From: Ian Lance Taylor Date: Tue, 28 Jul 2020 05:27:54 +0000 (-0700) Subject: libgo: update to go1.15rc1 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f75af8c1464e948b5e166cf5ab09ebf0d82fc253;p=gcc.git libgo: update to go1.15rc1 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/245157 --- diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 64a655e911e..89d1f3c7623 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -63bc2430187efe5ff47e9c7b9cd6d40b350ee7d7 +2c390ba951e83b547f6387cc9e19436c085b3775 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/libgo/MERGE b/libgo/MERGE index 4f8589371d3..ad43e2924c6 100644 --- a/libgo/MERGE +++ b/libgo/MERGE @@ -1,4 +1,4 @@ -edfd6f28486017dcb136cd3f3ec252706d4b326e +3e8f6b0791a670e52d25d76813d669daa68acfb4 The first line of this file holds the git revision number of the last merge done from the master library sources. diff --git a/libgo/Makefile.am b/libgo/Makefile.am index 52a8330ed2a..88ea2728bc3 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -391,6 +391,11 @@ toolexeclibgotexttemplatedir = $(toolexeclibgotextdir)/template toolexeclibgotexttemplate_DATA = \ text/template/parse.gox +toolexeclibgotimedir = $(toolexeclibgodir)/time + +toolexeclibgotime_DATA = \ + time/tzdata.gox + toolexeclibgounicodedir = $(toolexeclibgodir)/unicode toolexeclibgounicode_DATA = \ @@ -400,7 +405,8 @@ toolexeclibgounicode_DATA = \ # Some internal packages are needed to bootstrap the gc toolchain. toolexeclibgointernaldir = $(toolexeclibgodir)/internal toolexeclibgointernal_DATA = \ - internal/reflectlite.gox + internal/reflectlite.gox \ + internal/unsafeheader.gox # Some packages are only needed for tests, so unlike the other # internal packages nothing will explicitly depend on them. @@ -409,11 +415,11 @@ noinst_DATA = \ golang.org/x/net/nettest.gox \ internal/cfg.gox \ internal/obscuretestdata.gox \ + internal/profile.gox \ internal/testenv.gox \ internal/trace.gox \ net/internal/socktest.gox \ - os/signal/internal/pty.gox \ - runtime/pprof/internal/profile.gox + os/signal/internal/pty.gox if LIBGO_IS_RTEMS rtems_task_variable_add_file = runtime/rtems-task-variable-add.c @@ -706,9 +712,9 @@ syscall_lib_clone_lo = endif if LIBGO_IS_X86 -golangorg_x_sys_cpu_gccgo_lo = golang.org/x/sys/cpu_gccgo.lo +golangorg_x_sys_cpu_gccgo_x86_lo = golang.org/x/sys/cpu_gccgo_x86.lo else -golangorg_x_sys_cpu_gccgo_lo = +golangorg_x_sys_cpu_gccgo_x86_lo = endif PACKAGES = $(shell cat $(srcdir)/libgo-packages.txt) @@ -728,7 +734,7 @@ libgo_go_objs = \ runtime/internal/atomic_c.lo \ sync/atomic_c.lo \ internal/cpu/cpu_gccgo.lo \ - $(golangorg_x_sys_cpu_gccgo_lo) + $(golangorg_x_sys_cpu_gccgo_x86_lo) libgo_ldflags = \ -version-info $(libtool_VERSION) $(PTHREAD_CFLAGS) $(AM_LDFLAGS) @@ -1008,6 +1014,7 @@ extra_check_libs_cmd_go_internal_modload = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_module = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_mvs = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_search = $(abs_builddir)/libgotool.a +extra_check_libs_cmd_go_internal_test = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_web2 = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_work = $(abs_builddir)/libgotool.a @@ -1060,9 +1067,9 @@ internal/cpu/cpu_gccgo.lo: go/internal/cpu/cpu_gccgo.c runtime.inc $(LTCOMPILE) -c -o $@ $(srcdir)/go/internal/cpu/cpu_gccgo.c # Similarly, golang.org/x/sys/cpu needs some C code. -golang.org/x/sys/cpu_gccgo.lo: go/golang.org/x/sys/cpu/cpu_gccgo.c runtime.inc +golang.org/x/sys/cpu_gccgo_x86.lo: go/golang.org/x/sys/cpu/cpu_gccgo_x86.c runtime.inc @$(MKDIR_P) golang.org/x/sys - $(LTCOMPILE) -c -o $@ $(srcdir)/go/golang.org/x/sys/cpu/cpu_gccgo.c + $(LTCOMPILE) -c -o $@ $(srcdir)/go/golang.org/x/sys/cpu/cpu_gccgo_x86.c # Solaris 11.4 changed the type of fields in struct stat. # Use a build tag, based on a configure check, to cope. @@ -1238,7 +1245,7 @@ all-local: $(ALL_LOCAL_DEPS) MAJOR=$(firstword $(subst :, ,$(libtool_VERSION))) add-aix-fat-library: all-multi - @if test "$(MULTIBUILDTOP)" = ""; then \ - ${AR} -X$(AIX_DEFAULT_ARCH) rc .libs/$(PACKAGE).a ../ppc$(AIX_DEFAULT_ARCH)/$(PACKAGE)/.libs/$(PACKAGE).so.$(MAJOR); \ - ${AR} -X$(AIX_DEFAULT_ARCH) rc ../pthread/$(PACKAGE)/.libs/$(PACKAGE).a ../pthread/ppc$(AIX_DEFAULT_ARCH)/$(PACKAGE)/.libs/$(PACKAGE).so.$(MAJOR); \ - fi + @if test "$(MULTIBUILDTOP)" = ""; then \ + ${AR} -X$(AIX_DEFAULT_ARCH) rc .libs/$(PACKAGE).a ../ppc$(AIX_DEFAULT_ARCH)/$(PACKAGE)/.libs/$(PACKAGE).so.$(MAJOR); \ + ${AR} -X$(AIX_DEFAULT_ARCH) rc ../pthread/$(PACKAGE)/.libs/$(PACKAGE).a ../pthread/ppc$(AIX_DEFAULT_ARCH)/$(PACKAGE)/.libs/$(PACKAGE).so.$(MAJOR); \ + fi diff --git a/libgo/Makefile.in b/libgo/Makefile.in index 5cb44841c78..4aa9e98e8d8 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -191,6 +191,7 @@ am__installdirs = "$(DESTDIR)$(toolexeclibdir)" \ "$(DESTDIR)$(toolexeclibgotestinginternaldir)" \ "$(DESTDIR)$(toolexeclibgotextdir)" \ "$(DESTDIR)$(toolexeclibgotexttemplatedir)" \ + "$(DESTDIR)$(toolexeclibgotimedir)" \ "$(DESTDIR)$(toolexeclibgounicodedir)" LIBRARIES = $(noinst_LIBRARIES) $(toolexeclib_LIBRARIES) ARFLAGS = cru @@ -218,7 +219,8 @@ am_libgotool_a_OBJECTS = libgotool_a_OBJECTS = $(am_libgotool_a_OBJECTS) LTLIBRARIES = $(toolexeclib_LTLIBRARIES) @LIBGO_IS_LINUX_TRUE@am__DEPENDENCIES_1 = syscall/clone_linux.lo -@LIBGO_IS_X86_TRUE@am__DEPENDENCIES_2 = golang.org/x/sys/cpu_gccgo.lo +@LIBGO_IS_X86_TRUE@am__DEPENDENCIES_2 = \ +@LIBGO_IS_X86_TRUE@ golang.org/x/sys/cpu_gccgo_x86.lo am__DEPENDENCIES_3 = $(addsuffix .lo,$(PACKAGES)) \ internal/bytealg/bytealg.lo reflect/makefunc_ffi_c.lo \ $(am__DEPENDENCIES_1) syscall/errno.lo syscall/signame.lo \ @@ -345,7 +347,8 @@ DATA = $(noinst_DATA) $(toolexeclibgo_DATA) \ $(toolexeclibgoruntime_DATA) $(toolexeclibgosync_DATA) \ $(toolexeclibgotesting_DATA) \ $(toolexeclibgotestinginternal_DATA) $(toolexeclibgotext_DATA) \ - $(toolexeclibgotexttemplate_DATA) $(toolexeclibgounicode_DATA) + $(toolexeclibgotexttemplate_DATA) $(toolexeclibgotime_DATA) \ + $(toolexeclibgounicode_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ @@ -856,6 +859,10 @@ toolexeclibgotexttemplatedir = $(toolexeclibgotextdir)/template toolexeclibgotexttemplate_DATA = \ text/template/parse.gox +toolexeclibgotimedir = $(toolexeclibgodir)/time +toolexeclibgotime_DATA = \ + time/tzdata.gox + toolexeclibgounicodedir = $(toolexeclibgodir)/unicode toolexeclibgounicode_DATA = \ unicode/utf16.gox \ @@ -865,16 +872,17 @@ toolexeclibgounicode_DATA = \ # Some internal packages are needed to bootstrap the gc toolchain. toolexeclibgointernaldir = $(toolexeclibgodir)/internal toolexeclibgointernal_DATA = \ - internal/reflectlite.gox + internal/reflectlite.gox \ + internal/unsafeheader.gox # Some packages are only needed for tests, so unlike the other # internal packages nothing will explicitly depend on them. # Force them to be built. noinst_DATA = golang.org/x/net/nettest.gox internal/cfg.gox \ - internal/obscuretestdata.gox internal/testenv.gox \ - internal/trace.gox net/internal/socktest.gox \ - os/signal/internal/pty.gox runtime/pprof/internal/profile.gox \ + internal/obscuretestdata.gox internal/profile.gox \ + internal/testenv.gox internal/trace.gox \ + net/internal/socktest.gox os/signal/internal/pty.gox \ zdefaultcc.go @LIBGO_IS_RTEMS_FALSE@rtems_task_variable_add_file = @LIBGO_IS_RTEMS_TRUE@rtems_task_variable_add_file = runtime/rtems-task-variable-add.c @@ -923,8 +931,8 @@ SYSINFO_FLAGS = \ @LIBGO_IS_LINUX_FALSE@syscall_lib_clone_lo = @LIBGO_IS_LINUX_TRUE@syscall_lib_clone_lo = syscall/clone_linux.lo -@LIBGO_IS_X86_FALSE@golangorg_x_sys_cpu_gccgo_lo = -@LIBGO_IS_X86_TRUE@golangorg_x_sys_cpu_gccgo_lo = golang.org/x/sys/cpu_gccgo.lo +@LIBGO_IS_X86_FALSE@golangorg_x_sys_cpu_gccgo_x86_lo = +@LIBGO_IS_X86_TRUE@golangorg_x_sys_cpu_gccgo_x86_lo = golang.org/x/sys/cpu_gccgo_x86.lo PACKAGES = $(shell cat $(srcdir)/libgo-packages.txt) libgo_go_objs = \ $(addsuffix .lo,$(PACKAGES)) \ @@ -941,7 +949,7 @@ libgo_go_objs = \ runtime/internal/atomic_c.lo \ sync/atomic_c.lo \ internal/cpu/cpu_gccgo.lo \ - $(golangorg_x_sys_cpu_gccgo_lo) + $(golangorg_x_sys_cpu_gccgo_x86_lo) libgo_ldflags = \ -version-info $(libtool_VERSION) $(PTHREAD_CFLAGS) $(AM_LDFLAGS) @@ -1130,6 +1138,7 @@ extra_check_libs_cmd_go_internal_modload = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_module = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_mvs = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_search = $(abs_builddir)/libgotool.a +extra_check_libs_cmd_go_internal_test = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_web2 = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_work = $(abs_builddir)/libgotool.a extra_check_libs_cmd_vet_internal_cfg = $(abs_builddir)/libgotool.a @@ -2223,6 +2232,27 @@ uninstall-toolexeclibgotexttemplateDATA: @list='$(toolexeclibgotexttemplate_DATA)'; test -n "$(toolexeclibgotexttemplatedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(toolexeclibgotexttemplatedir)'; $(am__uninstall_files_from_dir) +install-toolexeclibgotimeDATA: $(toolexeclibgotime_DATA) + @$(NORMAL_INSTALL) + @list='$(toolexeclibgotime_DATA)'; test -n "$(toolexeclibgotimedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgotimedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(toolexeclibgotimedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(toolexeclibgotimedir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(toolexeclibgotimedir)" || exit $$?; \ + done + +uninstall-toolexeclibgotimeDATA: + @$(NORMAL_UNINSTALL) + @list='$(toolexeclibgotime_DATA)'; test -n "$(toolexeclibgotimedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(toolexeclibgotimedir)'; $(am__uninstall_files_from_dir) install-toolexeclibgounicodeDATA: $(toolexeclibgounicode_DATA) @$(NORMAL_INSTALL) @list='$(toolexeclibgounicode_DATA)'; test -n "$(toolexeclibgounicodedir)" || list=; \ @@ -2356,7 +2386,7 @@ all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(DATA) config.h \ all-local installdirs: installdirs-recursive installdirs-am: - for dir in "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(toolexeclibgodir)" "$(DESTDIR)$(toolexeclibgoarchivedir)" "$(DESTDIR)$(toolexeclibgocompressdir)" "$(DESTDIR)$(toolexeclibgocontainerdir)" "$(DESTDIR)$(toolexeclibgocryptodir)" "$(DESTDIR)$(toolexeclibgocryptox509dir)" "$(DESTDIR)$(toolexeclibgodatabasedir)" "$(DESTDIR)$(toolexeclibgodatabasesqldir)" "$(DESTDIR)$(toolexeclibgodebugdir)" "$(DESTDIR)$(toolexeclibgoencodingdir)" "$(DESTDIR)$(toolexeclibgogodir)" "$(DESTDIR)$(toolexeclibgohashdir)" "$(DESTDIR)$(toolexeclibgohtmldir)" "$(DESTDIR)$(toolexeclibgoimagedir)" "$(DESTDIR)$(toolexeclibgoimagecolordir)" "$(DESTDIR)$(toolexeclibgoindexdir)" "$(DESTDIR)$(toolexeclibgointernaldir)" "$(DESTDIR)$(toolexeclibgoiodir)" "$(DESTDIR)$(toolexeclibgologdir)" "$(DESTDIR)$(toolexeclibgomathdir)" "$(DESTDIR)$(toolexeclibgomimedir)" "$(DESTDIR)$(toolexeclibgonetdir)" "$(DESTDIR)$(toolexeclibgonethttpdir)" "$(DESTDIR)$(toolexeclibgonetrpcdir)" "$(DESTDIR)$(toolexeclibgoosdir)" "$(DESTDIR)$(toolexeclibgopathdir)" "$(DESTDIR)$(toolexeclibgoregexpdir)" "$(DESTDIR)$(toolexeclibgoruntimedir)" "$(DESTDIR)$(toolexeclibgosyncdir)" "$(DESTDIR)$(toolexeclibgotestingdir)" "$(DESTDIR)$(toolexeclibgotestinginternaldir)" "$(DESTDIR)$(toolexeclibgotextdir)" "$(DESTDIR)$(toolexeclibgotexttemplatedir)" "$(DESTDIR)$(toolexeclibgounicodedir)"; do \ + for dir in "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(toolexeclibgodir)" "$(DESTDIR)$(toolexeclibgoarchivedir)" "$(DESTDIR)$(toolexeclibgocompressdir)" "$(DESTDIR)$(toolexeclibgocontainerdir)" "$(DESTDIR)$(toolexeclibgocryptodir)" "$(DESTDIR)$(toolexeclibgocryptox509dir)" "$(DESTDIR)$(toolexeclibgodatabasedir)" "$(DESTDIR)$(toolexeclibgodatabasesqldir)" "$(DESTDIR)$(toolexeclibgodebugdir)" "$(DESTDIR)$(toolexeclibgoencodingdir)" "$(DESTDIR)$(toolexeclibgogodir)" "$(DESTDIR)$(toolexeclibgohashdir)" "$(DESTDIR)$(toolexeclibgohtmldir)" "$(DESTDIR)$(toolexeclibgoimagedir)" "$(DESTDIR)$(toolexeclibgoimagecolordir)" "$(DESTDIR)$(toolexeclibgoindexdir)" "$(DESTDIR)$(toolexeclibgointernaldir)" "$(DESTDIR)$(toolexeclibgoiodir)" "$(DESTDIR)$(toolexeclibgologdir)" "$(DESTDIR)$(toolexeclibgomathdir)" "$(DESTDIR)$(toolexeclibgomimedir)" "$(DESTDIR)$(toolexeclibgonetdir)" "$(DESTDIR)$(toolexeclibgonethttpdir)" "$(DESTDIR)$(toolexeclibgonetrpcdir)" "$(DESTDIR)$(toolexeclibgoosdir)" "$(DESTDIR)$(toolexeclibgopathdir)" "$(DESTDIR)$(toolexeclibgoregexpdir)" "$(DESTDIR)$(toolexeclibgoruntimedir)" "$(DESTDIR)$(toolexeclibgosyncdir)" "$(DESTDIR)$(toolexeclibgotestingdir)" "$(DESTDIR)$(toolexeclibgotestinginternaldir)" "$(DESTDIR)$(toolexeclibgotextdir)" "$(DESTDIR)$(toolexeclibgotexttemplatedir)" "$(DESTDIR)$(toolexeclibgotimedir)" "$(DESTDIR)$(toolexeclibgounicodedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive @@ -2450,7 +2480,7 @@ install-exec-am: install-exec-local install-toolexeclibLIBRARIES \ install-toolexeclibgotestinginternalDATA \ install-toolexeclibgotextDATA \ install-toolexeclibgotexttemplateDATA \ - install-toolexeclibgounicodeDATA + install-toolexeclibgotimeDATA install-toolexeclibgounicodeDATA install-html: install-html-recursive @@ -2523,6 +2553,7 @@ uninstall-am: uninstall-toolexeclibLIBRARIES \ uninstall-toolexeclibgotestinginternalDATA \ uninstall-toolexeclibgotextDATA \ uninstall-toolexeclibgotexttemplateDATA \ + uninstall-toolexeclibgotimeDATA \ uninstall-toolexeclibgounicodeDATA .MAKE: $(am__recursive_targets) all install-am install-strip @@ -2564,12 +2595,13 @@ uninstall-am: uninstall-toolexeclibLIBRARIES \ install-toolexeclibgotestinginternalDATA \ install-toolexeclibgotextDATA \ install-toolexeclibgotexttemplateDATA \ - install-toolexeclibgounicodeDATA installcheck installcheck-am \ - installdirs installdirs-am maintainer-clean \ - maintainer-clean-generic maintainer-clean-local mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - mostlyclean-local pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am uninstall-toolexeclibLIBRARIES \ + install-toolexeclibgotimeDATA install-toolexeclibgounicodeDATA \ + installcheck installcheck-am installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic \ + maintainer-clean-local mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool mostlyclean-local pdf \ + pdf-am ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-toolexeclibLIBRARIES \ uninstall-toolexeclibLTLIBRARIES uninstall-toolexeclibgoDATA \ uninstall-toolexeclibgoarchiveDATA \ uninstall-toolexeclibgocompressDATA \ @@ -2599,6 +2631,7 @@ uninstall-am: uninstall-toolexeclibLIBRARIES \ uninstall-toolexeclibgotestinginternalDATA \ uninstall-toolexeclibgotextDATA \ uninstall-toolexeclibgotexttemplateDATA \ + uninstall-toolexeclibgotimeDATA \ uninstall-toolexeclibgounicodeDATA .PRECIOUS: Makefile @@ -2929,9 +2962,9 @@ internal/cpu/cpu_gccgo.lo: go/internal/cpu/cpu_gccgo.c runtime.inc $(LTCOMPILE) -c -o $@ $(srcdir)/go/internal/cpu/cpu_gccgo.c # Similarly, golang.org/x/sys/cpu needs some C code. -golang.org/x/sys/cpu_gccgo.lo: go/golang.org/x/sys/cpu/cpu_gccgo.c runtime.inc +golang.org/x/sys/cpu_gccgo_x86.lo: go/golang.org/x/sys/cpu/cpu_gccgo_x86.c runtime.inc @$(MKDIR_P) golang.org/x/sys - $(LTCOMPILE) -c -o $@ $(srcdir)/go/golang.org/x/sys/cpu/cpu_gccgo.c + $(LTCOMPILE) -c -o $@ $(srcdir)/go/golang.org/x/sys/cpu/cpu_gccgo_x86.c # Build golang.org/x/net/route only on BSD systems. @@ -3087,8 +3120,8 @@ maintainer-clean-local: maintainer-clean-multi all-local: $(ALL_LOCAL_DEPS) add-aix-fat-library: all-multi @if test "$(MULTIBUILDTOP)" = ""; then \ - ${AR} -X$(AIX_DEFAULT_ARCH) rc .libs/$(PACKAGE).a ../ppc$(AIX_DEFAULT_ARCH)/$(PACKAGE)/.libs/$(PACKAGE).so.$(MAJOR); \ - ${AR} -X$(AIX_DEFAULT_ARCH) rc ../pthread/$(PACKAGE)/.libs/$(PACKAGE).a ../pthread/ppc$(AIX_DEFAULT_ARCH)/$(PACKAGE)/.libs/$(PACKAGE).so.$(MAJOR); \ + ${AR} -X$(AIX_DEFAULT_ARCH) rc .libs/$(PACKAGE).a ../ppc$(AIX_DEFAULT_ARCH)/$(PACKAGE)/.libs/$(PACKAGE).so.$(MAJOR); \ + ${AR} -X$(AIX_DEFAULT_ARCH) rc ../pthread/$(PACKAGE)/.libs/$(PACKAGE).a ../pthread/ppc$(AIX_DEFAULT_ARCH)/$(PACKAGE)/.libs/$(PACKAGE).so.$(MAJOR); \ fi # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/libgo/VERSION b/libgo/VERSION index 398d25321fb..0bcf07d0280 100644 --- a/libgo/VERSION +++ b/libgo/VERSION @@ -1 +1 @@ -go1.14.6 +go1.15rc1 diff --git a/libgo/check-packages.txt b/libgo/check-packages.txt index 48c4dfdbc91..efa7d191180 100644 --- a/libgo/check-packages.txt +++ b/libgo/check-packages.txt @@ -16,6 +16,7 @@ cmd/go/internal/modload cmd/go/internal/mvs cmd/go/internal/par cmd/go/internal/search +cmd/go/internal/test cmd/go/internal/txtar cmd/go/internal/work cmd/internal/buildid @@ -104,9 +105,11 @@ index/suffixarray internal/cpu internal/fmtsort internal/poll +internal/profile internal/reflectlite internal/singleflight internal/trace +internal/unsafeheader internal/xcoff io io/ioutil @@ -152,7 +155,6 @@ runtime/internal/atomic runtime/internal/math runtime/internal/sys runtime/pprof -runtime/pprof/internal/profile runtime/trace sort strconv diff --git a/libgo/configure b/libgo/configure index 67470acbadb..74bf072aa85 100755 --- a/libgo/configure +++ b/libgo/configure @@ -2551,7 +2551,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" -libtool_VERSION=16:0:0 +libtool_VERSION=17:0:0 # Default to --enable-multilib @@ -11501,7 +11501,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11602 "configure" +#line 11504 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11607,7 +11607,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11708 "configure" +#line 11610 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/libgo/configure.ac b/libgo/configure.ac index 841cba1768e..db5848e36ad 100644 --- a/libgo/configure.ac +++ b/libgo/configure.ac @@ -10,7 +10,7 @@ AC_INIT(package-unused, version-unused,, libgo) AC_CONFIG_SRCDIR(Makefile.am) AC_CONFIG_HEADER(config.h) -libtool_VERSION=16:0:0 +libtool_VERSION=17:0:0 AC_SUBST(libtool_VERSION) AM_ENABLE_MULTILIB(, ..) diff --git a/libgo/go/bufio/bufio.go b/libgo/go/bufio/bufio.go index f0810be3a44..7cbd5424ea6 100644 --- a/libgo/go/bufio/bufio.go +++ b/libgo/go/bufio/bufio.go @@ -11,6 +11,7 @@ import ( "bytes" "errors" "io" + "strings" "unicode/utf8" ) @@ -419,20 +420,16 @@ func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error) { return } -// ReadBytes reads until the first occurrence of delim in the input, -// returning a slice containing the data up to and including the delimiter. -// If ReadBytes encounters an error before finding a delimiter, -// it returns the data read before the error and the error itself (often io.EOF). -// ReadBytes returns err != nil if and only if the returned data does not end in -// delim. -// For simple uses, a Scanner may be more convenient. -func (b *Reader) ReadBytes(delim byte) ([]byte, error) { - // Use ReadSlice to look for array, - // accumulating full buffers. +// collectFragments reads until the first occurrence of delim in the input. It +// returns (slice of full buffers, remaining bytes before delim, total number +// of bytes in the combined first two elements, error). +// The complete result is equal to +// `bytes.Join(append(fullBuffers, finalFragment), nil)`, which has a +// length of `totalLen`. The result is strucured in this way to allow callers +// to minimize allocations and copies. +func (b *Reader) collectFragments(delim byte) (fullBuffers [][]byte, finalFragment []byte, totalLen int, err error) { var frag []byte - var full [][]byte - var err error - n := 0 + // Use ReadSlice to look for delim, accumulating full buffers. for { var e error frag, e = b.ReadSlice(delim) @@ -447,12 +444,23 @@ func (b *Reader) ReadBytes(delim byte) ([]byte, error) { // Make a copy of the buffer. buf := make([]byte, len(frag)) copy(buf, frag) - full = append(full, buf) - n += len(buf) + fullBuffers = append(fullBuffers, buf) + totalLen += len(buf) } - n += len(frag) + totalLen += len(frag) + return fullBuffers, frag, totalLen, err +} +// ReadBytes reads until the first occurrence of delim in the input, +// returning a slice containing the data up to and including the delimiter. +// If ReadBytes encounters an error before finding a delimiter, +// it returns the data read before the error and the error itself (often io.EOF). +// ReadBytes returns err != nil if and only if the returned data does not end in +// delim. +// For simple uses, a Scanner may be more convenient. +func (b *Reader) ReadBytes(delim byte) ([]byte, error) { + full, frag, n, err := b.collectFragments(delim) // Allocate new buffer to hold the full pieces and the fragment. buf := make([]byte, n) n = 0 @@ -472,8 +480,16 @@ func (b *Reader) ReadBytes(delim byte) ([]byte, error) { // delim. // For simple uses, a Scanner may be more convenient. func (b *Reader) ReadString(delim byte) (string, error) { - bytes, err := b.ReadBytes(delim) - return string(bytes), err + full, frag, n, err := b.collectFragments(delim) + // Allocate new buffer to hold the full pieces and the fragment. + var buf strings.Builder + buf.Grow(n) + // Copy full pieces and fragment in. + for _, fb := range full { + buf.Write(fb) + } + buf.Write(frag) + return buf.String(), err } // WriteTo implements io.WriterTo. diff --git a/libgo/go/bufio/bufio_test.go b/libgo/go/bufio/bufio_test.go index 9a9f102f151..cb68f3ba239 100644 --- a/libgo/go/bufio/bufio_test.go +++ b/libgo/go/bufio/bufio_test.go @@ -147,7 +147,7 @@ func TestReader(t *testing.T) { for i := 0; i < len(texts)-1; i++ { texts[i] = str + "\n" all += texts[i] - str += string(i%26 + 'a') + str += string(rune(i)%26 + 'a') } texts[len(texts)-1] = all @@ -535,6 +535,23 @@ func TestReadWriteRune(t *testing.T) { } } +func TestReadStringAllocs(t *testing.T) { + r := strings.NewReader(" foo foo 42 42 42 42 42 42 42 42 4.2 4.2 4.2 4.2\n") + buf := NewReader(r) + allocs := testing.AllocsPerRun(100, func() { + r.Seek(0, io.SeekStart) + buf.Reset(r) + + _, err := buf.ReadString('\n') + if err != nil { + t.Fatal(err) + } + }) + if allocs != 1 { + t.Errorf("Unexpected number of allocations, got %f, want 1", allocs) + } +} + func TestWriter(t *testing.T) { var data [8192]byte @@ -1644,6 +1661,21 @@ func BenchmarkReaderWriteToOptimal(b *testing.B) { } } +func BenchmarkReaderReadString(b *testing.B) { + r := strings.NewReader(" foo foo 42 42 42 42 42 42 42 42 4.2 4.2 4.2 4.2\n") + buf := NewReader(r) + b.ReportAllocs() + for i := 0; i < b.N; i++ { + r.Seek(0, io.SeekStart) + buf.Reset(r) + + _, err := buf.ReadString('\n') + if err != nil { + b.Fatal(err) + } + } +} + func BenchmarkWriterCopyOptimal(b *testing.B) { // Optimal case is where the underlying writer implements io.ReaderFrom srcBuf := bytes.NewBuffer(make([]byte, 8192)) diff --git a/libgo/go/bufio/scan.go b/libgo/go/bufio/scan.go index 4e787c4b0a4..af46a14fbbe 100644 --- a/libgo/go/bufio/scan.go +++ b/libgo/go/bufio/scan.go @@ -69,6 +69,7 @@ var ( ErrTooLong = errors.New("bufio.Scanner: token too long") ErrNegativeAdvance = errors.New("bufio.Scanner: SplitFunc returns negative advance count") ErrAdvanceTooFar = errors.New("bufio.Scanner: SplitFunc returns advance count beyond input") + ErrBadReadCount = errors.New("bufio.Scanner: Read returned impossible count") ) const ( @@ -211,6 +212,10 @@ func (s *Scanner) Scan() bool { // be extra careful: Scanner is for safe, simple jobs. for loop := 0; ; { n, err := s.r.Read(s.buf[s.end:len(s.buf)]) + if n < 0 || len(s.buf)-s.end < n { + s.setErr(ErrBadReadCount) + break + } s.end += n if err != nil { s.setErr(err) diff --git a/libgo/go/bufio/scan_test.go b/libgo/go/bufio/scan_test.go index 25682256887..e99b09f66f4 100644 --- a/libgo/go/bufio/scan_test.go +++ b/libgo/go/bufio/scan_test.go @@ -537,3 +537,60 @@ func TestHugeBuffer(t *testing.T) { t.Fatal("after scan:", s.Err()) } } + +// negativeEOFReader returns an invalid -1 at the end, as though it +// were wrapping the read system call. +type negativeEOFReader int + +func (r *negativeEOFReader) Read(p []byte) (int, error) { + if *r > 0 { + c := int(*r) + if c > len(p) { + c = len(p) + } + for i := 0; i < c; i++ { + p[i] = 'a' + } + p[c-1] = '\n' + *r -= negativeEOFReader(c) + return c, nil + } + return -1, io.EOF +} + +// Test that the scanner doesn't panic and returns ErrBadReadCount +// on a reader that returns a negative count of bytes read (issue 38053). +func TestNegativeEOFReader(t *testing.T) { + r := negativeEOFReader(10) + scanner := NewScanner(&r) + c := 0 + for scanner.Scan() { + c++ + if c > 1 { + t.Error("read too many lines") + break + } + } + if got, want := scanner.Err(), ErrBadReadCount; got != want { + t.Errorf("scanner.Err: got %v, want %v", got, want) + } +} + +// largeReader returns an invalid count that is larger than the number +// of bytes requested. +type largeReader struct{} + +func (largeReader) Read(p []byte) (int, error) { + return len(p) + 1, nil +} + +// Test that the scanner doesn't panic and returns ErrBadReadCount +// on a reader that returns an impossibly large count of bytes read (issue 38053). +func TestLargeReader(t *testing.T) { + scanner := NewScanner(largeReader{}) + for scanner.Scan() { + } + if got, want := scanner.Err(), ErrBadReadCount; got != want { + t.Errorf("scanner.Err: got %v, want %v", got, want) + } +} diff --git a/libgo/go/bytes/buffer_test.go b/libgo/go/bytes/buffer_test.go index 7626d277d4f..fec5ef8a35f 100644 --- a/libgo/go/bytes/buffer_test.go +++ b/libgo/go/bytes/buffer_test.go @@ -8,7 +8,6 @@ import ( . "bytes" "io" "math/rand" - "runtime" "testing" "unicode/utf8" ) @@ -495,20 +494,20 @@ func TestGrow(t *testing.T) { x := []byte{'x'} y := []byte{'y'} tmp := make([]byte, 72) - for _, startLen := range []int{0, 100, 1000, 10000, 100000} { - xBytes := Repeat(x, startLen) - for _, growLen := range []int{0, 100, 1000, 10000, 100000} { + for _, growLen := range []int{0, 100, 1000, 10000, 100000} { + for _, startLen := range []int{0, 100, 1000, 10000, 100000} { + xBytes := Repeat(x, startLen) + buf := NewBuffer(xBytes) // If we read, this affects buf.off, which is good to test. readBytes, _ := buf.Read(tmp) - buf.Grow(growLen) yBytes := Repeat(y, growLen) + allocs := testing.AllocsPerRun(100, func() { + buf.Grow(growLen) + buf.Write(yBytes) + }) // Check no allocation occurs in write, as long as we're single-threaded. - var m1, m2 runtime.MemStats - runtime.ReadMemStats(&m1) - buf.Write(yBytes) - runtime.ReadMemStats(&m2) - if runtime.GOMAXPROCS(-1) == 1 && m1.Mallocs != m2.Mallocs { + if allocs != 0 { t.Errorf("allocation occurred during write") } // Check that buffer has correct data. diff --git a/libgo/go/bytes/bytes.go b/libgo/go/bytes/bytes.go index e872cc20506..aa07b9fbc16 100644 --- a/libgo/go/bytes/bytes.go +++ b/libgo/go/bytes/bytes.go @@ -117,17 +117,17 @@ func LastIndex(s, sep []byte) int { return -1 } // Rabin-Karp search from the end of the string - hashss, pow := hashStrRev(sep) + hashss, pow := bytealg.HashStrRevBytes(sep) last := len(s) - n var h uint32 for i := len(s) - 1; i >= last; i-- { - h = h*primeRK + uint32(s[i]) + h = h*bytealg.PrimeRK + uint32(s[i]) } if h == hashss && Equal(s[last:], sep) { return last } for i := last - 1; i >= 0; i-- { - h *= primeRK + h *= bytealg.PrimeRK h += uint32(s[i]) h -= pow * uint32(s[i+n]) if h == hashss && Equal(s[i:i+n], sep) { @@ -183,6 +183,29 @@ func IndexAny(s []byte, chars string) int { // Avoid scanning all of s. return -1 } + if len(s) == 1 { + r := rune(s[0]) + if r >= utf8.RuneSelf { + // search utf8.RuneError. + for _, r = range chars { + if r == utf8.RuneError { + return 0 + } + } + return -1 + } + if bytealg.IndexByteString(chars, s[0]) >= 0 { + return 0 + } + return -1 + } + if len(chars) == 1 { + r := rune(chars[0]) + if r >= utf8.RuneSelf { + r = utf8.RuneError + } + return IndexRune(s, r) + } if len(s) > 8 { if as, isASCII := makeASCIISet(chars); isASCII { for i, c := range s { @@ -197,14 +220,26 @@ func IndexAny(s []byte, chars string) int { for i := 0; i < len(s); i += width { r := rune(s[i]) if r < utf8.RuneSelf { + if bytealg.IndexByteString(chars, s[i]) >= 0 { + return i + } width = 1 - } else { - r, width = utf8.DecodeRune(s[i:]) + continue } - for _, ch := range chars { - if r == ch { - return i + r, width = utf8.DecodeRune(s[i:]) + if r == utf8.RuneError { + for _, r = range chars { + if r == utf8.RuneError { + return i + } } + continue + } + // r is 2 to 4 bytes. Using strings.Index is more reasonable, but as the bytes + // package should not import the strings package, use bytealg.IndexString + // instead. And this does not seem to lose much performance. + if chars == string(r) || bytealg.IndexString(chars, string(r)) >= 0 { + return i } } return -1 @@ -229,13 +264,59 @@ func LastIndexAny(s []byte, chars string) int { return -1 } } + if len(s) == 1 { + r := rune(s[0]) + if r >= utf8.RuneSelf { + for _, r = range chars { + if r == utf8.RuneError { + return 0 + } + } + return -1 + } + if bytealg.IndexByteString(chars, s[0]) >= 0 { + return 0 + } + return -1 + } + if len(chars) == 1 { + cr := rune(chars[0]) + if cr >= utf8.RuneSelf { + cr = utf8.RuneError + } + for i := len(s); i > 0; { + r, size := utf8.DecodeLastRune(s[:i]) + i -= size + if r == cr { + return i + } + } + return -1 + } for i := len(s); i > 0; { + r := rune(s[i-1]) + if r < utf8.RuneSelf { + if bytealg.IndexByteString(chars, s[i-1]) >= 0 { + return i - 1 + } + i-- + continue + } r, size := utf8.DecodeLastRune(s[:i]) i -= size - for _, c := range chars { - if r == c { - return i + if r == utf8.RuneError { + for _, r = range chars { + if r == utf8.RuneError { + return i + } } + continue + } + // r is 2 to 4 bytes. Using strings.Index is more reasonable, but as the bytes + // package should not import the strings package, use bytealg.IndexString + // instead. And this does not seem to lose much performance. + if chars == string(r) || bytealg.IndexString(chars, string(r)) >= 0 { + return i } } return -1 @@ -364,8 +445,9 @@ func Fields(s []byte) [][]byte { // It splits the slice s at each run of code points c satisfying f(c) and // returns a slice of subslices of s. If all code points in s satisfy f(c), or // len(s) == 0, an empty slice is returned. -// FieldsFunc makes no guarantees about the order in which it calls f(c). -// If f does not return consistent results for a given c, FieldsFunc may crash. +// +// FieldsFunc makes no guarantees about the order in which it calls f(c) +// and assumes that f always returns the same value for a given c. func FieldsFunc(s []byte, f func(rune) bool) [][]byte { // A span is used to record a slice of s of the form s[start:end]. // The start index is inclusive and the end index is exclusive. @@ -376,8 +458,10 @@ func FieldsFunc(s []byte, f func(rune) bool) [][]byte { spans := make([]span, 0, 32) // Find the field start and end indices. - wasField := false - fromIndex := 0 + // Doing this in a separate pass (rather than slicing the string s + // and collecting the result substrings right away) is significantly + // more efficient, possibly due to cache effects. + start := -1 // valid span start if >= 0 for i := 0; i < len(s); { size := 1 r := rune(s[i]) @@ -385,22 +469,21 @@ func FieldsFunc(s []byte, f func(rune) bool) [][]byte { r, size = utf8.DecodeRune(s[i:]) } if f(r) { - if wasField { - spans = append(spans, span{start: fromIndex, end: i}) - wasField = false + if start >= 0 { + spans = append(spans, span{start, i}) + start = -1 } } else { - if !wasField { - fromIndex = i - wasField = true + if start < 0 { + start = i } } i += size } // Last field might end at EOF. - if wasField { - spans = append(spans, span{fromIndex, len(s)}) + if start >= 0 { + spans = append(spans, span{start, len(s)}) } // Create subslices from recorded field indices. @@ -1019,11 +1102,11 @@ func Index(s, sep []byte) int { if s[i] != c0 { // IndexByte is faster than bytealg.Index, so use it as long as // we're not getting lots of false positives. - o := IndexByte(s[i:t], c0) + o := IndexByte(s[i+1:t], c0) if o < 0 { return -1 } - i += o + i += o + 1 } if s[i+1] == c1 && Equal(s[i:i+n], sep) { return i @@ -1048,11 +1131,11 @@ func Index(s, sep []byte) int { t := len(s) - n + 1 for i < t { if s[i] != c0 { - o := IndexByte(s[i:t], c0) + o := IndexByte(s[i+1:t], c0) if o < 0 { break } - i += o + i += o + 1 } if s[i+1] == c1 && Equal(s[i:i+n], sep) { return i @@ -1068,7 +1151,7 @@ func Index(s, sep []byte) int { // we should cutover at even larger average skips, // because Equal becomes that much more expensive. // This code does not take that effect into account. - j := indexRabinKarp(s[i:], sep) + j := bytealg.IndexRabinKarpBytes(s[i:], sep) if j < 0 { return -1 } @@ -1077,63 +1160,3 @@ func Index(s, sep []byte) int { } return -1 } - -func indexRabinKarp(s, sep []byte) int { - // Rabin-Karp search - hashsep, pow := hashStr(sep) - n := len(sep) - var h uint32 - for i := 0; i < n; i++ { - h = h*primeRK + uint32(s[i]) - } - if h == hashsep && Equal(s[:n], sep) { - return 0 - } - for i := n; i < len(s); { - h *= primeRK - h += uint32(s[i]) - h -= pow * uint32(s[i-n]) - i++ - if h == hashsep && Equal(s[i-n:i], sep) { - return i - n - } - } - return -1 -} - -// primeRK is the prime base used in Rabin-Karp algorithm. -const primeRK = 16777619 - -// hashStr returns the hash and the appropriate multiplicative -// factor for use in Rabin-Karp algorithm. -func hashStr(sep []byte) (uint32, uint32) { - hash := uint32(0) - for i := 0; i < len(sep); i++ { - hash = hash*primeRK + uint32(sep[i]) - } - var pow, sq uint32 = 1, primeRK - for i := len(sep); i > 0; i >>= 1 { - if i&1 != 0 { - pow *= sq - } - sq *= sq - } - return hash, pow -} - -// hashStrRev returns the hash of the reverse of sep and the -// appropriate multiplicative factor for use in Rabin-Karp algorithm. -func hashStrRev(sep []byte) (uint32, uint32) { - hash := uint32(0) - for i := len(sep) - 1; i >= 0; i-- { - hash = hash*primeRK + uint32(sep[i]) - } - var pow, sq uint32 = 1, primeRK - for i := len(sep); i > 0; i >>= 1 { - if i&1 != 0 { - pow *= sq - } - sq *= sq - } - return hash, pow -} diff --git a/libgo/go/bytes/bytes_test.go b/libgo/go/bytes/bytes_test.go index ebff5f00e58..0111d31d44c 100644 --- a/libgo/go/bytes/bytes_test.go +++ b/libgo/go/bytes/bytes_test.go @@ -142,9 +142,10 @@ var indexTests = []BinOpTest{ {"barfoobarfooyyyzzzyyyzzzyyyzzzyyyxxxzzzyyy", "x", 33}, {"foofyfoobarfoobar", "y", 4}, {"oooooooooooooooooooooo", "r", -1}, - // test fallback to Rabin-Karp. {"oxoxoxoxoxoxoxoxoxoxoxoy", "oy", 22}, {"oxoxoxoxoxoxoxoxoxoxoxox", "oy", -1}, + // test fallback to Rabin-Karp. + {"000000000000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000000001", 5}, } var lastIndexTests = []BinOpTest{ @@ -169,6 +170,7 @@ var indexAnyTests = []BinOpTest{ {"", "abc", -1}, {"a", "", -1}, {"a", "a", 0}, + {"\x80", "\xffb", 0}, {"aaa", "a", 0}, {"abc", "xyz", -1}, {"abc", "xcz", 2}, @@ -179,6 +181,7 @@ var indexAnyTests = []BinOpTest{ {dots + dots + dots, " ", -1}, {"012abcba210", "\xffb", 4}, {"012\x80bcb\x80210", "\xffb", 3}, + {"0123456\xcf\x80abc", "\xcfb\x80", 10}, } var lastIndexAnyTests = []BinOpTest{ @@ -187,6 +190,7 @@ var lastIndexAnyTests = []BinOpTest{ {"", "abc", -1}, {"a", "", -1}, {"a", "a", 0}, + {"\x80", "\xffb", 0}, {"aaa", "a", 2}, {"abc", "xyz", -1}, {"abc", "ab", 1}, @@ -197,6 +201,7 @@ var lastIndexAnyTests = []BinOpTest{ {dots + dots + dots, " ", -1}, {"012abcba210", "\xffb", 6}, {"012\x80bcb\x80210", "\xffb", 7}, + {"0123456\xcf\x80abc", "\xcfb\x80", 10}, } // Execute f on each test case. funcName should be the name of f; it's used @@ -210,6 +215,27 @@ func runIndexTests(t *testing.T, f func(s, sep []byte) int, funcName string, tes t.Errorf("%s(%q,%q) = %v; want %v", funcName, a, b, actual, test.i) } } + var allocTests = []struct { + a []byte + b []byte + i int + }{ + // case for function Index. + {[]byte("000000000000000000000000000000000000000000000000000000000000000000000001"), []byte("0000000000000000000000000000000000000000000000000000000000000000001"), 5}, + // case for function LastIndex. + {[]byte("000000000000000000000000000000000000000000000000000000000000000010000"), []byte("00000000000000000000000000000000000000000000000000000000000001"), 3}, + } + allocs := testing.AllocsPerRun(100, func() { + if i := Index(allocTests[1].a, allocTests[1].b); i != allocTests[1].i { + t.Errorf("Index([]byte(%q), []byte(%q)) = %v; want %v", allocTests[1].a, allocTests[1].b, i, allocTests[1].i) + } + if i := LastIndex(allocTests[0].a, allocTests[0].b); i != allocTests[0].i { + t.Errorf("LastIndex([]byte(%q), []byte(%q)) = %v; want %v", allocTests[0].a, allocTests[0].b, i, allocTests[0].i) + } + }) + if allocs != 0 { + t.Errorf("expected no allocations, got %f", allocs) + } } func runIndexAnyTests(t *testing.T, f func(s []byte, chars string) int, funcName string, testCases []BinOpTest) { @@ -1873,10 +1899,10 @@ func BenchmarkBytesCompare(b *testing.B) { } func BenchmarkIndexAnyASCII(b *testing.B) { - x := Repeat([]byte{'#'}, 4096) // Never matches set - cs := "0123456789abcdef" - for k := 1; k <= 4096; k <<= 4 { - for j := 1; j <= 16; j <<= 1 { + x := Repeat([]byte{'#'}, 2048) // Never matches set + cs := "0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz" + for k := 1; k <= 2048; k <<= 4 { + for j := 1; j <= 64; j <<= 1 { b.Run(fmt.Sprintf("%d:%d", k, j), func(b *testing.B) { for i := 0; i < b.N; i++ { IndexAny(x[:k], cs[:j]) @@ -1886,6 +1912,48 @@ func BenchmarkIndexAnyASCII(b *testing.B) { } } +func BenchmarkIndexAnyUTF8(b *testing.B) { + x := Repeat([]byte{'#'}, 2048) // Never matches set + cs := "你好世界, hello world. 你好世界, hello world. 你好世界, hello world." + for k := 1; k <= 2048; k <<= 4 { + for j := 1; j <= 64; j <<= 1 { + b.Run(fmt.Sprintf("%d:%d", k, j), func(b *testing.B) { + for i := 0; i < b.N; i++ { + IndexAny(x[:k], cs[:j]) + } + }) + } + } +} + +func BenchmarkLastIndexAnyASCII(b *testing.B) { + x := Repeat([]byte{'#'}, 2048) // Never matches set + cs := "0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz" + for k := 1; k <= 2048; k <<= 4 { + for j := 1; j <= 64; j <<= 1 { + b.Run(fmt.Sprintf("%d:%d", k, j), func(b *testing.B) { + for i := 0; i < b.N; i++ { + LastIndexAny(x[:k], cs[:j]) + } + }) + } + } +} + +func BenchmarkLastIndexAnyUTF8(b *testing.B) { + x := Repeat([]byte{'#'}, 2048) // Never matches set + cs := "你好世界, hello world. 你好世界, hello world. 你好世界, hello world." + for k := 1; k <= 2048; k <<= 4 { + for j := 1; j <= 64; j <<= 1 { + b.Run(fmt.Sprintf("%d:%d", k, j), func(b *testing.B) { + for i := 0; i < b.N; i++ { + LastIndexAny(x[:k], cs[:j]) + } + }) + } + } +} + func BenchmarkTrimASCII(b *testing.B) { cs := "0123456789abcdef" for k := 1; k <= 4096; k <<= 4 { diff --git a/libgo/go/cmd/cgo/doc.go b/libgo/go/cmd/cgo/doc.go index 8c3bf81bf78..ca18c45d9d9 100644 --- a/libgo/go/cmd/cgo/doc.go +++ b/libgo/go/cmd/cgo/doc.go @@ -413,7 +413,7 @@ type in Go are instead represented by a uintptr. Those include: jobjectArray jweak -3. The EGLDisplay type from the EGL API. +3. The EGLDisplay and EGLConfig types from the EGL API. These types are uintptr on the Go side because they would otherwise confuse the Go garbage collector; they are sometimes not really @@ -429,11 +429,16 @@ from Go 1.9 and earlier, use the cftype or jni rewrites in the Go fix tool: It will replace nil with 0 in the appropriate places. -The EGLDisplay case were introduced in Go 1.12. Use the egl rewrite +The EGLDisplay case was introduced in Go 1.12. Use the egl rewrite to auto-update code from Go 1.11 and earlier: go tool fix -r egl +The EGLConfig case was introduced in Go 1.15. Use the eglconf rewrite +to auto-update code from Go 1.14 and earlier: + + go tool fix -r eglconf + Using cgo directly Usage: @@ -985,7 +990,7 @@ produces a file named a.out, even if cmd/link does so by invoking the host linker in external linking mode. By default, cmd/link will decide the linking mode as follows: if the only -packages using cgo are those on a whitelist of standard library +packages using cgo are those on a list of known standard library packages (net, os/user, runtime/cgo), cmd/link will use internal linking mode. Otherwise, there are non-standard cgo packages involved, and cmd/link will use external linking mode. The first rule means that a build of diff --git a/libgo/go/cmd/cgo/gcc.go b/libgo/go/cmd/cgo/gcc.go index e38972913be..249cfe4675d 100644 --- a/libgo/go/cmd/cgo/gcc.go +++ b/libgo/go/cmd/cgo/gcc.go @@ -200,6 +200,9 @@ func (p *Package) Translate(f *File) { numTypedefs = len(p.typedefs) // Also ask about any typedefs we've seen so far. for _, info := range p.typedefList { + if f.Name[info.typedef] != nil { + continue + } n := &Name{ Go: info.typedef, C: info.typedef, @@ -351,7 +354,7 @@ func (p *Package) guessKinds(f *File) []*Name { // void __cgo_f_xxx_5(void) { static const char __cgo_undefined__5[] = (name); } // // If we see an error at not-declared:xxx, the corresponding name is not declared. - // If we see an error at not-type:xxx, the corresponding name is a type. + // If we see an error at not-type:xxx, the corresponding name is not a type. // If we see an error at not-int-const:xxx, the corresponding name is not an integer constant. // If we see an error at not-num-const:xxx, the corresponding name is not a number constant. // If we see an error at not-str-lit:xxx, the corresponding name is not a string literal. @@ -728,6 +731,9 @@ func (p *Package) prepareNames(f *File) { } } p.mangleName(n) + if n.Kind == "type" && typedef[n.Mangle] == nil { + typedef[n.Mangle] = n.Type + } } } @@ -1366,6 +1372,9 @@ func (p *Package) rewriteRef(f *File) { if *godefs { // Substitute definition for mangled type name. + if r.Name.Type != nil && r.Name.Kind == "type" { + expr = r.Name.Type.Go + } if id, ok := expr.(*ast.Ident); ok { if t := typedef[id.Name]; t != nil { expr = t.Go @@ -1431,9 +1440,7 @@ func (p *Package) rewriteName(f *File, r *Ref) ast.Expr { r.Context = ctxType if r.Name.Type == nil { error_(r.Pos(), "invalid conversion to C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C) - break } - expr = r.Name.Type.Go break } error_(r.Pos(), "call of non-function C.%s", fixGo(r.Name.Go)) @@ -1490,9 +1497,7 @@ func (p *Package) rewriteName(f *File, r *Ref) ast.Expr { // Okay - might be new(T) if r.Name.Type == nil { error_(r.Pos(), "expression C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C) - break } - expr = r.Name.Type.Go case "var": expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr} case "macro": @@ -1511,8 +1516,6 @@ func (p *Package) rewriteName(f *File, r *Ref) ast.Expr { // Use of C.enum_x, C.struct_x or C.union_x without C definition. // GCC won't raise an error when using pointers to such unknown types. error_(r.Pos(), "type C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C) - } else { - expr = r.Name.Type.Go } default: if r.Name.Kind == "func" { @@ -3036,8 +3039,9 @@ func (c *typeConv) anonymousStructTypedef(dt *dwarf.TypedefType) bool { return ok && st.StructName == "" } -// badPointerTypedef reports whether t is a C typedef that should not be considered a pointer in Go. -// A typedef is bad if C code sometimes stores non-pointers in this type. +// badPointerTypedef reports whether dt is a C typedef that should not be +// considered a pointer in Go. A typedef is bad if C code sometimes stores +// non-pointers in this type. // TODO: Currently our best solution is to find these manually and list them as // they come up. A better solution is desired. func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool { @@ -3047,7 +3051,7 @@ func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool { if c.badJNI(dt) { return true } - if c.badEGLDisplay(dt) { + if c.badEGLType(dt) { return true } return false @@ -3186,11 +3190,11 @@ func (c *typeConv) badJNI(dt *dwarf.TypedefType) bool { return false } -func (c *typeConv) badEGLDisplay(dt *dwarf.TypedefType) bool { - if dt.Name != "EGLDisplay" { +func (c *typeConv) badEGLType(dt *dwarf.TypedefType) bool { + if dt.Name != "EGLDisplay" && dt.Name != "EGLConfig" { return false } - // Check that the typedef is "typedef void *EGLDisplay". + // Check that the typedef is "typedef void *". if ptr, ok := dt.Type.(*dwarf.PtrType); ok { if _, ok := ptr.Type.(*dwarf.VoidType); ok { return true diff --git a/libgo/go/cmd/cgo/out.go b/libgo/go/cmd/cgo/out.go index 4d66e1b24b3..a5a22c85955 100644 --- a/libgo/go/cmd/cgo/out.go +++ b/libgo/go/cmd/cgo/out.go @@ -22,6 +22,7 @@ import ( "regexp" "sort" "strings" + "unicode" ) var ( @@ -102,6 +103,11 @@ func (p *Package) writeDefs() { typedefNames := make([]string, 0, len(typedef)) for name := range typedef { + if name == "_Ctype_void" { + // We provide an appropriate declaration for + // _Ctype_void below (#39877). + continue + } typedefNames = append(typedefNames, name) } sort.Strings(typedefNames) @@ -807,6 +813,28 @@ func (p *Package) packedAttribute() string { return s + "))" } +// exportParamName returns the value of param as it should be +// displayed in a c header file. If param contains any non-ASCII +// characters, this function will return the character p followed by +// the value of position; otherwise, this function will return the +// value of param. +func exportParamName(param string, position int) string { + if param == "" { + return fmt.Sprintf("p%d", position) + } + + pname := param + + for i := 0; i < len(param); i++ { + if param[i] > unicode.MaxASCII { + pname = fmt.Sprintf("p%d", position) + break + } + } + + return pname +} + // Write out the various stubs we need to support functions exported // from Go so that they are callable from C. func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { @@ -920,42 +948,45 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { if i > 0 || fn.Recv != nil { s += ", " } - s += fmt.Sprintf("%s p%d", p.cgoType(atype).C, i) + s += fmt.Sprintf("%s %s", p.cgoType(atype).C, exportParamName(aname, i)) }) s += ")" if len(exp.Doc) > 0 { fmt.Fprintf(fgcch, "\n%s", exp.Doc) + if !strings.HasSuffix(exp.Doc, "\n") { + fmt.Fprint(fgcch, "\n") + } } - fmt.Fprintf(fgcch, "\nextern %s;\n", s) + fmt.Fprintf(fgcch, "extern %s;\n", s) fmt.Fprintf(fgcc, "extern void _cgoexp%s_%s(void *, int, __SIZE_TYPE__);\n", cPrefix, exp.ExpName) fmt.Fprintf(fgcc, "\nCGO_NO_SANITIZE_THREAD") fmt.Fprintf(fgcc, "\n%s\n", s) fmt.Fprintf(fgcc, "{\n") fmt.Fprintf(fgcc, "\t__SIZE_TYPE__ _cgo_ctxt = _cgo_wait_runtime_init_done();\n") - fmt.Fprintf(fgcc, "\t%s %v a;\n", ctype, p.packedAttribute()) + fmt.Fprintf(fgcc, "\t%s %v _cgo_a;\n", ctype, p.packedAttribute()) if gccResult != "void" && (len(fntype.Results.List) > 1 || len(fntype.Results.List[0].Names) > 1) { fmt.Fprintf(fgcc, "\t%s r;\n", gccResult) } if fn.Recv != nil { - fmt.Fprintf(fgcc, "\ta.recv = recv;\n") + fmt.Fprintf(fgcc, "\t_cgo_a.recv = recv;\n") } forFieldList(fntype.Params, func(i int, aname string, atype ast.Expr) { - fmt.Fprintf(fgcc, "\ta.p%d = p%d;\n", i, i) + fmt.Fprintf(fgcc, "\t_cgo_a.p%d = %s;\n", i, exportParamName(aname, i)) }) fmt.Fprintf(fgcc, "\t_cgo_tsan_release();\n") - fmt.Fprintf(fgcc, "\tcrosscall2(_cgoexp%s_%s, &a, %d, _cgo_ctxt);\n", cPrefix, exp.ExpName, off) + fmt.Fprintf(fgcc, "\tcrosscall2(_cgoexp%s_%s, &_cgo_a, %d, _cgo_ctxt);\n", cPrefix, exp.ExpName, off) fmt.Fprintf(fgcc, "\t_cgo_tsan_acquire();\n") fmt.Fprintf(fgcc, "\t_cgo_release_context(_cgo_ctxt);\n") if gccResult != "void" { if len(fntype.Results.List) == 1 && len(fntype.Results.List[0].Names) <= 1 { - fmt.Fprintf(fgcc, "\treturn a.r0;\n") + fmt.Fprintf(fgcc, "\treturn _cgo_a.r0;\n") } else { forFieldList(fntype.Results, func(i int, aname string, atype ast.Expr) { - fmt.Fprintf(fgcc, "\tr.r%d = a.r%d;\n", i, i) + fmt.Fprintf(fgcc, "\tr.r%d = _cgo_a.r%d;\n", i, i) }) fmt.Fprintf(fgcc, "\treturn r;\n") } diff --git a/libgo/go/cmd/go/alldocs.go b/libgo/go/cmd/go/alldocs.go index c2678c3dd3c..68bad3cff1b 100644 --- a/libgo/go/cmd/go/alldocs.go +++ b/libgo/go/cmd/go/alldocs.go @@ -35,23 +35,24 @@ // // Additional help topics: // -// buildmode build modes -// c calling between Go and C -// cache build and test caching -// environment environment variables -// filetype file types -// go.mod the go.mod file -// gopath GOPATH environment variable -// gopath-get legacy GOPATH go get -// goproxy module proxy protocol -// importpath import path syntax -// modules modules, module versions, and more -// module-get module-aware go get -// module-auth module authentication using go.sum -// module-private module configuration for non-public modules -// packages package lists and patterns -// testflag testing flags -// testfunc testing functions +// buildconstraint build constraints +// buildmode build modes +// c calling between Go and C +// cache build and test caching +// environment environment variables +// filetype file types +// go.mod the go.mod file +// gopath GOPATH environment variable +// gopath-get legacy GOPATH go get +// goproxy module proxy protocol +// importpath import path syntax +// modules modules, module versions, and more +// module-get module-aware go get +// module-auth module authentication using go.sum +// module-private module configuration for non-public modules +// packages package lists and patterns +// testflag testing flags +// testfunc testing functions // // Use "go help " for more information about that topic. // @@ -547,6 +548,9 @@ // tag "generate" so that files may be examined by go generate but ignored // during build. // +// For packages with invalid code, generate processes only source files with a +// valid package clause. +// // If any generator returns an error exit status, "go generate" skips // all further processing for that package. // @@ -657,7 +661,10 @@ // this automatically as well. // // The -insecure flag permits fetching from repositories and resolving -// custom domains using insecure schemes such as HTTP. Use with caution. +// custom domains using insecure schemes such as HTTP. Use with caution. The +// GOINSECURE environment variable is usually a better alternative, since it +// provides control over which modules may be retrieved using an insecure scheme. +// See 'go help environment' for details. // // The second step is to download (if needed), build, and install // the named packages. @@ -1017,7 +1024,8 @@ // // Download downloads the named modules, which can be module patterns selecting // dependencies of the main module or module queries of the form path@version. -// With no arguments, download applies to all dependencies of the main module. +// With no arguments, download applies to all dependencies of the main module +// (equivalent to 'go mod download all'). // // The go command will automatically download modules as needed during ordinary // execution. The "go mod download" command is useful mainly for pre-filling @@ -1305,10 +1313,10 @@ // and its test source files to identify significant problems. If go vet // finds any problems, go test reports those and does not run the test // binary. Only a high-confidence subset of the default go vet checks are -// used. That subset is: 'atomic', 'bool', 'buildtags', 'nilfunc', and -// 'printf'. You can see the documentation for these and other vet tests -// via "go doc cmd/vet". To disable the running of go vet, use the -// -vet=off flag. +// used. That subset is: 'atomic', 'bool', 'buildtags', 'errorsas', +// 'ifaceassert', 'nilfunc', 'printf', and 'stringintconv'. You can see +// the documentation for these and other vet tests via "go doc cmd/vet". +// To disable the running of go vet, use the -vet=off flag. // // All test output and summary lines are printed to the go command's // standard output, even if the test printed them to its own standard @@ -1470,6 +1478,95 @@ // See also: go fmt, go fix. // // +// Build constraints +// +// A build constraint, also known as a build tag, is a line comment that begins +// +// // +build +// +// that lists the conditions under which a file should be included in the package. +// Constraints may appear in any kind of source file (not just Go), but +// they must appear near the top of the file, preceded +// only by blank lines and other line comments. These rules mean that in Go +// files a build constraint must appear before the package clause. +// +// To distinguish build constraints from package documentation, a series of +// build constraints must be followed by a blank line. +// +// A build constraint is evaluated as the OR of space-separated options. +// Each option evaluates as the AND of its comma-separated terms. +// Each term consists of letters, digits, underscores, and dots. +// A term may be negated with a preceding !. +// For example, the build constraint: +// +// // +build linux,386 darwin,!cgo +// +// corresponds to the boolean formula: +// +// (linux AND 386) OR (darwin AND (NOT cgo)) +// +// A file may have multiple build constraints. The overall constraint is the AND +// of the individual constraints. That is, the build constraints: +// +// // +build linux darwin +// // +build amd64 +// +// corresponds to the boolean formula: +// +// (linux OR darwin) AND amd64 +// +// During a particular build, the following words are satisfied: +// +// - the target operating system, as spelled by runtime.GOOS, set with the +// GOOS environment variable. +// - the target architecture, as spelled by runtime.GOARCH, set with the +// GOARCH environment variable. +// - the compiler being used, either "gc" or "gccgo" +// - "cgo", if the cgo command is supported (see CGO_ENABLED in +// 'go help environment'). +// - a term for each Go major release, through the current version: +// "go1.1" from Go version 1.1 onward, "go1.12" from Go 1.12, and so on. +// - any additional tags given by the -tags flag (see 'go help build'). +// +// There are no separate build tags for beta or minor releases. +// +// If a file's name, after stripping the extension and a possible _test suffix, +// matches any of the following patterns: +// *_GOOS +// *_GOARCH +// *_GOOS_GOARCH +// (example: source_windows_amd64.go) where GOOS and GOARCH represent +// any known operating system and architecture values respectively, then +// the file is considered to have an implicit build constraint requiring +// those terms (in addition to any explicit constraints in the file). +// +// Using GOOS=android matches build tags and files as for GOOS=linux +// in addition to android tags and files. +// +// Using GOOS=illumos matches build tags and files as for GOOS=solaris +// in addition to illumos tags and files. +// +// To keep a file from being considered for the build: +// +// // +build ignore +// +// (any other unsatisfied word will work as well, but "ignore" is conventional.) +// +// To build a file only when using cgo, and only on Linux and OS X: +// +// // +build linux,cgo darwin,cgo +// +// Such a file is usually paired with another file implementing the +// default functionality for other systems, which in this case would +// carry the constraint: +// +// // +build !linux,!darwin !cgo +// +// Naming a file dns_windows.go will cause it to be included only when +// building the package for Windows; similarly, math_386.s will be included +// only when building the package for 32-bit x86. +// +// // Build modes // // The 'go build' and 'go install' commands take a -buildmode argument which @@ -1603,6 +1700,8 @@ // GOCACHE // The directory where the go command will store cached // information for reuse in future builds. +// GOMODCACHE +// The directory where the go command will store downloaded modules. // GODEBUG // Enable various debugging facilities. See 'go doc runtime' // for details. @@ -1620,6 +1719,9 @@ // Comma-separated list of glob patterns (in the syntax of Go's path.Match) // of module path prefixes that should always be fetched in an insecure // manner. Only applies to dependencies that are being fetched directly. +// Unlike the -insecure flag on 'go get', GOINSECURE does not disable +// checksum database validation. GOPRIVATE or GONOSUMDB may be used +// to achieve that. // GOOS // The operating system for which to compile code. // Examples are linux, darwin, windows, netbsd. @@ -2693,15 +2795,15 @@ // Go module mirror run by Google and fall back to a direct connection // if the proxy reports that it does not have the module (HTTP error 404 or 410). // See https://proxy.golang.org/privacy for the service's privacy policy. -// If GOPROXY is set to the string "direct", downloads use a direct connection -// to source control servers. Setting GOPROXY to "off" disallows downloading -// modules from any source. Otherwise, GOPROXY is expected to be a comma-separated -// list of the URLs of module proxies, in which case the go command will fetch -// modules from those proxies. For each request, the go command tries each proxy -// in sequence, only moving to the next if the current proxy returns a 404 or 410 -// HTTP response. The string "direct" may appear in the proxy list, -// to cause a direct connection to be attempted at that point in the search. -// Any proxies listed after "direct" are never consulted. +// +// If GOPROXY is set to the string "direct", downloads use a direct connection to +// source control servers. Setting GOPROXY to "off" disallows downloading modules +// from any source. Otherwise, GOPROXY is expected to be list of module proxy URLs +// separated by either comma (,) or pipe (|) characters, which control error +// fallback behavior. For each request, the go command tries each proxy in +// sequence. If there is an error, the go command will try the next proxy in the +// list if the error is a 404 or 410 HTTP response or if the current proxy is +// followed by a pipe character, indicating it is safe to fall back on any error. // // The GOPRIVATE and GONOPROXY environment variables allow bypassing // the proxy for selected modules. See 'go help module-private' for details. diff --git a/libgo/go/cmd/go/go_test.go b/libgo/go/cmd/go/go_test.go index 40999f22f8d..021930a8a81 100644 --- a/libgo/go/cmd/go/go_test.go +++ b/libgo/go/cmd/go/go_test.go @@ -6,9 +6,9 @@ package main_test import ( "bytes" - "context" "debug/elf" "debug/macho" + "debug/pe" "flag" "fmt" "go/format" @@ -60,7 +60,7 @@ func init() { canRun = false case "darwin": switch runtime.GOARCH { - case "arm", "arm64": + case "arm64": canRun = false } case "linux": @@ -113,12 +113,6 @@ var testGo string var testTmpDir string var testBin string -// testCtx is canceled when the test binary is about to time out. -// -// If https://golang.org/issue/28135 is accepted, uses of this variable in test -// functions should be replaced by t.Context(). -var testCtx = context.Background() - // The TestMain function creates a go command for testing purposes and // deletes it after the tests have been run. func TestMain(m *testing.M) { @@ -130,23 +124,9 @@ func TestMain(m *testing.M) { fmt.Printf("SKIP\n") return } - os.Unsetenv("GOROOT_FINAL") flag.Parse() - timeoutFlag := flag.Lookup("test.timeout") - if timeoutFlag != nil { - // TODO(golang.org/issue/28147): The go command does not pass the - // test.timeout flag unless either -timeout or -test.timeout is explicitly - // set on the command line. - if d := timeoutFlag.Value.(flag.Getter).Get().(time.Duration); d != 0 { - aBitShorter := d * 95 / 100 - var cancel context.CancelFunc - testCtx, cancel = context.WithTimeout(testCtx, aBitShorter) - defer cancel() - } - } - if *proxyAddr != "" { StartProxy() select {} @@ -198,6 +178,12 @@ func TestMain(m *testing.M) { return strings.TrimSpace(string(out)) } testGOROOT = goEnv("GOROOT") + os.Setenv("TESTGO_GOROOT", testGOROOT) + // Ensure that GOROOT is set explicitly. + // Otherwise, if the toolchain was built with GOROOT_FINAL set but has not + // yet been moved to its final location, programs that invoke runtime.GOROOT + // may accidentally use the wrong path. + os.Setenv("GOROOT", testGOROOT) // The whole GOROOT/pkg tree was installed using the GOHOSTOS/GOHOSTARCH // toolchain (installed in GOROOT/pkg/tool/GOHOSTOS_GOHOSTARCH). @@ -234,8 +220,10 @@ func TestMain(m *testing.M) { } testCC = strings.TrimSpace(string(out)) - if out, err := exec.Command(testGo, "env", "CGO_ENABLED").Output(); err != nil { - fmt.Fprintf(os.Stderr, "running testgo failed: %v\n", err) + cmd := exec.Command(testGo, "env", "CGO_ENABLED") + cmd.Stderr = new(strings.Builder) + if out, err := cmd.Output(); err != nil { + fmt.Fprintf(os.Stderr, "running testgo failed: %v\n%s", err, cmd.Stderr) canRun = false } else { canCgo, err = strconv.ParseBool(strings.TrimSpace(string(out))) @@ -317,7 +305,6 @@ var mtimeTick time.Duration = 1 * time.Second type testgoData struct { t *testing.T temps []string - wd string env []string tempdir string ran bool @@ -367,9 +354,6 @@ func (tg *testgoData) parallel() { if tg.ran { tg.t.Fatal("internal testsuite error: call to parallel after run") } - if tg.wd != "" { - tg.t.Fatal("internal testsuite error: call to parallel after cd") - } for _, e := range tg.env { if strings.HasPrefix(e, "GOROOT=") || strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "GOBIN=") { val := e[strings.Index(e, "=")+1:] @@ -392,24 +376,6 @@ func (tg *testgoData) pwd() string { return wd } -// cd changes the current directory to the named directory. Note that -// using this means that the test must not be run in parallel with any -// other tests. -func (tg *testgoData) cd(dir string) { - tg.t.Helper() - if tg.inParallel { - tg.t.Fatal("internal testsuite error: changing directory when running in parallel") - } - if tg.wd == "" { - tg.wd = tg.pwd() - } - abs, err := filepath.Abs(dir) - tg.must(os.Chdir(dir)) - if err == nil { - tg.setenv("PWD", abs) - } -} - // sleep sleeps for one tick, where a tick is a conservative estimate // of how long it takes for a file modification to get a different // mtime. @@ -680,15 +646,6 @@ func (tg *testgoData) creatingTemp(path string) { if filepath.IsAbs(path) && !strings.HasPrefix(path, tg.tempdir) { tg.t.Fatalf("internal testsuite error: creatingTemp(%q) with absolute path not in temporary directory", path) } - // If we have changed the working directory, make sure we have - // an absolute path, because we are going to change directory - // back before we remove the temporary. - if !filepath.IsAbs(path) { - if tg.wd == "" || strings.HasPrefix(tg.wd, testGOROOT) { - tg.t.Fatalf("internal testsuite error: creatingTemp(%q) within GOROOT/src", path) - } - path = filepath.Join(tg.wd, path) - } tg.must(robustio.RemoveAll(path)) tg.temps = append(tg.temps, path) } @@ -788,21 +745,6 @@ func (tg *testgoData) wantExecutable(path, msg string) { } } -// wantArchive fails if path is not an archive. -func (tg *testgoData) wantArchive(path string) { - tg.t.Helper() - f, err := os.Open(path) - if err != nil { - tg.t.Fatal(err) - } - buf := make([]byte, 100) - io.ReadFull(f, buf) - f.Close() - if !bytes.HasPrefix(buf, []byte("!\n")) { - tg.t.Fatalf("file %s exists but is not an archive", path) - } -} - // isStale reports whether pkg is stale, and why func (tg *testgoData) isStale(pkg string) (bool, string) { tg.t.Helper() @@ -857,16 +799,6 @@ var testWork = flag.Bool("testwork", false, "") // cleanup cleans up a test that runs testgo. func (tg *testgoData) cleanup() { tg.t.Helper() - if tg.wd != "" { - wd, _ := os.Getwd() - tg.t.Logf("ended in %s", wd) - - if err := os.Chdir(tg.wd); err != nil { - // We are unlikely to be able to continue. - fmt.Fprintln(os.Stderr, "could not restore working directory, crashing:", err) - os.Exit(2) - } - } if *testWork { tg.t.Logf("TESTWORK=%s\n", tg.path(".")) return @@ -883,10 +815,9 @@ func removeAll(dir string) error { // module cache has 0444 directories; // make them writable in order to remove content. filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { - if err != nil { - return nil // ignore errors walking in file system - } - if info.IsDir() { + // chmod not only directories, but also things that we couldn't even stat + // due to permission errors: they may also be unreadable directories. + if err != nil || info.IsDir() { os.Chmod(path, 0777) } return nil @@ -1012,35 +943,6 @@ func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) { tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with old release") } -func TestInternalPackagesInGOROOTAreRespected(t *testing.T) { - skipIfGccgo(t, "gccgo does not have GOROOT") - tg := testgo(t) - defer tg.cleanup() - tg.runFail("build", "-v", "./testdata/testinternal") - tg.grepBoth(`testinternal(\/|\\)p\.go\:3\:8\: use of internal package net/http/internal not allowed`, "wrong error message for testdata/testinternal") -} - -func TestInternalPackagesOutsideGOROOTAreRespected(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.runFail("build", "-v", "./testdata/testinternal2") - tg.grepBoth(`testinternal2(\/|\\)p\.go\:3\:8\: use of internal package .*internal/w not allowed`, "wrote error message for testdata/testinternal2") -} - -func TestInternalPackageErrorsAreHandled(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.run("list", "./testdata/testinternal3") -} - -func TestInternalCache(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/testinternal4")) - tg.runFail("build", "p") - tg.grepStderr("internal", "did not fail to build p") -} - // cmd/go: custom import path checking should not apply to Go packages without import comment. func TestIssue10952(t *testing.T) { testenv.MustHaveExternalNetwork(t) @@ -1128,6 +1030,7 @@ func TestGetGitDefaultBranch(t *testing.T) { func TestAccidentalGitCheckout(t *testing.T) { testenv.MustHaveExternalNetwork(t) testenv.MustHaveExecPath(t, "git") + testenv.MustHaveExecPath(t, "svn") tg := testgo(t) defer tg.cleanup() @@ -1146,87 +1049,6 @@ func TestAccidentalGitCheckout(t *testing.T) { } } -func TestRelativeImportsGoTest(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.run("test", "./testdata/testimport") -} - -func TestRelativeImportsGoTestDashI(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - - // don't let test -i overwrite runtime - tg.wantNotStale("runtime", "", "must be non-stale before test -i") - - tg.run("test", "-i", "./testdata/testimport") -} - -func TestRelativeImportsInCommandLinePackage(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - // TODO: tg.parallel() - files, err := filepath.Glob("./testdata/testimport/*.go") - tg.must(err) - tg.run(append([]string{"test"}, files...)...) -} - -func TestVersionControlErrorMessageIncludesCorrectDirectory(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/shadow/root1")) - tg.runFail("get", "-u", "foo") - - // TODO(iant): We should not have to use strconv.Quote here. - // The code in vcs.go should be changed so that it is not required. - quoted := strconv.Quote(filepath.Join("testdata", "shadow", "root1", "src", "foo")) - quoted = quoted[1 : len(quoted)-1] - - tg.grepStderr(regexp.QuoteMeta(quoted), "go get -u error does not mention shadow/root1/src/foo") -} - -func TestInstallFailsWithNoBuildableFiles(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.setenv("CGO_ENABLED", "0") - tg.runFail("install", "cgotest") - tg.grepStderr("build constraints exclude all Go files", "go install cgotest did not report 'build constraints exclude all Go files'") -} - -// Issue 21895 -func TestMSanAndRaceRequireCgo(t *testing.T) { - if !canMSan && !canRace { - t.Skip("skipping because both msan and the race detector are not supported") - } - - tg := testgo(t) - defer tg.cleanup() - tg.tempFile("triv.go", `package main; func main() {}`) - tg.setenv("CGO_ENABLED", "0") - if canRace { - tg.runFail("install", "-race", "triv.go") - tg.grepStderr("-race requires cgo", "did not correctly report that -race requires cgo") - tg.grepStderrNot("-msan", "reported that -msan instead of -race requires cgo") - } - if canMSan { - tg.runFail("install", "-msan", "triv.go") - tg.grepStderr("-msan requires cgo", "did not correctly report that -msan requires cgo") - tg.grepStderrNot("-race", "reported that -race instead of -msan requires cgo") - } -} - -func TestRelativeGOBINFail(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.tempFile("triv.go", `package main; func main() {}`) - tg.cd(tg.path(".")) - tg.setenv("GOBIN", ".") - tg.cd(tg.path(".")) - tg.runFail("install") - tg.grepStderr("cannot install, GOBIN must be an absolute path", "go install must fail if $GOBIN is a relative path") -} - func TestPackageMainTestCompilerFlags(t *testing.T) { tg := testgo(t) defer tg.cleanup() @@ -1240,54 +1062,6 @@ func TestPackageMainTestCompilerFlags(t *testing.T) { tg.grepStderr(`([\\/]compile|gccgo).* (-p p1|-fgo-pkgpath=p1).*p1\.go`, "should have run compile -p p1 p1.go") } -// Issue 12690 -func TestPackageNotStaleWithTrailingSlash(t *testing.T) { - skipIfGccgo(t, "gccgo does not have GOROOT") - tg := testgo(t) - defer tg.cleanup() - - // Make sure the packages below are not stale. - tg.wantNotStale("runtime", "", "must be non-stale before test runs") - tg.wantNotStale("os", "", "must be non-stale before test runs") - tg.wantNotStale("io", "", "must be non-stale before test runs") - - goroot := runtime.GOROOT() - tg.setenv("GOROOT", goroot+"/") - - tg.wantNotStale("runtime", "", "with trailing slash in GOROOT, runtime listed as stale") - tg.wantNotStale("os", "", "with trailing slash in GOROOT, os listed as stale") - tg.wantNotStale("io", "", "with trailing slash in GOROOT, io listed as stale") -} - -func TestGoGetNonPkg(t *testing.T) { - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") - - tg := testgo(t) - defer tg.cleanup() - tg.tempDir("gobin") - tg.setenv("GOPATH", tg.path(".")) - tg.setenv("GOBIN", tg.path("gobin")) - tg.runFail("get", "-d", "golang.org/x/tools") - tg.grepStderr("golang.org/x/tools: no Go files", "missing error") - tg.runFail("get", "-d", "-u", "golang.org/x/tools") - tg.grepStderr("golang.org/x/tools: no Go files", "missing error") - tg.runFail("get", "-d", "golang.org/x/tools") - tg.grepStderr("golang.org/x/tools: no Go files", "missing error") -} - -func TestGoGetTestOnlyPkg(t *testing.T) { - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") - - tg := testgo(t) - defer tg.cleanup() - tg.tempDir("gopath") - tg.setenv("GOPATH", tg.path("gopath")) - tg.run("get", "golang.org/x/tour/content...") - tg.run("get", "-t", "golang.org/x/tour/content...") -} - // Issue 4104. func TestGoTestWithPackageListedMultipleTimes(t *testing.T) { tooSlow(t) @@ -1338,19 +1112,6 @@ func TestGoListCmdOnlyShowsCommands(t *testing.T) { } } -func TestGoListDedupsPackages(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - // TODO: tg.parallel() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.run("list", "xtestonly", "./testdata/src/xtestonly/...") - got := strings.TrimSpace(tg.getStdout()) - const want = "xtestonly" - if got != want { - t.Errorf("got %q; want %q", got, want) - } -} - func TestGoListDeps(t *testing.T) { tg := testgo(t) defer tg.cleanup() @@ -1618,57 +1379,6 @@ func TestDefaultGOPATHPrintedSearchList(t *testing.T) { tg.grepStderr(regexp.QuoteMeta(tg.path("home/go/src/github.com/golang/example/hello"))+`.*from \$GOPATH`, "expected default GOPATH") } -// Issue 4186. go get cannot be used to download packages to $GOROOT. -// Test that without GOPATH set, go get should fail. -func TestGoGetIntoGOROOT(t *testing.T) { - testenv.MustHaveExternalNetwork(t) - - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.tempDir("src") - - // Fails because GOROOT=GOPATH - tg.setenv("GOPATH", tg.path(".")) - tg.setenv("GOROOT", tg.path(".")) - tg.runFail("get", "-d", "github.com/golang/example/hello") - tg.grepStderr("warning: GOPATH set to GOROOT", "go should detect GOPATH=GOROOT") - tg.grepStderr(`\$GOPATH must not be set to \$GOROOT`, "go should detect GOPATH=GOROOT") - - // Fails because GOROOT=GOPATH after cleaning. - tg.setenv("GOPATH", tg.path(".")+"/") - tg.setenv("GOROOT", tg.path(".")) - tg.runFail("get", "-d", "github.com/golang/example/hello") - tg.grepStderr("warning: GOPATH set to GOROOT", "go should detect GOPATH=GOROOT") - tg.grepStderr(`\$GOPATH must not be set to \$GOROOT`, "go should detect GOPATH=GOROOT") - - tg.setenv("GOPATH", tg.path(".")) - tg.setenv("GOROOT", tg.path(".")+"/") - tg.runFail("get", "-d", "github.com/golang/example/hello") - tg.grepStderr("warning: GOPATH set to GOROOT", "go should detect GOPATH=GOROOT") - tg.grepStderr(`\$GOPATH must not be set to \$GOROOT`, "go should detect GOPATH=GOROOT") - - // Fails because GOROOT=$HOME/go so default GOPATH unset. - tg.tempDir("home/go") - tg.setenv(homeEnvName(), tg.path("home")) - tg.setenv("GOPATH", "") - tg.setenv("GOROOT", tg.path("home/go")) - tg.runFail("get", "-d", "github.com/golang/example/hello") - tg.grepStderr(`\$GOPATH not set`, "expected GOPATH not set") - - tg.setenv(homeEnvName(), tg.path("home")+"/") - tg.setenv("GOPATH", "") - tg.setenv("GOROOT", tg.path("home/go")) - tg.runFail("get", "-d", "github.com/golang/example/hello") - tg.grepStderr(`\$GOPATH not set`, "expected GOPATH not set") - - tg.setenv(homeEnvName(), tg.path("home")) - tg.setenv("GOPATH", "") - tg.setenv("GOROOT", tg.path("home/go")+"/") - tg.runFail("get", "-d", "github.com/golang/example/hello") - tg.grepStderr(`\$GOPATH not set`, "expected GOPATH not set") -} - func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) { skipIfGccgo(t, "gccgo does not support -ldflags -X") tooSlow(t) @@ -1684,54 +1394,6 @@ func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) { tg.grepStderr("^hello world", `ldflags -X "main.extern=hello world"' failed`) } -func TestGoTestCpuprofileLeavesBinaryBehind(t *testing.T) { - skipIfGccgo(t, "gccgo has no standard packages") - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - // TODO: tg.parallel() - tg.makeTempdir() - tg.cd(tg.path(".")) - tg.run("test", "-cpuprofile", "errors.prof", "errors") - tg.wantExecutable("errors.test"+exeSuffix, "go test -cpuprofile did not create errors.test") -} - -func TestGoTestCpuprofileDashOControlsBinaryLocation(t *testing.T) { - skipIfGccgo(t, "gccgo has no standard packages") - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - // TODO: tg.parallel() - tg.makeTempdir() - tg.cd(tg.path(".")) - tg.run("test", "-cpuprofile", "errors.prof", "-o", "myerrors.test"+exeSuffix, "errors") - tg.wantExecutable("myerrors.test"+exeSuffix, "go test -cpuprofile -o myerrors.test did not create myerrors.test") -} - -func TestGoTestMutexprofileLeavesBinaryBehind(t *testing.T) { - skipIfGccgo(t, "gccgo has no standard packages") - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - // TODO: tg.parallel() - tg.makeTempdir() - tg.cd(tg.path(".")) - tg.run("test", "-mutexprofile", "errors.prof", "errors") - tg.wantExecutable("errors.test"+exeSuffix, "go test -mutexprofile did not create errors.test") -} - -func TestGoTestMutexprofileDashOControlsBinaryLocation(t *testing.T) { - skipIfGccgo(t, "gccgo has no standard packages") - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - // TODO: tg.parallel() - tg.makeTempdir() - tg.cd(tg.path(".")) - tg.run("test", "-mutexprofile", "errors.prof", "-o", "myerrors.test"+exeSuffix, "errors") - tg.wantExecutable("myerrors.test"+exeSuffix, "go test -mutexprofile -o myerrors.test did not create myerrors.test") -} - func TestGoTestDashCDashOControlsBinaryLocation(t *testing.T) { skipIfGccgo(t, "gccgo has no standard packages") tooSlow(t) @@ -1770,88 +1432,6 @@ func TestGoTestDashIDashOWritesBinary(t *testing.T) { tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -o myerrors.test did not create myerrors.test") } -// Issue 4568. -func TestSymlinksList(t *testing.T) { - testenv.MustHaveSymlink(t) - - tg := testgo(t) - defer tg.cleanup() - // TODO: tg.parallel() - tg.tempDir("src") - tg.must(os.Symlink(tg.path("."), tg.path("src/dir1"))) - tg.tempFile("src/dir1/p.go", "package p") - tg.setenv("GOPATH", tg.path(".")) - tg.cd(tg.path("src")) - tg.run("list", "-f", "{{.Root}}", "dir1") - if strings.TrimSpace(tg.getStdout()) != tg.path(".") { - t.Error("confused by symlinks") - } -} - -// Issue 14054. -func TestSymlinksVendor(t *testing.T) { - testenv.MustHaveSymlink(t) - - tg := testgo(t) - defer tg.cleanup() - // TODO: tg.parallel() - tg.tempDir("gopath/src/dir1/vendor/v") - tg.tempFile("gopath/src/dir1/p.go", "package main\nimport _ `v`\nfunc main(){}") - tg.tempFile("gopath/src/dir1/vendor/v/v.go", "package v") - tg.must(os.Symlink(tg.path("gopath/src/dir1"), tg.path("symdir1"))) - tg.setenv("GOPATH", tg.path("gopath")) - tg.cd(tg.path("symdir1")) - tg.run("list", "-f", "{{.Root}}", ".") - if strings.TrimSpace(tg.getStdout()) != tg.path("gopath") { - t.Error("list confused by symlinks") - } - - // All of these should succeed, not die in vendor-handling code. - tg.run("run", "p.go") - tg.run("build") - tg.run("install") -} - -// Issue 15201. -func TestSymlinksVendor15201(t *testing.T) { - testenv.MustHaveSymlink(t) - - tg := testgo(t) - defer tg.cleanup() - - tg.tempDir("gopath/src/x/y/_vendor/src/x") - tg.must(os.Symlink("../../..", tg.path("gopath/src/x/y/_vendor/src/x/y"))) - tg.tempFile("gopath/src/x/y/w/w.go", "package w\nimport \"x/y/z\"\n") - tg.must(os.Symlink("../_vendor/src", tg.path("gopath/src/x/y/w/vendor"))) - tg.tempFile("gopath/src/x/y/z/z.go", "package z\n") - - tg.setenv("GOPATH", tg.path("gopath/src/x/y/_vendor")+string(filepath.ListSeparator)+tg.path("gopath")) - tg.cd(tg.path("gopath/src")) - tg.run("list", "./...") -} - -func TestSymlinksInternal(t *testing.T) { - testenv.MustHaveSymlink(t) - - tg := testgo(t) - defer tg.cleanup() - tg.tempDir("gopath/src/dir1/internal/v") - tg.tempFile("gopath/src/dir1/p.go", "package main\nimport _ `dir1/internal/v`\nfunc main(){}") - tg.tempFile("gopath/src/dir1/internal/v/v.go", "package v") - tg.must(os.Symlink(tg.path("gopath/src/dir1"), tg.path("symdir1"))) - tg.setenv("GOPATH", tg.path("gopath")) - tg.cd(tg.path("symdir1")) - tg.run("list", "-f", "{{.Root}}", ".") - if strings.TrimSpace(tg.getStdout()) != tg.path("gopath") { - t.Error("list confused by symlinks") - } - - // All of these should succeed, not die in internal-handling code. - tg.run("run", "p.go") - tg.run("build") - tg.run("install") -} - // Issue 4515. func TestInstallWithTags(t *testing.T) { tooSlow(t) @@ -1880,52 +1460,6 @@ func TestInstallWithTags(t *testing.T) { } } -// Issue 4773 -func TestCaseCollisions(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.tempDir("src/example/a/pkg") - tg.tempDir("src/example/a/Pkg") - tg.tempDir("src/example/b") - tg.setenv("GOPATH", tg.path(".")) - tg.tempFile("src/example/a/a.go", `package p - import ( - _ "example/a/pkg" - _ "example/a/Pkg" - )`) - tg.tempFile("src/example/a/pkg/pkg.go", `package pkg`) - tg.tempFile("src/example/a/Pkg/pkg.go", `package pkg`) - tg.run("list", "-json", "example/a") - tg.grepStdout("case-insensitive import collision", "go list -json example/a did not report import collision") - tg.runFail("build", "example/a") - tg.grepStderr("case-insensitive import collision", "go build example/a did not report import collision") - tg.tempFile("src/example/b/file.go", `package b`) - tg.tempFile("src/example/b/FILE.go", `package b`) - f, err := os.Open(tg.path("src/example/b")) - tg.must(err) - names, err := f.Readdirnames(0) - tg.must(err) - tg.check(f.Close()) - args := []string{"list"} - if len(names) == 2 { - // case-sensitive file system, let directory read find both files - args = append(args, "example/b") - } else { - // case-insensitive file system, list files explicitly on command line - args = append(args, tg.path("src/example/b/file.go"), tg.path("src/example/b/FILE.go")) - } - tg.runFail(args...) - tg.grepStderr("case-insensitive file name collision", "go list example/b did not report file name collision") - - tg.runFail("list", "example/a/pkg", "example/a/Pkg") - tg.grepStderr("case-insensitive import collision", "go list example/a/pkg example/a/Pkg did not report import collision") - tg.run("list", "-json", "-e", "example/a/pkg", "example/a/Pkg") - tg.grepStdout("case-insensitive import collision", "go list -json -e example/a/pkg example/a/Pkg did not report import collision") - tg.runFail("build", "example/a/pkg", "example/a/Pkg") - tg.grepStderr("case-insensitive import collision", "go build example/a/pkg example/a/Pkg did not report import collision") -} - // Issue 17451, 17662. func TestSymlinkWarning(t *testing.T) { tg := testgo(t) @@ -1951,383 +1485,55 @@ func TestSymlinkWarning(t *testing.T) { tg.grepStderr("ignoring symlink", "list should have reported symlink") } -// Issue 8181. -func TestGoGetDashTIssue8181(t *testing.T) { - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") +func TestCgoShowsFullPathNames(t *testing.T) { + if !canCgo { + t.Skip("skipping because cgo not enabled") + } tg := testgo(t) defer tg.cleanup() tg.parallel() - tg.makeTempdir() + tg.tempFile("src/x/y/dirname/foo.go", ` + package foo + import "C" + func f() {`) tg.setenv("GOPATH", tg.path(".")) - tg.run("get", "-v", "-t", "github.com/rsc/go-get-issue-8181/a", "github.com/rsc/go-get-issue-8181/b") - tg.run("list", "...") - tg.grepStdout("x/build/gerrit", "missing expected x/build/gerrit") + tg.runFail("build", "x/y/dirname") + tg.grepBoth("x/y/dirname", "error did not use full path") } -func TestIssue11307(t *testing.T) { - // go get -u was not working except in checkout directory - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") +func TestCgoHandlesWlORIGIN(t *testing.T) { + tooSlow(t) + if !canCgo { + t.Skip("skipping because cgo not enabled") + } tg := testgo(t) defer tg.cleanup() tg.parallel() - tg.makeTempdir() + tg.tempFile("src/origin/origin.go", `package origin + // #cgo !darwin LDFLAGS: -Wl,-rpath,$ORIGIN + // void f(void) {} + import "C" + func f() { C.f() }`) tg.setenv("GOPATH", tg.path(".")) - tg.run("get", "github.com/rsc/go-get-issue-11307") - tg.run("get", "-u", "github.com/rsc/go-get-issue-11307") // was failing + tg.run("build", "origin") } -func TestShadowingLogic(t *testing.T) { - skipIfGccgo(t, "gccgo has no standard packages") +func TestCgoPkgConfig(t *testing.T) { + tooSlow(t) + if !canCgo { + t.Skip("skipping because cgo not enabled") + } tg := testgo(t) defer tg.cleanup() - pwd := tg.pwd() - sep := string(filepath.ListSeparator) - tg.setenv("GOPATH", filepath.Join(pwd, "testdata", "shadow", "root1")+sep+filepath.Join(pwd, "testdata", "shadow", "root2")) - - // The math in root1 is not "math" because the standard math is. - tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root1/src/math") - pwdForwardSlash := strings.ReplaceAll(pwd, string(os.PathSeparator), "/") - if !strings.HasPrefix(pwdForwardSlash, "/") { - pwdForwardSlash = "/" + pwdForwardSlash - } - // The output will have makeImportValid applies, but we only - // bother to deal with characters we might reasonably see. - for _, r := range " :" { - pwdForwardSlash = strings.ReplaceAll(pwdForwardSlash, string(r), "_") - } - want := "(_" + pwdForwardSlash + "/testdata/shadow/root1/src/math) (" + filepath.Join(runtime.GOROOT(), "src", "math") + ")" - if strings.TrimSpace(tg.getStdout()) != want { - t.Error("shadowed math is not shadowed; looking for", want) - } + tg.parallel() - // The foo in root1 is "foo". - tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root1/src/foo") - if strings.TrimSpace(tg.getStdout()) != "(foo) ()" { - t.Error("unshadowed foo is shadowed") - } - - // The foo in root2 is not "foo" because the foo in root1 got there first. - tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root2/src/foo") - want = "(_" + pwdForwardSlash + "/testdata/shadow/root2/src/foo) (" + filepath.Join(pwd, "testdata", "shadow", "root1", "src", "foo") + ")" - if strings.TrimSpace(tg.getStdout()) != want { - t.Error("shadowed foo is not shadowed; looking for", want) - } - - // The error for go install should mention the conflicting directory. - tg.runFail("install", "./testdata/shadow/root2/src/foo") - want = "go install: no install location for " + filepath.Join(pwd, "testdata", "shadow", "root2", "src", "foo") + ": hidden by " + filepath.Join(pwd, "testdata", "shadow", "root1", "src", "foo") - if strings.TrimSpace(tg.getStderr()) != want { - t.Error("wrong shadowed install error; looking for", want) - } -} - -// Only succeeds if source order is preserved. -func TestSourceFileNameOrderPreserved(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.run("test", "testdata/example1_test.go", "testdata/example2_test.go") -} - -// Check that coverage analysis works at all. -// Don't worry about the exact numbers but require not 0.0%. -func checkCoverage(tg *testgoData, data string) { - tg.t.Helper() - if regexp.MustCompile(`[^0-9]0\.0%`).MatchString(data) { - tg.t.Error("some coverage results are 0.0%") - } -} - -func TestCoverageRuns(t *testing.T) { - skipIfGccgo(t, "gccgo has no cover tool") - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - tg.run("test", "-short", "-coverpkg=strings", "strings", "regexp") - data := tg.getStdout() + tg.getStderr() - tg.run("test", "-short", "-cover", "strings", "math", "regexp") - data += tg.getStdout() + tg.getStderr() - checkCoverage(tg, data) -} - -func TestCoverageDotImport(t *testing.T) { - skipIfGccgo(t, "gccgo has no cover tool") - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.run("test", "-coverpkg=coverdot1,coverdot2", "coverdot2") - data := tg.getStdout() + tg.getStderr() - checkCoverage(tg, data) -} - -func TestCoverageSyncAtomicImport(t *testing.T) { - skipIfGccgo(t, "gccgo has no cover tool") - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.run("test", "-short", "-cover", "-covermode=atomic", "-coverpkg=coverdep/p1", "coverdep") -} - -func TestCoverageDepLoop(t *testing.T) { - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - // coverdep2/p1's xtest imports coverdep2/p2 which imports coverdep2/p1. - // Make sure that coverage on coverdep2/p2 recompiles coverdep2/p2. - tg.run("test", "-short", "-cover", "coverdep2/p1") - tg.grepStdout("coverage: 100.0% of statements", "expected 100.0% coverage") -} - -func TestCoverageNoStatements(t *testing.T) { - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - tg.run("test", "-cover", "./testdata/testcover/pkg4") - tg.grepStdout("[no statements]", "expected [no statements] for pkg4") -} - -func TestCoverageErrorLine(t *testing.T) { - skipIfGccgo(t, "gccgo has no cover tool") - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.makeTempdir() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.setenv("GOTMPDIR", tg.tempdir) - - tg.runFail("test", "coverbad") - tg.grepStderr(`coverbad[\\/]p\.go:4`, "did not find coverbad/p.go:4") - if canCgo { - tg.grepStderr(`coverbad[\\/]p1\.go:6`, "did not find coverbad/p1.go:6") - } - tg.grepStderrNot(regexp.QuoteMeta(tg.tempdir), "found temporary directory in error") - stderr := tg.getStderr() - - tg.runFail("test", "-cover", "coverbad") - stderr2 := tg.getStderr() - - // It's OK that stderr2 drops the character position in the error, - // because of the //line directive (see golang.org/issue/22662). - stderr = strings.ReplaceAll(stderr, "p.go:4:2:", "p.go:4:") - if stderr != stderr2 { - t.Logf("test -cover changed error messages:\nbefore:\n%s\n\nafter:\n%s", stderr, stderr2) - t.Skip("golang.org/issue/22660") - t.FailNow() - } -} - -func TestTestBuildFailureOutput(t *testing.T) { - tooSlow(t) - - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - - // Doesn't build, -x output should not claim to run test. - tg.runFail("test", "-x", "coverbad") - tg.grepStderrNot(`[\\/]coverbad\.test( |$)`, "claimed to run test") -} - -func TestCoverageFunc(t *testing.T) { - skipIfGccgo(t, "gccgo has no cover tool") - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.makeTempdir() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - - tg.run("test", "-outputdir="+tg.tempdir, "-coverprofile=cover.out", "coverasm") - tg.run("tool", "cover", "-func="+tg.path("cover.out")) - tg.grepStdout(`\tg\t*100.0%`, "did not find g 100% covered") - tg.grepStdoutNot(`\tf\t*[0-9]`, "reported coverage for assembly function f") -} - -// Issue 24588. -func TestCoverageDashC(t *testing.T) { - skipIfGccgo(t, "gccgo has no cover tool") - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.makeTempdir() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.run("test", "-c", "-o", tg.path("coverdep"), "-coverprofile="+tg.path("no/such/dir/cover.out"), "coverdep") - tg.wantExecutable(tg.path("coverdep"), "go -test -c -coverprofile did not create executable") -} - -func TestTestEmpty(t *testing.T) { - if !canRace { - t.Skip("no race detector") - } - - wd, _ := os.Getwd() - testdata := filepath.Join(wd, "testdata") - for _, dir := range []string{"pkg", "test", "xtest", "pkgtest", "pkgxtest", "pkgtestxtest", "testxtest"} { - t.Run(dir, func(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.setenv("GOPATH", testdata) - tg.cd(filepath.Join(testdata, "src/empty/"+dir)) - tg.run("test", "-cover", "-coverpkg=.", "-race") - }) - if testing.Short() { - break - } - } -} - -func TestNoGoError(t *testing.T) { - wd, _ := os.Getwd() - testdata := filepath.Join(wd, "testdata") - for _, dir := range []string{"empty/test", "empty/xtest", "empty/testxtest", "exclude", "exclude/ignore", "exclude/empty"} { - t.Run(dir, func(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.setenv("GOPATH", testdata) - tg.cd(filepath.Join(testdata, "src")) - tg.runFail("build", "./"+dir) - var want string - if strings.Contains(dir, "test") { - want = "no non-test Go files in " - } else if dir == "exclude" { - want = "build constraints exclude all Go files in " - } else { - want = "no Go files in " - } - tg.grepStderr(want, "wrong reason for failure") - }) - } -} - -func TestTestRaceInstall(t *testing.T) { - if !canRace { - t.Skip("no race detector") - } - tooSlow(t) - - tg := testgo(t) - defer tg.cleanup() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - - tg.tempDir("pkg") - pkgdir := tg.path("pkg") - tg.run("install", "-race", "-pkgdir="+pkgdir, "std") - tg.run("test", "-race", "-pkgdir="+pkgdir, "-i", "-v", "empty/pkg") - if tg.getStderr() != "" { - t.Error("go test -i -race: rebuilds cached packages") - } -} - -func TestBuildDryRunWithCgo(t *testing.T) { - if !canCgo { - t.Skip("skipping because cgo not enabled") - } - - tg := testgo(t) - defer tg.cleanup() - tg.tempFile("foo.go", `package main - -/* -#include -*/ -import "C" - -func main() { - println(C.INT_MAX) -}`) - tg.run("build", "-n", tg.path("foo.go")) - tg.grepStderrNot(`os.Stat .* no such file or directory`, "unexpected stat of archive file") -} - -func TestCgoDependsOnSyscall(t *testing.T) { - if testing.Short() { - t.Skip("skipping test that removes $GOROOT/pkg/*_race in short mode") - } - if !canCgo { - t.Skip("skipping because cgo not enabled") - } - if !canRace { - t.Skip("skipping because race detector not supported") - } - - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - - files, err := filepath.Glob(filepath.Join(runtime.GOROOT(), "pkg", "*_race")) - tg.must(err) - for _, file := range files { - tg.check(robustio.RemoveAll(file)) - } - tg.tempFile("src/foo/foo.go", ` - package foo - //#include - import "C"`) - tg.setenv("GOPATH", tg.path(".")) - tg.run("build", "-race", "foo") -} - -func TestCgoShowsFullPathNames(t *testing.T) { - if !canCgo { - t.Skip("skipping because cgo not enabled") - } - - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.tempFile("src/x/y/dirname/foo.go", ` - package foo - import "C" - func f() {`) - tg.setenv("GOPATH", tg.path(".")) - tg.runFail("build", "x/y/dirname") - tg.grepBoth("x/y/dirname", "error did not use full path") -} - -func TestCgoHandlesWlORIGIN(t *testing.T) { - tooSlow(t) - if !canCgo { - t.Skip("skipping because cgo not enabled") - } - - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.tempFile("src/origin/origin.go", `package origin - // #cgo !darwin LDFLAGS: -Wl,-rpath,$ORIGIN - // void f(void) {} - import "C" - func f() { C.f() }`) - tg.setenv("GOPATH", tg.path(".")) - tg.run("build", "origin") -} - -func TestCgoPkgConfig(t *testing.T) { - tooSlow(t) - if !canCgo { - t.Skip("skipping because cgo not enabled") - } - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - - tg.run("env", "PKG_CONFIG") - pkgConfig := strings.TrimSpace(tg.getStdout()) - testenv.MustHaveExecPath(t, pkgConfig) - if out, err := exec.Command(pkgConfig, "--atleast-pkgconfig-version", "0.24").CombinedOutput(); err != nil { - t.Skipf("%s --atleast-pkgconfig-version 0.24: %v\n%s", pkgConfig, err, out) + tg.run("env", "PKG_CONFIG") + pkgConfig := strings.TrimSpace(tg.getStdout()) + testenv.MustHaveExecPath(t, pkgConfig) + if out, err := exec.Command(pkgConfig, "--atleast-pkgconfig-version", "0.24").CombinedOutput(); err != nil { + t.Skipf("%s --atleast-pkgconfig-version 0.24: %v\n%s", pkgConfig, err, out) } // OpenBSD's pkg-config is strict about whitespace and only @@ -2338,381 +1544,62 @@ func TestCgoPkgConfig(t *testing.T) { Name: foo Description: The foo library Version: 1.0.0 -Cflags: -Dhello=10 -Dworld=+32 -DDEFINED_FROM_PKG_CONFIG=hello\ world -`) - tg.tempFile("foo.go", `package main - -/* -#cgo pkg-config: foo -int value() { - return DEFINED_FROM_PKG_CONFIG; -} -*/ -import "C" -import "os" - -func main() { - if C.value() != 42 { - println("value() =", C.value(), "wanted 42") - os.Exit(1) - } -} -`) - tg.setenv("PKG_CONFIG_PATH", tg.path(".")) - tg.run("run", tg.path("foo.go")) -} - -// "go test -c -test.bench=XXX errors" should not hang. -// "go test -c" should also produce reproducible binaries. -// "go test -c" should also appear to write a new binary every time, -// even if it's really just updating the mtime on an existing up-to-date binary. -func TestIssue6480(t *testing.T) { - skipIfGccgo(t, "gccgo has no standard packages") - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - // TODO: tg.parallel() - tg.makeTempdir() - tg.cd(tg.path(".")) - tg.run("test", "-c", "-test.bench=XXX", "errors") - tg.run("test", "-c", "-o", "errors2.test", "errors") - - data1, err := ioutil.ReadFile("errors.test" + exeSuffix) - tg.must(err) - data2, err := ioutil.ReadFile("errors2.test") // no exeSuffix because -o above doesn't have it - tg.must(err) - if !bytes.Equal(data1, data2) { - t.Fatalf("go test -c errors produced different binaries when run twice") - } - - start := time.Now() - tg.run("test", "-x", "-c", "-test.bench=XXX", "errors") - tg.grepStderrNot(`[\\/]link|gccgo`, "incorrectly relinked up-to-date test binary") - info, err := os.Stat("errors.test" + exeSuffix) - if err != nil { - t.Fatal(err) - } - start = truncateLike(start, info.ModTime()) - if info.ModTime().Before(start) { - t.Fatalf("mtime of errors.test predates test -c command (%v < %v)", info.ModTime(), start) - } - - start = time.Now() - tg.run("test", "-x", "-c", "-o", "errors2.test", "errors") - tg.grepStderrNot(`[\\/]link|gccgo`, "incorrectly relinked up-to-date test binary") - info, err = os.Stat("errors2.test") - if err != nil { - t.Fatal(err) - } - start = truncateLike(start, info.ModTime()) - if info.ModTime().Before(start) { - t.Fatalf("mtime of errors2.test predates test -c command (%v < %v)", info.ModTime(), start) - } -} - -// truncateLike returns the result of truncating t to the apparent precision of p. -func truncateLike(t, p time.Time) time.Time { - nano := p.UnixNano() - d := 1 * time.Nanosecond - for nano%int64(d) == 0 && d < 1*time.Second { - d *= 10 - } - for nano%int64(d) == 0 && d < 2*time.Second { - d *= 2 - } - return t.Truncate(d) -} - -// cmd/cgo: undefined reference when linking a C-library using gccgo -func TestIssue7573(t *testing.T) { - if !canCgo { - t.Skip("skipping because cgo not enabled") - } - testenv.MustHaveExecPath(t, "gccgo") - - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.tempFile("src/cgoref/cgoref.go", ` -package main -// #cgo LDFLAGS: -L alibpath -lalib -// void f(void) {} -import "C" - -func main() { C.f() }`) - tg.setenv("GOPATH", tg.path(".")) - tg.run("build", "-n", "-compiler", "gccgo", "cgoref") - tg.grepStderr(`gccgo.*\-L [^ ]*alibpath \-lalib`, `no Go-inline "#cgo LDFLAGS:" ("-L alibpath -lalib") passed to gccgo linking stage`) -} - -func TestListTemplateContextFunction(t *testing.T) { - t.Parallel() - for _, tt := range []struct { - v string - want string - }{ - {"GOARCH", runtime.GOARCH}, - {"GOOS", runtime.GOOS}, - {"GOROOT", filepath.Clean(runtime.GOROOT())}, - {"GOPATH", os.Getenv("GOPATH")}, - {"CgoEnabled", ""}, - {"UseAllFiles", ""}, - {"Compiler", ""}, - {"BuildTags", ""}, - {"ReleaseTags", ""}, - {"InstallSuffix", ""}, - } { - tt := tt - t.Run(tt.v, func(t *testing.T) { - tg := testgo(t) - tg.parallel() - defer tg.cleanup() - tmpl := "{{context." + tt.v + "}}" - tg.run("list", "-f", tmpl) - if tt.want == "" { - return - } - if got := strings.TrimSpace(tg.getStdout()); got != tt.want { - t.Errorf("go list -f %q: got %q; want %q", tmpl, got, tt.want) - } - }) - } -} - -func TestGoBuildTestOnly(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path(".")) - tg.tempFile("src/testonly/t_test.go", `package testonly`) - tg.tempFile("src/testonly2/t.go", `package testonly2`) - tg.cd(tg.path("src")) - - // Named explicitly, test-only packages should be reported as unbuildable/uninstallable, - // even if there is a wildcard also matching. - tg.runFail("build", "testonly", "testonly...") - tg.grepStderr("no non-test Go files in", "go build ./xtestonly produced unexpected error") - tg.runFail("install", "./testonly") - tg.grepStderr("no non-test Go files in", "go install ./testonly produced unexpected error") - - // Named through a wildcards, the test-only packages should be silently ignored. - tg.run("build", "testonly...") - tg.run("install", "./testonly...") -} - -func TestGoTestFooTestWorks(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.run("test", "testdata/standalone_test.go") -} - -func TestGoTestTestMainSeesTestingFlags(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.run("test", "testdata/standalone_testmain_flag_test.go") -} - -// Issue 22388 -func TestGoTestMainWithWrongSignature(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.runFail("test", "testdata/standalone_main_wrong_test.go") - tg.grepStderr(`wrong signature for TestMain, must be: func TestMain\(m \*testing.M\)`, "detected wrong error message") -} - -func TestGoTestMainAsNormalTest(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.run("test", "testdata/standalone_main_normal_test.go") - tg.grepBoth(okPattern, "go test did not say ok") -} - -func TestGoTestXtestonlyWorks(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.run("clean", "-i", "xtestonly") - tg.run("test", "xtestonly") -} - -func TestGoTestBuildsAnXtestContainingOnlyNonRunnableExamples(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.run("test", "-v", "./testdata/norunexample") - tg.grepStdout("File with non-runnable example was built.", "file with non-runnable example was not built") -} - -func TestGoGenerateHandlesSimpleCommand(t *testing.T) { - if runtime.GOOS == "windows" { - t.Skip("skipping because windows has no echo command") - } - - tg := testgo(t) - defer tg.cleanup() - tg.run("generate", "./testdata/generate/test1.go") - tg.grepStdout("Success", "go generate ./testdata/generate/test1.go generated wrong output") -} - -func TestGoGenerateHandlesCommandAlias(t *testing.T) { - if runtime.GOOS == "windows" { - t.Skip("skipping because windows has no echo command") - } - - tg := testgo(t) - defer tg.cleanup() - tg.run("generate", "./testdata/generate/test2.go") - tg.grepStdout("Now is the time for all good men", "go generate ./testdata/generate/test2.go generated wrong output") -} - -func TestGoGenerateVariableSubstitution(t *testing.T) { - if runtime.GOOS == "windows" { - t.Skip("skipping because windows has no echo command") - } - - tg := testgo(t) - defer tg.cleanup() - tg.run("generate", "./testdata/generate/test3.go") - tg.grepStdout(runtime.GOARCH+" test3.go:7 pabc xyzp/test3.go/123", "go generate ./testdata/generate/test3.go generated wrong output") -} - -func TestGoGenerateRunFlag(t *testing.T) { - if runtime.GOOS == "windows" { - t.Skip("skipping because windows has no echo command") - } - - tg := testgo(t) - defer tg.cleanup() - tg.run("generate", "-run", "y.s", "./testdata/generate/test4.go") - tg.grepStdout("yes", "go generate -run yes ./testdata/generate/test4.go did not select yes") - tg.grepStdoutNot("no", "go generate -run yes ./testdata/generate/test4.go selected no") -} - -func TestGoGenerateEnv(t *testing.T) { - switch runtime.GOOS { - case "plan9", "windows": - t.Skipf("skipping because %s does not have the env command", runtime.GOOS) - } - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.tempFile("env.go", "package main\n\n//go:generate env") - tg.run("generate", tg.path("env.go")) - for _, v := range []string{"GOARCH", "GOOS", "GOFILE", "GOLINE", "GOPACKAGE", "DOLLAR"} { - tg.grepStdout("^"+v+"=", "go generate environment missing "+v) - } -} - -func TestGoGenerateXTestPkgName(t *testing.T) { - if runtime.GOOS == "windows" { - t.Skip("skipping because windows has no echo command") - } - - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.tempFile("env_test.go", "package main_test\n\n//go:generate echo $GOPACKAGE") - tg.run("generate", tg.path("env_test.go")) - want := "main_test" - if got := strings.TrimSpace(tg.getStdout()); got != want { - t.Errorf("go generate in XTest file got package name %q; want %q", got, want) - } -} - -func TestGoGetCustomDomainWildcard(t *testing.T) { - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") - - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path(".")) - tg.run("get", "-u", "rsc.io/pdf/...") - tg.wantExecutable(tg.path("bin/pdfpasswd"+exeSuffix), "did not build rsc/io/pdf/pdfpasswd") -} - -func TestGoGetInternalWildcard(t *testing.T) { - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") - - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path(".")) - // used to fail with errors about internal packages - tg.run("get", "github.com/rsc/go-get-issue-11960/...") -} - -func TestGoVetWithExternalTests(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.runFail("vet", "vetpkg") - tg.grepBoth("Printf", "go vet vetpkg did not find missing argument for Printf") -} - -func TestGoVetWithTags(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.runFail("vet", "-tags", "tagtest", "vetpkg") - tg.grepBoth(`c\.go.*Printf`, "go vet vetpkg did not run scan tagged file") -} - -func TestGoVetWithFlagsOn(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.runFail("vet", "-printf", "vetpkg") - tg.grepBoth("Printf", "go vet -printf vetpkg did not find missing argument for Printf") -} - -func TestGoVetWithFlagsOff(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.run("vet", "-printf=false", "vetpkg") -} +Cflags: -Dhello=10 -Dworld=+32 -DDEFINED_FROM_PKG_CONFIG=hello\ world +`) + tg.tempFile("foo.go", `package main -// Issue 23395. -func TestGoVetWithOnlyTestFiles(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.tempFile("src/p/p_test.go", "package p; import \"testing\"; func TestMe(*testing.T) {}") - tg.setenv("GOPATH", tg.path(".")) - tg.run("vet", "p") +/* +#cgo pkg-config: foo +int value() { + return DEFINED_FROM_PKG_CONFIG; } +*/ +import "C" +import "os" -// Issue 24193. -func TestVetWithOnlyCgoFiles(t *testing.T) { - if !canCgo { - t.Skip("skipping because cgo not enabled") +func main() { + if C.value() != 42 { + println("value() =", C.value(), "wanted 42") + os.Exit(1) } - tooSlow(t) - - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.tempFile("src/p/p.go", "package p; import \"C\"; func F() {}") - tg.setenv("GOPATH", tg.path(".")) - tg.run("vet", "p") +} +`) + tg.setenv("PKG_CONFIG_PATH", tg.path(".")) + tg.run("run", tg.path("foo.go")) } -// Issue 9767, 19769. -func TestGoGetDotSlashDownload(t *testing.T) { - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") - - tg := testgo(t) - defer tg.cleanup() - tg.tempDir("src/rsc.io") - tg.setenv("GOPATH", tg.path(".")) - tg.cd(tg.path("src/rsc.io")) - tg.run("get", "./pprof_mac_fix") +func TestListTemplateContextFunction(t *testing.T) { + t.Parallel() + for _, tt := range []struct { + v string + want string + }{ + {"GOARCH", runtime.GOARCH}, + {"GOOS", runtime.GOOS}, + {"GOROOT", filepath.Clean(runtime.GOROOT())}, + {"GOPATH", os.Getenv("GOPATH")}, + {"CgoEnabled", ""}, + {"UseAllFiles", ""}, + {"Compiler", ""}, + {"BuildTags", ""}, + {"ReleaseTags", ""}, + {"InstallSuffix", ""}, + } { + tt := tt + t.Run(tt.v, func(t *testing.T) { + tg := testgo(t) + tg.parallel() + defer tg.cleanup() + tmpl := "{{context." + tt.v + "}}" + tg.run("list", "-f", tmpl) + if tt.want == "" { + return + } + if got := strings.TrimSpace(tg.getStdout()); got != tt.want { + t.Errorf("go list -f %q: got %q; want %q", tmpl, got, tt.want) + } + }) + } } // Test that you cannot use a local import in a package @@ -2827,477 +1714,63 @@ func TestImportLocal(t *testing.T) { tg.tempFile("src/dir/x/y/y_test.go", `package y_test import ".." import "testing" - var _ = x.X - func TestFoo(t *testing.T) {} - `) - tg.run("build", "dir/x/y") - tg.runFail("test", "dir/x/y") - tg.grepStderr("local import.*in non-local package", "did not diagnose local import") - - // Relative import "." should not work. - tg.tempFile("src/dir/x/xx.go", `package x - import "." - var _ = x.X - `) - tg.runFail("build", "dir/x") - tg.grepStderr("cannot import current directory", "did not diagnose import current directory") - - // ... even in a test. - tg.tempFile("src/dir/x/xx.go", `package x - `) - tg.tempFile("src/dir/x/xx_test.go", `package x - import "." - import "testing" - var _ = x.X - func TestFoo(t *testing.T) {} - `) - tg.run("build", "dir/x") - tg.runFail("test", "dir/x") - tg.grepStderr("cannot import current directory", "did not diagnose import current directory") - - // ... even in an xtest. - tg.tempFile("src/dir/x/xx.go", `package x - `) - tg.tempFile("src/dir/x/xx_test.go", `package x_test - import "." - import "testing" - var _ = x.X - func TestFoo(t *testing.T) {} - `) - tg.run("build", "dir/x") - tg.runFail("test", "dir/x") - tg.grepStderr("cannot import current directory", "did not diagnose import current directory") -} - -func TestGoGetInsecure(t *testing.T) { - test := func(t *testing.T, modules bool) { - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") - - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.failSSH() - - if modules { - tg.setenv("GOPATH", tg.path("gp")) - tg.tempFile("go.mod", "module m") - tg.cd(tg.path(".")) - tg.setenv("GO111MODULE", "on") - tg.setenv("GOPROXY", "") - } else { - tg.setenv("GOPATH", tg.path(".")) - tg.setenv("GO111MODULE", "off") - } - - const repo = "insecure.go-get-issue-15410.appspot.com/pkg/p" - - // Try go get -d of HTTP-only repo (should fail). - tg.runFail("get", "-d", repo) - - // Try again with -insecure (should succeed). - tg.run("get", "-d", "-insecure", repo) - - // Try updating without -insecure (should fail). - tg.runFail("get", "-d", "-u", "-f", repo) - - if modules { - tg.run("list", "-m", "...") - tg.grepStdout("insecure.go-get-issue", "should find insecure module") - } - } - - t.Run("gopath", func(t *testing.T) { test(t, false) }) - t.Run("modules", func(t *testing.T) { test(t, true) }) -} - -func TestGoGetUpdateInsecure(t *testing.T) { - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") - - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path(".")) - - const repo = "github.com/golang/example" - - // Clone the repo via HTTP manually. - cmd := exec.Command("git", "clone", "-q", "http://"+repo, tg.path("src/"+repo)) - if out, err := cmd.CombinedOutput(); err != nil { - t.Fatalf("cloning %v repo: %v\n%s", repo, err, out) - } - - // Update without -insecure should fail. - // Update with -insecure should succeed. - // We need -f to ignore import comments. - const pkg = repo + "/hello" - tg.runFail("get", "-d", "-u", "-f", pkg) - tg.run("get", "-d", "-u", "-f", "-insecure", pkg) -} - -func TestGoGetUpdateUnknownProtocol(t *testing.T) { - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") - - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path(".")) - - const repo = "github.com/golang/example" - - // Clone the repo via HTTPS manually. - repoDir := tg.path("src/" + repo) - cmd := exec.Command("git", "clone", "-q", "https://"+repo, repoDir) - if out, err := cmd.CombinedOutput(); err != nil { - t.Fatalf("cloning %v repo: %v\n%s", repo, err, out) - } - - // Configure the repo to use a protocol unknown to cmd/go - // that still actually works. - cmd = exec.Command("git", "remote", "set-url", "origin", "xyz://"+repo) - cmd.Dir = repoDir - if out, err := cmd.CombinedOutput(); err != nil { - t.Fatalf("git remote set-url: %v\n%s", err, out) - } - cmd = exec.Command("git", "config", "--local", "url.https://github.com/.insteadOf", "xyz://github.com/") - cmd.Dir = repoDir - if out, err := cmd.CombinedOutput(); err != nil { - t.Fatalf("git config: %v\n%s", err, out) - } - - // We need -f to ignore import comments. - tg.run("get", "-d", "-u", "-f", repo+"/hello") -} - -func TestGoGetInsecureCustomDomain(t *testing.T) { - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") - - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path(".")) - - const repo = "insecure.go-get-issue-15410.appspot.com/pkg/p" - tg.runFail("get", "-d", repo) - tg.run("get", "-d", "-insecure", repo) -} - -func TestGoRunDirs(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.cd("testdata/rundir") - tg.runFail("run", "x.go", "sub/sub.go") - tg.grepStderr("named files must all be in one directory; have ./ and sub/", "wrong output") - tg.runFail("run", "sub/sub.go", "x.go") - tg.grepStderr("named files must all be in one directory; have sub/ and ./", "wrong output") -} - -func TestGoInstallPkgdir(t *testing.T) { - skipIfGccgo(t, "gccgo has no standard packages") - tooSlow(t) - - tg := testgo(t) - tg.parallel() - defer tg.cleanup() - tg.makeTempdir() - pkg := tg.path(".") - tg.run("install", "-pkgdir", pkg, "sync") - tg.mustExist(filepath.Join(pkg, "sync.a")) - tg.mustNotExist(filepath.Join(pkg, "sync/atomic.a")) - tg.run("install", "-i", "-pkgdir", pkg, "sync") - tg.mustExist(filepath.Join(pkg, "sync.a")) - tg.mustExist(filepath.Join(pkg, "sync/atomic.a")) -} - -func TestGoTestRaceInstallCgo(t *testing.T) { - if !canRace { - t.Skip("skipping because race detector not supported") - } - - // golang.org/issue/10500. - // This used to install a race-enabled cgo. - tg := testgo(t) - defer tg.cleanup() - tg.run("tool", "-n", "cgo") - cgo := strings.TrimSpace(tg.stdout.String()) - old, err := os.Stat(cgo) - tg.must(err) - - // For this test, we don't actually care whether 'go test -race -i' succeeds. - // It may fail, for example, if GOROOT was installed from source as root and - // is now read-only. - // We only care that — regardless of whether it succeeds — it does not - // overwrite cmd/cgo. - runArgs := []string{"test", "-race", "-i", "runtime/race"} - if status := tg.doRun(runArgs); status != nil { - tg.t.Logf("go %v failure ignored: %v", runArgs, status) - } - - new, err := os.Stat(cgo) - tg.must(err) - if !new.ModTime().Equal(old.ModTime()) { - t.Fatalf("go test -i runtime/race reinstalled cmd/cgo") - } -} - -func TestGoGetUpdate(t *testing.T) { - // golang.org/issue/9224. - // The recursive updating was trying to walk to - // former dependencies, not current ones. - - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") - - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path(".")) - - rewind := func() { - tg.run("get", "github.com/rsc/go-get-issue-9224-cmd") - cmd := exec.Command("git", "reset", "--hard", "HEAD~") - cmd.Dir = tg.path("src/github.com/rsc/go-get-issue-9224-lib") - out, err := cmd.CombinedOutput() - if err != nil { - t.Fatalf("git: %v\n%s", err, out) - } - } - - rewind() - tg.run("get", "-u", "github.com/rsc/go-get-issue-9224-cmd") - - // Again with -d -u. - rewind() - tg.run("get", "-d", "-u", "github.com/rsc/go-get-issue-9224-cmd") -} - -// Issue #20512. -func TestGoGetRace(t *testing.T) { - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") - if !canRace { - t.Skip("skipping because race detector not supported") - } - - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path(".")) - tg.run("get", "-race", "github.com/rsc/go-get-issue-9224-cmd") -} - -func TestGoGetDomainRoot(t *testing.T) { - // golang.org/issue/9357. - // go get foo.io (not foo.io/subdir) was not working consistently. - - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") - - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path(".")) - - // go-get-issue-9357.appspot.com is running - // the code at github.com/rsc/go-get-issue-9357, - // a trivial Go on App Engine app that serves a - // tag for the domain root. - tg.run("get", "-d", "go-get-issue-9357.appspot.com") - tg.run("get", "go-get-issue-9357.appspot.com") - tg.run("get", "-u", "go-get-issue-9357.appspot.com") - - tg.must(robustio.RemoveAll(tg.path("src/go-get-issue-9357.appspot.com"))) - tg.run("get", "go-get-issue-9357.appspot.com") - - tg.must(robustio.RemoveAll(tg.path("src/go-get-issue-9357.appspot.com"))) - tg.run("get", "-u", "go-get-issue-9357.appspot.com") -} - -func TestGoInstallShadowedGOPATH(t *testing.T) { - // golang.org/issue/3652. - // go get foo.io (not foo.io/subdir) was not working consistently. - - testenv.MustHaveExternalNetwork(t) - - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path("gopath1")+string(filepath.ListSeparator)+tg.path("gopath2")) - - tg.tempDir("gopath1/src/test") - tg.tempDir("gopath2/src/test") - tg.tempFile("gopath2/src/test/main.go", "package main\nfunc main(){}\n") - - tg.cd(tg.path("gopath2/src/test")) - tg.runFail("install") - tg.grepStderr("no install location for.*gopath2.src.test: hidden by .*gopath1.src.test", "missing error") -} - -func TestGoBuildGOPATHOrder(t *testing.T) { - // golang.org/issue/14176#issuecomment-179895769 - // golang.org/issue/14192 - // -I arguments to compiler could end up not in GOPATH order, - // leading to unexpected import resolution in the compiler. - // This is still not a complete fix (see golang.org/issue/14271 and next test) - // but it is clearly OK and enough to fix both of the two reported - // instances of the underlying problem. It will have to do for now. - - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path("p1")+string(filepath.ListSeparator)+tg.path("p2")) - - tg.tempFile("p1/src/foo/foo.go", "package foo\n") - tg.tempFile("p2/src/baz/baz.go", "package baz\n") - tg.tempFile("p2/pkg/"+runtime.GOOS+"_"+runtime.GOARCH+"/foo.a", "bad\n") - tg.tempFile("p1/src/bar/bar.go", ` - package bar - import _ "baz" - import _ "foo" - `) - - tg.run("install", "-x", "bar") -} - -func TestGoBuildGOPATHOrderBroken(t *testing.T) { - // This test is known not to work. - // See golang.org/issue/14271. - t.Skip("golang.org/issue/14271") - - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - - tg.tempFile("p1/src/foo/foo.go", "package foo\n") - tg.tempFile("p2/src/baz/baz.go", "package baz\n") - tg.tempFile("p1/pkg/"+runtime.GOOS+"_"+runtime.GOARCH+"/baz.a", "bad\n") - tg.tempFile("p2/pkg/"+runtime.GOOS+"_"+runtime.GOARCH+"/foo.a", "bad\n") - tg.tempFile("p1/src/bar/bar.go", ` - package bar - import _ "baz" - import _ "foo" + var _ = x.X + func TestFoo(t *testing.T) {} `) + tg.run("build", "dir/x/y") + tg.runFail("test", "dir/x/y") + tg.grepStderr("local import.*in non-local package", "did not diagnose local import") - colon := string(filepath.ListSeparator) - tg.setenv("GOPATH", tg.path("p1")+colon+tg.path("p2")) - tg.run("install", "-x", "bar") - - tg.setenv("GOPATH", tg.path("p2")+colon+tg.path("p1")) - tg.run("install", "-x", "bar") -} + // Relative import "." should not work. + tg.tempFile("src/dir/x/xx.go", `package x + import "." + var _ = x.X + `) + tg.runFail("build", "dir/x") + tg.grepStderr("cannot import current directory", "did not diagnose import current directory") -func TestIssue11709(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.tempFile("run.go", ` - package main - import "os" - func main() { - if os.Getenv("TERM") != "" { - os.Exit(1) - } - }`) - tg.unsetenv("TERM") - tg.run("run", tg.path("run.go")) -} + // ... even in a test. + tg.tempFile("src/dir/x/xx.go", `package x + `) + tg.tempFile("src/dir/x/xx_test.go", `package x + import "." + import "testing" + var _ = x.X + func TestFoo(t *testing.T) {} + `) + tg.run("build", "dir/x") + tg.runFail("test", "dir/x") + tg.grepStderr("cannot import current directory", "did not diagnose import current directory") -func TestIssue12096(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.tempFile("test_test.go", ` - package main - import ("os"; "testing") - func TestEnv(t *testing.T) { - if os.Getenv("TERM") != "" { - t.Fatal("TERM is set") - } - }`) - tg.unsetenv("TERM") - tg.run("test", tg.path("test_test.go")) + // ... even in an xtest. + tg.tempFile("src/dir/x/xx.go", `package x + `) + tg.tempFile("src/dir/x/xx_test.go", `package x_test + import "." + import "testing" + var _ = x.X + func TestFoo(t *testing.T) {} + `) + tg.run("build", "dir/x") + tg.runFail("test", "dir/x") + tg.grepStderr("cannot import current directory", "did not diagnose import current directory") } -func TestGoBuildOutput(t *testing.T) { +func TestGoInstallPkgdir(t *testing.T) { skipIfGccgo(t, "gccgo has no standard packages") tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - - tg.makeTempdir() - tg.cd(tg.path(".")) - - nonExeSuffix := ".exe" - if exeSuffix == ".exe" { - nonExeSuffix = "" - } - - tg.tempFile("x.go", "package main\nfunc main(){}\n") - tg.run("build", "x.go") - tg.wantExecutable("x"+exeSuffix, "go build x.go did not write x"+exeSuffix) - tg.must(os.Remove(tg.path("x" + exeSuffix))) - tg.mustNotExist("x" + nonExeSuffix) - - tg.run("build", "-o", "myprog", "x.go") - tg.mustNotExist("x") - tg.mustNotExist("x.exe") - tg.wantExecutable("myprog", "go build -o myprog x.go did not write myprog") - tg.mustNotExist("myprog.exe") - - tg.tempFile("p.go", "package p\n") - tg.run("build", "p.go") - tg.mustNotExist("p") - tg.mustNotExist("p.a") - tg.mustNotExist("p.o") - tg.mustNotExist("p.exe") - - tg.run("build", "-o", "p.a", "p.go") - tg.wantArchive("p.a") - - tg.run("build", "cmd/gofmt") - tg.wantExecutable("gofmt"+exeSuffix, "go build cmd/gofmt did not write gofmt"+exeSuffix) - tg.must(os.Remove(tg.path("gofmt" + exeSuffix))) - tg.mustNotExist("gofmt" + nonExeSuffix) - - tg.run("build", "-o", "mygofmt", "cmd/gofmt") - tg.wantExecutable("mygofmt", "go build -o mygofmt cmd/gofmt did not write mygofmt") - tg.mustNotExist("mygofmt.exe") - tg.mustNotExist("gofmt") - tg.mustNotExist("gofmt.exe") - - tg.run("build", "sync/atomic") - tg.mustNotExist("atomic") - tg.mustNotExist("atomic.exe") - - tg.run("build", "-o", "myatomic.a", "sync/atomic") - tg.wantArchive("myatomic.a") - tg.mustNotExist("atomic") - tg.mustNotExist("atomic.a") - tg.mustNotExist("atomic.exe") - - tg.runFail("build", "-o", "whatever", "cmd/gofmt", "sync/atomic") - tg.grepStderr("multiple packages", "did not reject -o with multiple packages") -} - -func TestGoBuildARM(t *testing.T) { - if testing.Short() { - t.Skip("skipping cross-compile in short mode") - } tg := testgo(t) + tg.parallel() defer tg.cleanup() - tg.makeTempdir() - tg.cd(tg.path(".")) - - tg.setenv("GOARCH", "arm") - tg.setenv("GOOS", "linux") - tg.setenv("GOARM", "5") - tg.tempFile("hello.go", `package main - func main() {}`) - tg.run("build", "hello.go") - tg.grepStderrNot("unable to find math.a", "did not build math.a correctly") + pkg := tg.path(".") + tg.run("install", "-pkgdir", pkg, "sync") + tg.mustExist(filepath.Join(pkg, "sync.a")) + tg.mustNotExist(filepath.Join(pkg, "sync/atomic.a")) + tg.run("install", "-i", "-pkgdir", pkg, "sync") + tg.mustExist(filepath.Join(pkg, "sync.a")) + tg.mustExist(filepath.Join(pkg, "sync/atomic.a")) } // For issue 14337. @@ -3321,50 +1794,6 @@ func TestParallelTest(t *testing.T) { tg.run("test", "-p=4", "p1", "p2", "p3", "p4") } -func TestCgoConsistentResults(t *testing.T) { - tooSlow(t) - if !canCgo { - t.Skip("skipping because cgo not enabled") - } - switch runtime.GOOS { - case "solaris", "illumos": - testenv.SkipFlaky(t, 13247) - } - - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.makeTempdir() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - exe1 := tg.path("cgotest1" + exeSuffix) - exe2 := tg.path("cgotest2" + exeSuffix) - tg.run("build", "-o", exe1, "cgotest") - tg.run("build", "-x", "-o", exe2, "cgotest") - b1, err := ioutil.ReadFile(exe1) - tg.must(err) - b2, err := ioutil.ReadFile(exe2) - tg.must(err) - - if !tg.doGrepMatch(`-fdebug-prefix-map=\$WORK`, &tg.stderr) { - t.Skip("skipping because C compiler does not support -fdebug-prefix-map") - } - if !bytes.Equal(b1, b2) { - t.Error("building cgotest twice did not produce the same output") - } -} - -// Issue 14444: go get -u .../ duplicate loads errors -func TestGoGetUpdateAllDoesNotTryToLoadDuplicates(t *testing.T) { - testenv.MustHaveExternalNetwork(t) - - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path(".")) - tg.run("get", "-u", ".../") - tg.grepStderrNot("duplicate loads of", "did not remove old packages from cache") -} - func TestBinaryOnlyPackages(t *testing.T) { tooSlow(t) @@ -3456,39 +1885,9 @@ func TestGenerateUsesBuildContext(t *testing.T) { tg.grepStdout("linux amd64", "unexpected GOOS/GOARCH combination") tg.setenv("GOOS", "darwin") - tg.setenv("GOARCH", "386") + tg.setenv("GOARCH", "arm64") tg.run("generate", "gen") - tg.grepStdout("darwin 386", "unexpected GOOS/GOARCH combination") -} - -// Issue 14450: go get -u .../ tried to import not downloaded package -func TestGoGetUpdateWithWildcard(t *testing.T) { - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") - - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path(".")) - const aPkgImportPath = "github.com/tmwh/go-get-issue-14450/a" - tg.run("get", aPkgImportPath) - tg.runFail("get", "-u", ".../") - tg.grepStderr("cannot find package.*d-dependency/e", "should have detected e missing") - - // Even though get -u failed, the source for others should be downloaded. - var expectedPkgPaths = []string{ - "src/github.com/tmwh/go-get-issue-14450/b", - "src/github.com/tmwh/go-get-issue-14450-b-dependency/c", - "src/github.com/tmwh/go-get-issue-14450-b-dependency/d", - } - - for _, importPath := range expectedPkgPaths { - _, err := os.Stat(tg.path(importPath)) - tg.must(err) - } - const notExpectedPkgPath = "src/github.com/tmwh/go-get-issue-14450-c-dependency/e" - tg.mustNotExist(tg.path(notExpectedPkgPath)) + tg.grepStdout("darwin arm64", "unexpected GOOS/GOARCH combination") } func TestGoEnv(t *testing.T) { @@ -3522,153 +1921,6 @@ const ( okPattern = `(?m)^ok` ) -func TestMatchesNoTests(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - // TODO: tg.parallel() - tg.run("test", "-run", "ThisWillNotMatch", "testdata/standalone_test.go") - tg.grepBoth(noMatchesPattern, "go test did not say [no tests to run]") -} - -func TestMatchesNoBenchmarksIsOK(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - // TODO: tg.parallel() - tg.run("test", "-run", "^$", "-bench", "ThisWillNotMatch", "testdata/standalone_benchmark_test.go") - tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]") - tg.grepBoth(okPattern, "go test did not say ok") -} - -func TestMatchesOnlyExampleIsOK(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - // TODO: tg.parallel() - tg.run("test", "-run", "Example", "testdata/example1_test.go") - tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]") - tg.grepBoth(okPattern, "go test did not say ok") -} - -func TestMatchesOnlyBenchmarkIsOK(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - // TODO: tg.parallel() - tg.run("test", "-run", "^$", "-bench", ".", "testdata/standalone_benchmark_test.go") - tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]") - tg.grepBoth(okPattern, "go test did not say ok") -} - -func TestBenchmarkLabelsOutsideGOPATH(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - // TODO: tg.parallel() - tg.run("test", "-run", "^$", "-bench", ".", "testdata/standalone_benchmark_test.go") - tg.grepStdout(`(?m)^goos: `+runtime.GOOS, "go test did not print goos") - tg.grepStdout(`(?m)^goarch: `+runtime.GOARCH, "go test did not print goarch") - tg.grepBothNot(`(?m)^pkg:`, "go test did say pkg:") -} - -func TestMatchesOnlyTestIsOK(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - // TODO: tg.parallel() - tg.run("test", "-run", "Test", "testdata/standalone_test.go") - tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]") - tg.grepBoth(okPattern, "go test did not say ok") -} - -func TestMatchesNoTestsWithSubtests(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.run("test", "-run", "ThisWillNotMatch", "testdata/standalone_sub_test.go") - tg.grepBoth(noMatchesPattern, "go test did not say [no tests to run]") -} - -func TestMatchesNoSubtestsMatch(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.run("test", "-run", "Test/ThisWillNotMatch", "testdata/standalone_sub_test.go") - tg.grepBoth(noMatchesPattern, "go test did not say [no tests to run]") -} - -func TestMatchesNoSubtestsDoesNotOverrideFailure(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.runFail("test", "-run", "TestThatFails/ThisWillNotMatch", "testdata/standalone_fail_sub_test.go") - tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]") - tg.grepBoth("FAIL", "go test did not say FAIL") -} - -func TestMatchesOnlySubtestIsOK(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.run("test", "-run", "Test/Sub", "testdata/standalone_sub_test.go") - tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]") - tg.grepBoth(okPattern, "go test did not say ok") -} - -func TestMatchesNoSubtestsParallel(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.run("test", "-run", "Test/Sub/ThisWillNotMatch", "testdata/standalone_parallel_sub_test.go") - tg.grepBoth(noMatchesPattern, "go test did not say [no tests to run]") -} - -func TestMatchesOnlySubtestParallelIsOK(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.run("test", "-run", "Test/Sub/Nested", "testdata/standalone_parallel_sub_test.go") - tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]") - tg.grepBoth(okPattern, "go test did not say ok") -} - -// Issue 18845 -func TestBenchTimeout(t *testing.T) { - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - tg.run("test", "-bench", ".", "-timeout", "750ms", "testdata/timeoutbench_test.go") -} - -// Issue 19394 -func TestWriteProfilesOnTimeout(t *testing.T) { - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - tg.tempDir("profiling") - tg.tempFile("profiling/timeouttest_test.go", `package timeouttest_test -import "testing" -import "time" -func TestSleep(t *testing.T) { time.Sleep(time.Second) }`) - tg.cd(tg.path("profiling")) - tg.runFail( - "test", - "-cpuprofile", tg.path("profiling/cpu.pprof"), "-memprofile", tg.path("profiling/mem.pprof"), - "-timeout", "1ms") - tg.mustHaveContent(tg.path("profiling/cpu.pprof")) - tg.mustHaveContent(tg.path("profiling/mem.pprof")) -} - -func TestLinkXImportPathEscape(t *testing.T) { - // golang.org/issue/16710 - skipIfGccgo(t, "gccgo does not support -ldflags -X") - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.makeTempdir() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - exe := tg.path("linkx" + exeSuffix) - tg.creatingTemp(exe) - tg.run("build", "-o", exe, "-ldflags", "-X=my.pkg.Text=linkXworked", "my.pkg/main") - out, err := exec.Command(exe).CombinedOutput() - if err != nil { - tg.t.Fatal(err) - } - if string(out) != "linkXworked\n" { - tg.t.Log(string(out)) - tg.t.Fatal(`incorrect output: expected "linkXworked\n"`) - } -} - // Issue 18044. func TestLdBindNow(t *testing.T) { tg := testgo(t) @@ -3695,29 +1947,6 @@ GLOBL ·constants<>(SB),8,$8 tg.run("build", "p") } -// Issue 18778. -func TestDotDotDotOutsideGOPATH(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - - tg.tempFile("pkgs/a.go", `package x`) - tg.tempFile("pkgs/a_test.go", `package x_test -import "testing" -func TestX(t *testing.T) {}`) - - tg.tempFile("pkgs/a/a.go", `package a`) - tg.tempFile("pkgs/a/a_test.go", `package a_test -import "testing" -func TestA(t *testing.T) {}`) - - tg.cd(tg.path("pkgs")) - tg.run("build", "./...") - tg.run("test", "./...") - tg.run("list", "./...") - tg.grepStdout("pkgs$", "expected package not listed") - tg.grepStdout("pkgs/a", "expected package not listed") -} - // Issue 18975. func TestFFLAGS(t *testing.T) { if !canCgo { @@ -3790,135 +2019,24 @@ func main() { tg.run("build", "-o", exe, "p") } -func TestBuildTagsNoComma(t *testing.T) { - skipIfGccgo(t, "gccgo has no standard packages") - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path("go")) - tg.run("build", "-tags", "tag1 tag2", "math") - tg.runFail("build", "-tags", "tag1,tag2 tag3", "math") - tg.grepBoth("space-separated list contains comma", "-tags with a comma-separated list didn't error") -} - func copyFile(src, dst string, perm os.FileMode) error { sf, err := os.Open(src) if err != nil { return err - } - defer sf.Close() - - df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) - if err != nil { - return err - } - - _, err = io.Copy(df, sf) - err2 := df.Close() - if err != nil { - return err - } - return err2 -} - -// TestExecutableGOROOT verifies that the cmd/go binary itself uses -// os.Executable (when available) to locate GOROOT. -func TestExecutableGOROOT(t *testing.T) { - skipIfGccgo(t, "gccgo has no GOROOT") - - // Note: Must not call tg methods inside subtests: tg is attached to outer t. - tg := testgo(t) - tg.unsetenv("GOROOT") - defer tg.cleanup() - - check := func(t *testing.T, exe, want string) { - cmd := exec.Command(exe, "env", "GOROOT") - cmd.Env = tg.env - out, err := cmd.CombinedOutput() - if err != nil { - t.Fatalf("%s env GOROOT: %v, %s", exe, err, out) - } - goroot, err := filepath.EvalSymlinks(strings.TrimSpace(string(out))) - if err != nil { - t.Fatal(err) - } - want, err = filepath.EvalSymlinks(want) - if err != nil { - t.Fatal(err) - } - if !strings.EqualFold(goroot, want) { - t.Errorf("go env GOROOT:\nhave %s\nwant %s", goroot, want) - } else { - t.Logf("go env GOROOT: %s", goroot) - } - } - - tg.makeTempdir() - tg.tempDir("new/bin") - newGoTool := tg.path("new/bin/go" + exeSuffix) - tg.must(copyFile(tg.goTool(), newGoTool, 0775)) - newRoot := tg.path("new") - - t.Run("RelocatedExe", func(t *testing.T) { - // Should fall back to default location in binary, - // which is the GOROOT we used when building testgo.exe. - check(t, newGoTool, testGOROOT) - }) - - // If the binary is sitting in a bin dir next to ../pkg/tool, that counts as a GOROOT, - // so it should find the new tree. - tg.tempDir("new/pkg/tool") - t.Run("RelocatedTree", func(t *testing.T) { - check(t, newGoTool, newRoot) - }) - - tg.tempDir("other/bin") - symGoTool := tg.path("other/bin/go" + exeSuffix) - - // Symlink into go tree should still find go tree. - t.Run("SymlinkedExe", func(t *testing.T) { - testenv.MustHaveSymlink(t) - if err := os.Symlink(newGoTool, symGoTool); err != nil { - t.Fatal(err) - } - check(t, symGoTool, newRoot) - }) - - tg.must(robustio.RemoveAll(tg.path("new/pkg"))) - - // Binaries built in the new tree should report the - // new tree when they call runtime.GOROOT. - t.Run("RuntimeGoroot", func(t *testing.T) { - // Build a working GOROOT the easy way, with symlinks. - testenv.MustHaveSymlink(t) - if err := os.Symlink(filepath.Join(testGOROOT, "src"), tg.path("new/src")); err != nil { - t.Fatal(err) - } - if err := os.Symlink(filepath.Join(testGOROOT, "pkg"), tg.path("new/pkg")); err != nil { - t.Fatal(err) - } - - cmd := exec.Command(newGoTool, "run", "testdata/print_goroot.go") - cmd.Env = tg.env - cmd.Stderr = os.Stderr - out, err := cmd.Output() - if err != nil { - t.Fatalf("%s run testdata/print_goroot.go: %v, %s", newGoTool, err, out) - } - goroot, err := filepath.EvalSymlinks(strings.TrimSpace(string(out))) - if err != nil { - t.Fatal(err) - } - want, err := filepath.EvalSymlinks(tg.path("new")) - if err != nil { - t.Fatal(err) - } - if !strings.EqualFold(goroot, want) { - t.Errorf("go run testdata/print_goroot.go:\nhave %s\nwant %s", goroot, want) - } else { - t.Logf("go run testdata/print_goroot.go: %s", goroot) - } - }) + } + defer sf.Close() + + df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) + if err != nil { + return err + } + + _, err = io.Copy(df, sf) + err2 := df.Close() + if err != nil { + return err + } + return err2 } func TestNeedVersion(t *testing.T) { @@ -3933,47 +2051,6 @@ func TestNeedVersion(t *testing.T) { tg.grepStderr("compile", "does not match go tool version") } -func TestCgoFlagContainsSpace(t *testing.T) { - tooSlow(t) - if !canCgo { - t.Skip("skipping because cgo not enabled") - } - tg := testgo(t) - defer tg.cleanup() - - tg.makeTempdir() - tg.cd(tg.path(".")) - tg.tempFile("main.go", `package main - // #cgo CFLAGS: -I"c flags" - // #cgo LDFLAGS: -L"ld flags" - import "C" - func main() {} - `) - tg.run("run", "-x", "main.go") - tg.grepStderr(`"-I[^"]+c flags"`, "did not find quoted c flags") - tg.grepStderrNot(`"-I[^"]+c flags".*"-I[^"]+c flags"`, "found too many quoted c flags") - tg.grepStderr(`"-L[^"]+ld flags"`, "did not find quoted ld flags") - tg.grepStderrNot(`"-L[^"]+c flags".*"-L[^"]+c flags"`, "found too many quoted ld flags") -} - -func TestListTests(t *testing.T) { - tooSlow(t) - var tg *testgoData - testWith := func(listName, expected string) func(*testing.T) { - return func(t *testing.T) { - tg = testgo(t) - defer tg.cleanup() - tg.run("test", "./testdata/src/testlist/...", fmt.Sprintf("-list=%s", listName)) - tg.grepStdout(expected, fmt.Sprintf("-test.list=%s returned %q, expected %s", listName, tg.getStdout(), expected)) - } - } - - t.Run("Test", testWith("Test", "TestSimple")) - t.Run("Bench", testWith("Benchmark", "BenchmarkSimple")) - t.Run("Example1", testWith("Example", "ExampleSimple")) - t.Run("Example2", testWith("Example", "ExampleWithEmptyOutput")) -} - func TestBuildmodePIE(t *testing.T) { if testing.Short() && testenv.Builder() == "" { t.Skipf("skipping in -short mode on non-builder") @@ -3983,20 +2060,62 @@ func TestBuildmodePIE(t *testing.T) { switch platform { case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x", "android/amd64", "android/arm", "android/arm64", "android/386", - "freebsd/amd64": + "freebsd/amd64", + "windows/386", "windows/amd64", "windows/arm": case "darwin/amd64": default: t.Skipf("skipping test because buildmode=pie is not supported on %s", platform) } + t.Run("non-cgo", func(t *testing.T) { + testBuildmodePIE(t, false, true) + }) + if canCgo { + switch runtime.GOOS { + case "darwin", "freebsd", "linux", "windows": + t.Run("cgo", func(t *testing.T) { + testBuildmodePIE(t, true, true) + }) + } + } +} + +func TestWindowsDefaultBuildmodIsPIE(t *testing.T) { + if testing.Short() && testenv.Builder() == "" { + t.Skipf("skipping in -short mode on non-builder") + } + + if runtime.GOOS != "windows" { + t.Skip("skipping windows only test") + } + + t.Run("non-cgo", func(t *testing.T) { + testBuildmodePIE(t, false, false) + }) + if canCgo { + t.Run("cgo", func(t *testing.T) { + testBuildmodePIE(t, true, false) + }) + } +} +func testBuildmodePIE(t *testing.T, useCgo, setBuildmodeToPIE bool) { tg := testgo(t) defer tg.cleanup() tg.parallel() - tg.tempFile("main.go", `package main; func main() { print("hello") }`) + var s string + if useCgo { + s = `import "C";` + } + tg.tempFile("main.go", fmt.Sprintf(`package main;%s func main() { print("hello") }`, s)) src := tg.path("main.go") - obj := tg.path("main") - tg.run("build", "-buildmode=pie", "-o", obj, src) + obj := tg.path("main.exe") + args := []string{"build"} + if setBuildmodeToPIE { + args = append(args, "-buildmode=pie") + } + args = append(args, "-o", obj, src) + tg.run(args...) switch runtime.GOOS { case "linux", "android", "freebsd": @@ -4020,6 +2139,33 @@ func TestBuildmodePIE(t *testing.T) { if f.Flags&macho.FlagPIE == 0 { t.Error("PIE must have PIE flag, but not") } + case "windows": + f, err := pe.Open(obj) + if err != nil { + t.Fatal(err) + } + defer f.Close() + if f.Section(".reloc") == nil { + t.Error(".reloc section is not present") + } + if (f.FileHeader.Characteristics & pe.IMAGE_FILE_RELOCS_STRIPPED) != 0 { + t.Error("IMAGE_FILE_RELOCS_STRIPPED flag is set") + } + var dc uint16 + switch oh := f.OptionalHeader.(type) { + case *pe.OptionalHeader32: + dc = oh.DllCharacteristics + case *pe.OptionalHeader64: + dc = oh.DllCharacteristics + if (dc & pe.IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA) == 0 { + t.Error("IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA flag is not set") + } + default: + t.Fatalf("unexpected optional header type of %T", f.OptionalHeader) + } + if (dc & pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) == 0 { + t.Error("IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE flag is not set") + } default: panic("unreachable") } @@ -4034,93 +2180,6 @@ func TestBuildmodePIE(t *testing.T) { } } -func TestExecBuildX(t *testing.T) { - tooSlow(t) - if !canCgo { - t.Skip("skipping because cgo not enabled") - } - - testenv.MustHaveExecPath(t, "/usr/bin/env") - testenv.MustHaveExecPath(t, "bash") - - tg := testgo(t) - defer tg.cleanup() - - tg.tempDir("cache") - tg.setenv("GOCACHE", tg.path("cache")) - - // Before building our test main.go, ensure that an up-to-date copy of - // runtime/cgo is present in the cache. If it isn't, the 'go build' step below - // will fail with "can't open import". See golang.org/issue/29004. - tg.run("build", "runtime/cgo") - - tg.tempFile("main.go", `package main; import "C"; func main() { print("hello") }`) - src := tg.path("main.go") - obj := tg.path("main") - tg.run("build", "-x", "-o", obj, src) - sh := tg.path("test.sh") - cmds := tg.getStderr() - err := ioutil.WriteFile(sh, []byte("set -e\n"+cmds), 0666) - if err != nil { - t.Fatal(err) - } - - out, err := exec.Command(obj).CombinedOutput() - if err != nil { - t.Fatal(err) - } - if string(out) != "hello" { - t.Fatalf("got %q; want %q", out, "hello") - } - - err = os.Remove(obj) - if err != nil { - t.Fatal(err) - } - - out, err = exec.Command("/usr/bin/env", "bash", "-x", sh).CombinedOutput() - if err != nil { - t.Fatalf("/bin/sh %s: %v\n%s", sh, err, out) - } - t.Logf("shell output:\n%s", out) - - out, err = exec.Command(obj).CombinedOutput() - if err != nil { - t.Fatal(err) - } - if string(out) != "hello" { - t.Fatalf("got %q; want %q", out, "hello") - } - - matches := regexp.MustCompile(`^WORK=(.*)\n`).FindStringSubmatch(cmds) - if len(matches) == 0 { - t.Fatal("no WORK directory") - } - tg.must(robustio.RemoveAll(matches[1])) -} - -func TestParallelNumber(t *testing.T) { - tooSlow(t) - for _, n := range [...]string{"-1", "0"} { - t.Run(n, func(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.runFail("test", "-parallel", n, "testdata/standalone_parallel_sub_test.go") - tg.grepBoth("-parallel can only be given", "go test -parallel with N<1 did not error") - }) - } -} - -func TestWrongGOOSErrorBeforeLoadError(t *testing.T) { - skipIfGccgo(t, "gccgo assumes cross-compilation is always possible") - tg := testgo(t) - defer tg.cleanup() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.setenv("GOOS", "windwos") - tg.runFail("build", "exclude") - tg.grepStderr("unsupported GOOS/GOARCH pair", "GOOS=windwos go build exclude did not report 'unsupported GOOS/GOARCH pair'") -} - func TestUpxCompression(t *testing.T) { if runtime.GOOS != "linux" || (runtime.GOARCH != "amd64" && runtime.GOARCH != "386") { @@ -4304,30 +2363,6 @@ func TestTestCache(t *testing.T) { tg.setenv("GOPATH", tg.tempdir) tg.setenv("GOCACHE", tg.path("cache")) - if runtime.Compiler != "gccgo" { - // timeout here should not affect result being cached - // or being retrieved later. - tg.run("test", "-x", "-timeout=10s", "errors") - tg.grepStderr(`[\\/]compile|gccgo`, "did not run compiler") - tg.grepStderr(`[\\/]link|gccgo`, "did not run linker") - tg.grepStderr(`errors\.test`, "did not run test") - - tg.run("test", "-x", "errors") - tg.grepStdout(`ok \terrors\t\(cached\)`, "did not report cached result") - tg.grepStderrNot(`[\\/]compile|gccgo`, "incorrectly ran compiler") - tg.grepStderrNot(`[\\/]link|gccgo`, "incorrectly ran linker") - tg.grepStderrNot(`errors\.test`, "incorrectly ran test") - tg.grepStderrNot("DO NOT USE", "poisoned action status leaked") - - // Even very low timeouts do not disqualify cached entries. - tg.run("test", "-timeout=1ns", "-x", "errors") - tg.grepStderrNot(`errors\.test`, "incorrectly ran test") - - tg.run("clean", "-testcache") - tg.run("test", "-x", "errors") - tg.grepStderr(`errors\.test`, "did not run test") - } - // The -p=1 in the commands below just makes the -x output easier to read. t.Log("\n\nINITIAL\n\n") @@ -4407,53 +2442,6 @@ func TestTestCache(t *testing.T) { } } -func TestTestVet(t *testing.T) { - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - - tg.tempFile("p1_test.go", ` - package p - import "testing" - func Test(t *testing.T) { - t.Logf("%d") // oops - } - `) - - tg.runFail("test", tg.path("p1_test.go")) - tg.grepStderr(`Logf format %d`, "did not diagnose bad Logf") - tg.run("test", "-vet=off", tg.path("p1_test.go")) - tg.grepStdout(`^ok`, "did not print test summary") - - tg.tempFile("p1.go", ` - package p - import "fmt" - func F() { - fmt.Printf("%d") // oops - } - `) - tg.runFail("test", tg.path("p1.go")) - tg.grepStderr(`Printf format %d`, "did not diagnose bad Printf") - tg.run("test", "-x", "-vet=shift", tg.path("p1.go")) - tg.grepStderr(`[\\/]vet.*-shift`, "did not run vet with -shift") - tg.grepStdout(`\[no test files\]`, "did not print test summary") - tg.run("test", "-vet=off", tg.path("p1.go")) - tg.grepStdout(`\[no test files\]`, "did not print test summary") - - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.run("test", "vetcycle") // must not fail; #22890 - - tg.runFail("test", "vetfail/...") - tg.grepStderr(`Printf format %d`, "did not diagnose bad Printf") - tg.grepStdout(`ok\s+vetfail/p2`, "did not run vetfail/p2") - - // Use -a so that we need to recompute the vet-specific export data for - // vetfail/p1. - tg.run("test", "-a", "vetfail/p2") - tg.grepStderrNot(`invalid.*constraint`, "did diagnose bad build constraint in vetxonly mode") -} - func TestTestSkipVetAfterFailedBuild(t *testing.T) { tg := testgo(t) defer tg.cleanup() @@ -4549,92 +2537,6 @@ func TestInstallDeps(t *testing.T) { tg.mustExist(p1) } -func TestGoTestJSON(t *testing.T) { - skipIfGccgo(t, "gccgo does not have standard packages") - tooSlow(t) - - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.makeTempdir() - tg.setenv("GOCACHE", tg.tempdir) - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - - // It would be nice to test that the output is interlaced - // but it seems to be impossible to do that in a short test - // that isn't also flaky. Just check that we get JSON output. - tg.run("test", "-json", "-short", "-v", "errors", "empty/pkg", "skipper") - tg.grepStdout(`"Package":"errors"`, "did not see JSON output") - tg.grepStdout(`"Action":"run"`, "did not see JSON output") - - tg.grepStdout(`"Action":"output","Package":"empty/pkg","Output":".*no test files`, "did not see no test files print") - tg.grepStdout(`"Action":"skip","Package":"empty/pkg"`, "did not see skip") - - tg.grepStdout(`"Action":"output","Package":"skipper","Test":"Test","Output":"--- SKIP:`, "did not see SKIP output") - tg.grepStdout(`"Action":"skip","Package":"skipper","Test":"Test"`, "did not see skip result for Test") - - tg.run("test", "-json", "-short", "-v", "errors") - tg.grepStdout(`"Action":"output","Package":"errors","Output":".*\(cached\)`, "did not see no cached output") - - tg.run("test", "-json", "-bench=NONE", "-short", "-v", "errors") - tg.grepStdout(`"Package":"errors"`, "did not see JSON output") - tg.grepStdout(`"Action":"run"`, "did not see JSON output") - - tg.run("test", "-o", tg.path("errors.test.exe"), "-c", "errors") - tg.run("tool", "test2json", "-p", "errors", tg.path("errors.test.exe"), "-test.v", "-test.short") - tg.grepStdout(`"Package":"errors"`, "did not see JSON output") - tg.grepStdout(`"Action":"run"`, "did not see JSON output") - tg.grepStdout(`\{"Action":"pass","Package":"errors"\}`, "did not see final pass") -} - -func TestFailFast(t *testing.T) { - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - - tests := []struct { - run string - failfast bool - nfail int - }{ - {"TestFailingA", true, 1}, - {"TestFailing[AB]", true, 1}, - {"TestFailing[AB]", false, 2}, - // mix with non-failing tests: - {"TestA|TestFailing[AB]", true, 1}, - {"TestA|TestFailing[AB]", false, 2}, - // mix with parallel tests: - {"TestFailingB|TestParallelFailingA", true, 2}, - {"TestFailingB|TestParallelFailingA", false, 2}, - {"TestFailingB|TestParallelFailing[AB]", true, 3}, - {"TestFailingB|TestParallelFailing[AB]", false, 3}, - // mix with parallel sub-tests - {"TestFailingB|TestParallelFailing[AB]|TestParallelFailingSubtestsA", true, 3}, - {"TestFailingB|TestParallelFailing[AB]|TestParallelFailingSubtestsA", false, 5}, - {"TestParallelFailingSubtestsA", true, 1}, - // only parallels: - {"TestParallelFailing[AB]", false, 2}, - // non-parallel subtests: - {"TestFailingSubtestsA", true, 1}, - {"TestFailingSubtestsA", false, 2}, - // fatal test - {"TestFatal[CD]", true, 1}, - {"TestFatal[CD]", false, 2}, - } - - for _, tt := range tests { - t.Run(tt.run, func(t *testing.T) { - tg.runFail("test", "./testdata/src/failfast_test.go", "-run="+tt.run, "-failfast="+strconv.FormatBool(tt.failfast)) - - nfail := strings.Count(tg.getStdout(), "FAIL - ") - - if nfail != tt.nfail { - t.Errorf("go test -run=%s -failfast=%t printed %d FAILs, want %d", tt.run, tt.failfast, nfail, tt.nfail) - } - }) - } -} - // Issue 22986. func TestImportPath(t *testing.T) { tooSlow(t) @@ -4723,7 +2625,7 @@ func TestBadCommandLines(t *testing.T) { tg.tempFile("src/-x/x.go", "package x\n") tg.setenv("GOPATH", tg.path(".")) tg.runFail("build", "--", "-x") - tg.grepStderr("invalid input directory name \"-x\"", "did not reject -x directory") + tg.grepStderr("invalid import path \"-x\"", "did not reject -x import path") tg.tempFile("src/-x/y/y.go", "package y\n") tg.setenv("GOPATH", tg.path(".")) @@ -4731,118 +2633,6 @@ func TestBadCommandLines(t *testing.T) { tg.grepStderr("invalid import path \"-x/y\"", "did not reject -x/y import path") } -func TestBadCgoDirectives(t *testing.T) { - if !canCgo { - t.Skip("no cgo") - } - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - - tg.tempFile("src/x/x.go", "package x\n") - tg.setenv("GOPATH", tg.path(".")) - - if runtime.Compiler == "gc" { - tg.tempFile("src/x/x.go", `package x - - //go:cgo_ldflag "-fplugin=foo.so" - - import "C" - `) - tg.runFail("build", "x") - tg.grepStderr("//go:cgo_ldflag .* only allowed in cgo-generated code", "did not reject //go:cgo_ldflag directive") - } - - tg.must(os.Remove(tg.path("src/x/x.go"))) - tg.runFail("build", "x") - tg.grepStderr("no Go files", "did not report missing source code") - tg.tempFile("src/x/_cgo_yy.go", `package x - - //go:cgo_ldflag "-fplugin=foo.so" - - import "C" - `) - tg.runFail("build", "x") - tg.grepStderr("no Go files", "did not report missing source code") // _* files are ignored... - - if runtime.Compiler == "gc" { - tg.runFail("build", tg.path("src/x/_cgo_yy.go")) // ... but if forced, the comment is rejected - // Actually, today there is a separate issue that _ files named - // on the command line are ignored. Once that is fixed, - // we want to see the cgo_ldflag error. - tg.grepStderr("//go:cgo_ldflag only allowed in cgo-generated code|no Go files", "did not reject //go:cgo_ldflag directive") - } - - tg.must(os.Remove(tg.path("src/x/_cgo_yy.go"))) - - tg.tempFile("src/x/x.go", "package x\n") - tg.tempFile("src/x/y.go", `package x - // #cgo CFLAGS: -fplugin=foo.so - import "C" - `) - tg.runFail("build", "x") - tg.grepStderr("invalid flag in #cgo CFLAGS: -fplugin=foo.so", "did not reject -fplugin") - - tg.tempFile("src/x/y.go", `package x - // #cgo CFLAGS: -Ibar -fplugin=foo.so - import "C" - `) - tg.runFail("build", "x") - tg.grepStderr("invalid flag in #cgo CFLAGS: -fplugin=foo.so", "did not reject -fplugin") - - tg.tempFile("src/x/y.go", `package x - // #cgo pkg-config: -foo - import "C" - `) - tg.runFail("build", "x") - tg.grepStderr("invalid pkg-config package name: -foo", "did not reject pkg-config: -foo") - - tg.tempFile("src/x/y.go", `package x - // #cgo pkg-config: @foo - import "C" - `) - tg.runFail("build", "x") - tg.grepStderr("invalid pkg-config package name: @foo", "did not reject pkg-config: -foo") - - tg.tempFile("src/x/y.go", `package x - // #cgo CFLAGS: @foo - import "C" - `) - tg.runFail("build", "x") - tg.grepStderr("invalid flag in #cgo CFLAGS: @foo", "did not reject @foo flag") - - tg.tempFile("src/x/y.go", `package x - // #cgo CFLAGS: -D - import "C" - `) - tg.runFail("build", "x") - tg.grepStderr("invalid flag in #cgo CFLAGS: -D without argument", "did not reject trailing -I flag") - - // Note that -I @foo is allowed because we rewrite it into -I /path/to/src/@foo - // before the check is applied. There's no such rewrite for -D. - - tg.tempFile("src/x/y.go", `package x - // #cgo CFLAGS: -D @foo - import "C" - `) - tg.runFail("build", "x") - tg.grepStderr("invalid flag in #cgo CFLAGS: -D @foo", "did not reject -D @foo flag") - - tg.tempFile("src/x/y.go", `package x - // #cgo CFLAGS: -D@foo - import "C" - `) - tg.runFail("build", "x") - tg.grepStderr("invalid flag in #cgo CFLAGS: -D@foo", "did not reject -D@foo flag") - - tg.setenv("CGO_CFLAGS", "-D@foo") - tg.tempFile("src/x/y.go", `package x - import "C" - `) - tg.run("build", "-n", "x") - tg.grepStderr("-D@foo", "did not find -D@foo in commands") -} - func TestTwoPkgConfigs(t *testing.T) { if !canCgo { t.Skip("no cgo") @@ -4978,52 +2768,6 @@ func TestLinkerTmpDirIsDeleted(t *testing.T) { } } -func testCDAndGOPATHAreDifferent(tg *testgoData, cd, gopath string) { - skipIfGccgo(tg.t, "gccgo does not support -ldflags -X") - tg.setenv("GOPATH", gopath) - - tg.tempDir("dir") - exe := tg.path("dir/a.exe") - - tg.cd(cd) - - tg.run("build", "-o", exe, "-ldflags", "-X=my.pkg.Text=linkXworked") - out, err := exec.Command(exe).CombinedOutput() - if err != nil { - tg.t.Fatal(err) - } - if string(out) != "linkXworked\n" { - tg.t.Errorf(`incorrect output with GOPATH=%q and CD=%q: expected "linkXworked\n", but have %q`, gopath, cd, string(out)) - } -} - -func TestCDAndGOPATHAreDifferent(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - - gopath := filepath.Join(tg.pwd(), "testdata") - cd := filepath.Join(gopath, "src/my.pkg/main") - - testCDAndGOPATHAreDifferent(tg, cd, gopath) - if runtime.GOOS == "windows" { - testCDAndGOPATHAreDifferent(tg, cd, strings.ReplaceAll(gopath, `\`, `/`)) - testCDAndGOPATHAreDifferent(tg, cd, strings.ToUpper(gopath)) - testCDAndGOPATHAreDifferent(tg, cd, strings.ToLower(gopath)) - } -} - -// Issue 25579. -func TestGoBuildDashODevNull(t *testing.T) { - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.run("build", "-o", os.DevNull, filepath.Join(tg.pwd(), "testdata", "src", "hello", "hello.go")) - tg.mustNotExist("hello") - tg.mustNotExist("hello.exe") -} - // Issue 25093. func TestCoverpkgTestOnly(t *testing.T) { skipIfGccgo(t, "gccgo has no cover tool") diff --git a/libgo/go/cmd/go/help_test.go b/libgo/go/cmd/go/help_test.go index 9bcab820ce6..78d63ff05e9 100644 --- a/libgo/go/cmd/go/help_test.go +++ b/libgo/go/cmd/go/help_test.go @@ -14,6 +14,8 @@ import ( ) func TestDocsUpToDate(t *testing.T) { + t.Parallel() + if !modload.Enabled() { t.Skipf("help.Help in GOPATH mode is configured by main.main") } diff --git a/libgo/go/cmd/go/internal/auth/auth.go b/libgo/go/cmd/go/internal/auth/auth.go index 12e3c74dcc7..fe5a89d7271 100644 --- a/libgo/go/cmd/go/internal/auth/auth.go +++ b/libgo/go/cmd/go/internal/auth/auth.go @@ -10,10 +10,12 @@ import "net/http" // AddCredentials fills in the user's credentials for req, if any. // The return value reports whether any matching credentials were found. func AddCredentials(req *http.Request) (added bool) { + host := req.URL.Hostname() + // TODO(golang.org/issue/26232): Support arbitrary user-provided credentials. netrcOnce.Do(readNetrc) for _, l := range netrc { - if l.machine == req.URL.Host { + if l.machine == host { req.SetBasicAuth(l.login, l.password) return true } diff --git a/libgo/go/cmd/go/internal/base/base.go b/libgo/go/cmd/go/internal/base/base.go index 272da556812..ab2f1bb4e2c 100644 --- a/libgo/go/cmd/go/internal/base/base.go +++ b/libgo/go/cmd/go/internal/base/base.go @@ -7,11 +7,8 @@ package base import ( - "bytes" - "errors" "flag" "fmt" - "go/scanner" "log" "os" "os/exec" @@ -172,25 +169,3 @@ func RunStdin(cmdline []string) { // Usage is the usage-reporting function, filled in by package main // but here for reference by other packages. var Usage func() - -// ExpandScanner expands a scanner.List error into all the errors in the list. -// The default Error method only shows the first error -// and does not shorten paths. -func ExpandScanner(err error) error { - // Look for parser errors. - if err, ok := err.(scanner.ErrorList); ok { - // Prepare error with \n before each message. - // When printed in something like context: %v - // this will put the leading file positions each on - // its own line. It will also show all the errors - // instead of just the first, as err.Error does. - var buf bytes.Buffer - for _, e := range err { - e.Pos.Filename = ShortPath(e.Pos.Filename) - buf.WriteString("\n") - buf.WriteString(e.Error()) - } - return errors.New(buf.String()) - } - return err -} diff --git a/libgo/go/cmd/go/internal/base/env.go b/libgo/go/cmd/go/internal/base/env.go index 077295e0eff..5f2665d2367 100644 --- a/libgo/go/cmd/go/internal/base/env.go +++ b/libgo/go/cmd/go/internal/base/env.go @@ -4,12 +4,12 @@ package base -// EnvForDir returns a modified environment suitable for running in the given -// directory. -// The environment is the supplied base environment but with an updated $PWD, so -// that an os.Getwd in the child will be faster. -func EnvForDir(dir string, base []string) []string { - // Internally we only use rooted paths, so dir is rooted. - // Even if dir is not rooted, no harm done. +// AppendPWD returns the result of appending PWD=dir to the environment base. +// +// The resulting environment makes os.Getwd more efficient for a subprocess +// running in dir. +func AppendPWD(base []string, dir string) []string { + // Internally we only use absolute paths, so dir is absolute. + // Even if dir is not absolute, no harm done. return append(base, "PWD="+dir) } diff --git a/libgo/go/cmd/go/internal/base/goflags.go b/libgo/go/cmd/go/internal/base/goflags.go index 187c2a14727..34766134b09 100644 --- a/libgo/go/cmd/go/internal/base/goflags.go +++ b/libgo/go/cmd/go/internal/base/goflags.go @@ -102,7 +102,7 @@ type boolFlag interface { } // SetFromGOFLAGS sets the flags in the given flag set using settings in $GOFLAGS. -func SetFromGOFLAGS(flags flag.FlagSet) { +func SetFromGOFLAGS(flags *flag.FlagSet) { InitGOFLAGS() // This loop is similar to flag.Parse except that it ignores @@ -125,14 +125,18 @@ func SetFromGOFLAGS(flags flag.FlagSet) { if f == nil { continue } + + // Use flags.Set consistently (instead of f.Value.Set) so that a subsequent + // call to flags.Visit will correctly visit the flags that have been set. + if fb, ok := f.Value.(boolFlag); ok && fb.IsBoolFlag() { if hasValue { - if err := fb.Set(value); err != nil { + if err := flags.Set(f.Name, value); err != nil { fmt.Fprintf(flags.Output(), "go: invalid boolean value %q for flag %s (from %s): %v\n", value, name, where, err) flags.Usage() } } else { - if err := fb.Set("true"); err != nil { + if err := flags.Set(f.Name, "true"); err != nil { fmt.Fprintf(flags.Output(), "go: invalid boolean flag %s (from %s): %v\n", name, where, err) flags.Usage() } @@ -142,7 +146,7 @@ func SetFromGOFLAGS(flags flag.FlagSet) { fmt.Fprintf(flags.Output(), "go: flag needs an argument: %s (from %s)\n", name, where) flags.Usage() } - if err := f.Value.Set(value); err != nil { + if err := flags.Set(f.Name, value); err != nil { fmt.Fprintf(flags.Output(), "go: invalid value %q for flag %s (from %s): %v\n", value, name, where, err) flags.Usage() } diff --git a/libgo/go/cmd/go/internal/cache/cache.go b/libgo/go/cmd/go/internal/cache/cache.go index 87973987650..15545ac31f8 100644 --- a/libgo/go/cmd/go/internal/cache/cache.go +++ b/libgo/go/cmd/go/internal/cache/cache.go @@ -108,7 +108,7 @@ const ( // GODEBUG=gocacheverify=1. var verify = false -var errVerifyMode = errors.New("gocachverify=1") +var errVerifyMode = errors.New("gocacheverify=1") // DebugTest is set when GODEBUG=gocachetest=1 is in the environment. var DebugTest = false diff --git a/libgo/go/cmd/go/internal/cfg/cfg.go b/libgo/go/cmd/go/internal/cfg/cfg.go index 61dc6bdda66..7f8f8e92be3 100644 --- a/libgo/go/cmd/go/internal/cfg/cfg.go +++ b/libgo/go/cmd/go/internal/cfg/cfg.go @@ -236,6 +236,7 @@ var ( GOROOTpkg = filepath.Join(GOROOT, "pkg") GOROOTsrc = filepath.Join(GOROOT, "src") GOROOT_FINAL = findGOROOT_FINAL() + GOMODCACHE = envOr("GOMODCACHE", gopathDir("pkg/mod")) // Used in envcmd.MkEnv and build ID computations. GOARM = envOr("GOARM", fmt.Sprint(objabi.GOARM)) @@ -253,6 +254,8 @@ var ( GOINSECURE = Getenv("GOINSECURE") ) +var SumdbDir = gopathDir("pkg/sumdb") + // GetArchEnv returns the name and setting of the // GOARCH-specific architecture environment variable. // If the current architecture has no GOARCH-specific variable, @@ -364,3 +367,11 @@ func isGOROOT(path string) bool { } return stat.IsDir() } + +func gopathDir(rel string) string { + list := filepath.SplitList(BuildContext.GOPATH) + if len(list) == 0 || list[0] == "" { + return "" + } + return filepath.Join(list[0], rel) +} diff --git a/libgo/go/cmd/go/internal/clean/clean.go b/libgo/go/cmd/go/internal/clean/clean.go index 69e17482b44..99704cb2b1b 100644 --- a/libgo/go/cmd/go/internal/clean/clean.go +++ b/libgo/go/cmd/go/internal/clean/clean.go @@ -137,20 +137,27 @@ func runClean(cmd *base.Command, args []string) { if cfg.BuildN || cfg.BuildX { b.Showcmd("", "rm -r %s", strings.Join(subdirs, " ")) } - for _, d := range subdirs { - // Only print the first error - there may be many. - // This also mimics what os.RemoveAll(dir) would do. - if err := os.RemoveAll(d); err != nil && !printedErrors { - printedErrors = true - base.Errorf("go clean -cache: %v", err) + if !cfg.BuildN { + for _, d := range subdirs { + // Only print the first error - there may be many. + // This also mimics what os.RemoveAll(dir) would do. + if err := os.RemoveAll(d); err != nil && !printedErrors { + printedErrors = true + base.Errorf("go clean -cache: %v", err) + } } } } logFile := filepath.Join(dir, "log.txt") - if err := os.RemoveAll(logFile); err != nil && !printedErrors { - printedErrors = true - base.Errorf("go clean -cache: %v", err) + if cfg.BuildN || cfg.BuildX { + b.Showcmd("", "rm -f %s", logFile) + } + if !cfg.BuildN { + if err := os.RemoveAll(logFile); err != nil && !printedErrors { + printedErrors = true + base.Errorf("go clean -cache: %v", err) + } } } } @@ -186,14 +193,14 @@ func runClean(cmd *base.Command, args []string) { } if cleanModcache { - if modfetch.PkgMod == "" { + if cfg.GOMODCACHE == "" { base.Fatalf("go clean -modcache: no module cache") } if cfg.BuildN || cfg.BuildX { - b.Showcmd("", "rm -rf %s", modfetch.PkgMod) + b.Showcmd("", "rm -rf %s", cfg.GOMODCACHE) } if !cfg.BuildN { - if err := modfetch.RemoveAll(modfetch.PkgMod); err != nil { + if err := modfetch.RemoveAll(cfg.GOMODCACHE); err != nil { base.Errorf("go clean -modcache: %v", err) } } @@ -232,7 +239,7 @@ func clean(p *load.Package) { cleaned[p] = true if p.Dir == "" { - base.Errorf("can't load package: %v", p.Error) + base.Errorf("%v", p.Error) return } dirs, err := ioutil.ReadDir(p.Dir) diff --git a/libgo/go/cmd/go/internal/cmdflag/flag.go b/libgo/go/cmd/go/internal/cmdflag/flag.go index 3f934328fe1..8abb7e559f5 100644 --- a/libgo/go/cmd/go/internal/cmdflag/flag.go +++ b/libgo/go/cmd/go/internal/cmdflag/flag.go @@ -6,13 +6,10 @@ package cmdflag import ( + "errors" "flag" "fmt" - "os" - "strconv" "strings" - - "cmd/go/internal/base" ) // The flag handling part of go commands such as test is large and distracting. @@ -20,141 +17,113 @@ import ( // our command line are for us, and some are for the binary we're running, // and some are for both. -// Defn defines a flag we know about. -type Defn struct { - Name string // Name on command line. - BoolVar *bool // If it's a boolean flag, this points to it. - Value flag.Value // The flag.Value represented. - PassToTest bool // Pass to the test binary? Used only by go test. - Present bool // Flag has been seen. -} +// ErrFlagTerminator indicates the distinguished token "--", which causes the +// flag package to treat all subsequent arguments as non-flags. +var ErrFlagTerminator = errors.New("flag terminator") -// IsBool reports whether v is a bool flag. -func IsBool(v flag.Value) bool { - vv, ok := v.(interface { - IsBoolFlag() bool - }) - if ok { - return vv.IsBoolFlag() - } - return false +// A FlagNotDefinedError indicates a flag-like argument that does not correspond +// to any registered flag in a FlagSet. +type FlagNotDefinedError struct { + RawArg string // the original argument, like --foo or -foo=value + Name string + HasValue bool // is this the -foo=value or --foo=value form? + Value string // only provided if HasValue is true } -// SetBool sets the addressed boolean to the value. -func SetBool(cmd string, flag *bool, value string) { - x, err := strconv.ParseBool(value) - if err != nil { - SyntaxError(cmd, "illegal bool flag value "+value) - } - *flag = x +func (e FlagNotDefinedError) Error() string { + return fmt.Sprintf("flag provided but not defined: -%s", e.Name) } -// SetInt sets the addressed integer to the value. -func SetInt(cmd string, flag *int, value string) { - x, err := strconv.Atoi(value) - if err != nil { - SyntaxError(cmd, "illegal int flag value "+value) - } - *flag = x +// A NonFlagError indicates an argument that is not a syntactically-valid flag. +type NonFlagError struct { + RawArg string } -// SyntaxError reports an argument syntax error and exits the program. -func SyntaxError(cmd, msg string) { - fmt.Fprintf(os.Stderr, "go %s: %s\n", cmd, msg) - if cmd == "test" { - fmt.Fprintf(os.Stderr, `run "go help %s" or "go help testflag" for more information`+"\n", cmd) - } else { - fmt.Fprintf(os.Stderr, `run "go help %s" for more information`+"\n", cmd) - } - base.SetExitStatus(2) - base.Exit() +func (e NonFlagError) Error() string { + return fmt.Sprintf("not a flag: %q", e.RawArg) } -// AddKnownFlags registers the flags in defns with base.AddKnownFlag. -func AddKnownFlags(cmd string, defns []*Defn) { - for _, f := range defns { - base.AddKnownFlag(f.Name) - base.AddKnownFlag(cmd + "." + f.Name) - } -} +// ParseOne sees if args[0] is present in the given flag set and if so, +// sets its value and returns the flag along with the remaining (unused) arguments. +// +// ParseOne always returns either a non-nil Flag or a non-nil error, +// and always consumes at least one argument (even on error). +// +// Unlike (*flag.FlagSet).Parse, ParseOne does not log its own errors. +func ParseOne(fs *flag.FlagSet, args []string) (f *flag.Flag, remainingArgs []string, err error) { + // This function is loosely derived from (*flag.FlagSet).parseOne. -// Parse sees if argument i is present in the definitions and if so, -// returns its definition, value, and whether it consumed an extra word. -// If the flag begins (cmd.Name()+".") it is ignored for the purpose of this function. -func Parse(cmd string, usage func(), defns []*Defn, args []string, i int) (f *Defn, value string, extra bool) { - arg := args[i] - if strings.HasPrefix(arg, "--") { // reduce two minuses to one - arg = arg[1:] + raw, args := args[0], args[1:] + arg := raw + if strings.HasPrefix(arg, "--") { + if arg == "--" { + return nil, args, ErrFlagTerminator + } + arg = arg[1:] // reduce two minuses to one } + switch arg { case "-?", "-h", "-help": - usage() + return nil, args, flag.ErrHelp } - if arg == "" || arg[0] != '-' { - return + if len(arg) < 2 || arg[0] != '-' || arg[1] == '-' || arg[1] == '=' { + return nil, args, NonFlagError{RawArg: raw} } + name := arg[1:] - // If there's already a prefix such as "test.", drop it for now. - name = strings.TrimPrefix(name, cmd+".") - equals := strings.Index(name, "=") - if equals >= 0 { - value = name[equals+1:] - name = name[:equals] + hasValue := false + value := "" + if i := strings.Index(name, "="); i >= 0 { + value = name[i+1:] + hasValue = true + name = name[0:i] } - for _, f = range defns { - if name == f.Name { - // Booleans are special because they have modes -x, -x=true, -x=false. - if f.BoolVar != nil || IsBool(f.Value) { - if equals < 0 { // Otherwise, it's been set and will be verified in SetBool. - value = "true" - } else { - // verify it parses - SetBool(cmd, new(bool), value) - } - } else { // Non-booleans must have a value. - extra = equals < 0 - if extra { - if i+1 >= len(args) { - SyntaxError(cmd, "missing argument for flag "+f.Name) - } - value = args[i+1] - } - } - if f.Present { - SyntaxError(cmd, f.Name+" flag may be set only once") - } - f.Present = true - return + + f = fs.Lookup(name) + if f == nil { + return nil, args, FlagNotDefinedError{ + RawArg: raw, + Name: name, + HasValue: hasValue, + Value: value, } } - f = nil - return -} -// FindGOFLAGS extracts and returns the flags matching defns from GOFLAGS. -// Ideally the caller would mention that the flags were from GOFLAGS -// when reporting errors, but that's too hard for now. -func FindGOFLAGS(defns []*Defn) []string { - var flags []string - for _, flag := range base.GOFLAGS() { - // Flags returned by base.GOFLAGS are well-formed, one of: - // -x - // --x - // -x=value - // --x=value - if strings.HasPrefix(flag, "--") { - flag = flag[1:] + // Use fs.Set instead of f.Value.Set below so that any subsequent call to + // fs.Visit will correctly visit the flags that have been set. + + failf := func(format string, a ...interface{}) (*flag.Flag, []string, error) { + return f, args, fmt.Errorf(format, a...) + } + + if fv, ok := f.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg + if hasValue { + if err := fs.Set(name, value); err != nil { + return failf("invalid boolean value %q for -%s: %v", value, name, err) + } + } else { + if err := fs.Set(name, "true"); err != nil { + return failf("invalid boolean flag %s: %v", name, err) + } } - name := flag[1:] - if i := strings.Index(name, "="); i >= 0 { - name = name[:i] + } else { + // It must have a value, which might be the next argument. + if !hasValue && len(args) > 0 { + // value is the next arg + hasValue = true + value, args = args[0], args[1:] } - for _, f := range defns { - if name == f.Name { - flags = append(flags, flag) - break - } + if !hasValue { + return failf("flag needs an argument: -%s", name) + } + if err := fs.Set(name, value); err != nil { + return failf("invalid value %q for flag -%s: %v", value, name, err) } } - return flags + + return f, args, nil +} + +type boolFlag interface { + IsBoolFlag() bool } diff --git a/libgo/go/cmd/go/internal/envcmd/env.go b/libgo/go/cmd/go/internal/envcmd/env.go index d2d5ed95076..252025dc255 100644 --- a/libgo/go/cmd/go/internal/envcmd/env.go +++ b/libgo/go/cmd/go/internal/envcmd/env.go @@ -77,6 +77,7 @@ func MkEnv() []cfg.EnvVar { {Name: "GOHOSTARCH", Value: runtime.GOARCH}, {Name: "GOHOSTOS", Value: runtime.GOOS}, {Name: "GOINSECURE", Value: cfg.GOINSECURE}, + {Name: "GOMODCACHE", Value: cfg.GOMODCACHE}, {Name: "GONOPROXY", Value: cfg.GONOPROXY}, {Name: "GONOSUMDB", Value: cfg.GONOSUMDB}, {Name: "GOOS", Value: cfg.Goos}, diff --git a/libgo/go/cmd/go/internal/fmtcmd/fmt.go b/libgo/go/cmd/go/internal/fmtcmd/fmt.go index 408af52ffa0..d6894edc9f5 100644 --- a/libgo/go/cmd/go/internal/fmtcmd/fmt.go +++ b/libgo/go/cmd/go/internal/fmtcmd/fmt.go @@ -6,11 +6,11 @@ package fmtcmd import ( + "errors" "fmt" "os" "path/filepath" "runtime" - "strings" "sync" "cmd/go/internal/base" @@ -72,11 +72,12 @@ func runFmt(cmd *base.Command, args []string) { continue } if pkg.Error != nil { - if strings.HasPrefix(pkg.Error.Err.Error(), "build constraints exclude all Go files") { + var nogo *load.NoGoError + if errors.As(pkg.Error, &nogo) && len(pkg.InternalAllGoFiles()) > 0 { // Skip this error, as we will format // all files regardless. } else { - base.Errorf("can't load package: %s", pkg.Error) + base.Errorf("%v", pkg.Error) continue } } diff --git a/libgo/go/cmd/go/internal/generate/generate.go b/libgo/go/cmd/go/internal/generate/generate.go index 315db69de8a..093b19817b5 100644 --- a/libgo/go/cmd/go/internal/generate/generate.go +++ b/libgo/go/cmd/go/internal/generate/generate.go @@ -9,7 +9,10 @@ import ( "bufio" "bytes" "fmt" + "go/parser" + "go/token" "io" + "io/ioutil" "log" "os" "os/exec" @@ -119,6 +122,9 @@ in the file, one at a time. The go generate tool also sets the build tag "generate" so that files may be examined by go generate but ignored during build. +For packages with invalid code, generate processes only source files with a +valid package clause. + If any generator returns an error exit status, "go generate" skips all further processing for that package. @@ -169,7 +175,7 @@ func runGenerate(cmd *base.Command, args []string) { // Even if the arguments are .go files, this loop suffices. printed := false - for _, pkg := range load.Packages(args) { + for _, pkg := range load.PackagesAndErrors(args) { if modload.Enabled() && pkg.Module != nil && !pkg.Module.Main { if !printed { fmt.Fprintf(os.Stderr, "go: not generating in packages in dependency modules\n") @@ -178,18 +184,14 @@ func runGenerate(cmd *base.Command, args []string) { continue } - pkgName := pkg.Name - for _, file := range pkg.InternalGoFiles() { - if !generate(pkgName, file) { + if !generate(file) { break } } - pkgName += "_test" - for _, file := range pkg.InternalXGoFiles() { - if !generate(pkgName, file) { + if !generate(file) { break } } @@ -197,16 +199,23 @@ func runGenerate(cmd *base.Command, args []string) { } // generate runs the generation directives for a single file. -func generate(pkg, absFile string) bool { - fd, err := os.Open(absFile) +func generate(absFile string) bool { + src, err := ioutil.ReadFile(absFile) if err != nil { log.Fatalf("generate: %s", err) } - defer fd.Close() + + // Parse package clause + filePkg, err := parser.ParseFile(token.NewFileSet(), "", src, parser.PackageClauseOnly) + if err != nil { + // Invalid package clause - ignore file. + return true + } + g := &Generator{ - r: fd, + r: bytes.NewReader(src), path: absFile, - pkg: pkg, + pkg: filePkg.Name.String(), commands: make(map[string][]string), } return g.run() diff --git a/libgo/go/cmd/go/internal/get/get.go b/libgo/go/cmd/go/internal/get/get.go index 500e3e0da6d..d38350c2a82 100644 --- a/libgo/go/cmd/go/internal/get/get.go +++ b/libgo/go/cmd/go/internal/get/get.go @@ -7,7 +7,6 @@ package get import ( "fmt" - "go/build" "os" "path/filepath" "runtime" @@ -194,12 +193,28 @@ func downloadPaths(patterns []string) []string { for _, arg := range patterns { if strings.Contains(arg, "@") { base.Fatalf("go: cannot use path@version syntax in GOPATH mode") + continue + } + + // Guard against 'go get x.go', a common mistake. + // Note that package and module paths may end with '.go', so only print an error + // if the argument has no slash or refers to an existing file. + if strings.HasSuffix(arg, ".go") { + if !strings.Contains(arg, "/") { + base.Errorf("go get %s: arguments must be package or module paths", arg) + continue + } + if fi, err := os.Stat(arg); err == nil && !fi.IsDir() { + base.Errorf("go get: %s exists as a file, but 'go get' requires package arguments", arg) + } } } + base.ExitIfErrors() + var pkgs []string for _, m := range search.ImportPathsQuiet(patterns) { - if len(m.Pkgs) == 0 && strings.Contains(m.Pattern, "...") { - pkgs = append(pkgs, m.Pattern) + if len(m.Pkgs) == 0 && strings.Contains(m.Pattern(), "...") { + pkgs = append(pkgs, m.Pattern()) } else { pkgs = append(pkgs, m.Pkgs...) } @@ -285,10 +300,16 @@ func download(arg string, parent *load.Package, stk *load.ImportStack, mode int) // We delay this until after reloadPackage so that the old entry // for p has been replaced in the package cache. if wildcardOkay && strings.Contains(arg, "...") { - if build.IsLocalImport(arg) { - args = search.MatchPackagesInFS(arg).Pkgs + match := search.NewMatch(arg) + if match.IsLocal() { + match.MatchDirs() + args = match.Dirs } else { - args = search.MatchPackages(arg).Pkgs + match.MatchPackages() + args = match.Pkgs + } + for _, err := range match.Errs { + base.Errorf("%s", err) } isWildcard = true } diff --git a/libgo/go/cmd/go/internal/get/vcs.go b/libgo/go/cmd/go/internal/get/vcs.go index 2e4d6388cfe..fd37fcb76f2 100644 --- a/libgo/go/cmd/go/internal/get/vcs.go +++ b/libgo/go/cmd/go/internal/get/vcs.go @@ -430,7 +430,7 @@ func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool) cmd := exec.Command(v.cmd, args...) cmd.Dir = dir - cmd.Env = base.EnvForDir(cmd.Dir, os.Environ()) + cmd.Env = base.AppendPWD(os.Environ(), cmd.Dir) if cfg.BuildX { fmt.Fprintf(os.Stderr, "cd %s\n", dir) fmt.Fprintf(os.Stderr, "%s %s\n", v.cmd, strings.Join(args, " ")) diff --git a/libgo/go/cmd/go/internal/help/help.go b/libgo/go/cmd/go/internal/help/help.go index edb4a2a23ca..7a730fc8eb8 100644 --- a/libgo/go/cmd/go/internal/help/help.go +++ b/libgo/go/cmd/go/internal/help/help.go @@ -93,7 +93,7 @@ Use "go help{{with .LongName}} {{.}}{{end}} " for more information abou {{if eq (.UsageLine) "go"}} Additional help topics: {{range .Commands}}{{if and (not .Runnable) (not .Commands)}} - {{.Name | printf "%-11s"}} {{.Short}}{{end}}{{end}} + {{.Name | printf "%-15s"}} {{.Short}}{{end}}{{end}} Use "go help{{with .LongName}} {{.}}{{end}} " for more information about that topic. {{end}} diff --git a/libgo/go/cmd/go/internal/help/helpdoc.go b/libgo/go/cmd/go/internal/help/helpdoc.go index 6a843f459a8..e1f0521ea41 100644 --- a/libgo/go/cmd/go/internal/help/helpdoc.go +++ b/libgo/go/cmd/go/internal/help/helpdoc.go @@ -493,6 +493,8 @@ General-purpose environment variables: GOCACHE The directory where the go command will store cached information for reuse in future builds. + GOMODCACHE + The directory where the go command will store downloaded modules. GODEBUG Enable various debugging facilities. See 'go doc runtime' for details. @@ -510,6 +512,9 @@ General-purpose environment variables: Comma-separated list of glob patterns (in the syntax of Go's path.Match) of module path prefixes that should always be fetched in an insecure manner. Only applies to dependencies that are being fetched directly. + Unlike the -insecure flag on 'go get', GOINSECURE does not disable + checksum database validation. GOPRIVATE or GONOSUMDB may be used + to achieve that. GOOS The operating system for which to compile code. Examples are linux, darwin, windows, netbsd. @@ -762,3 +767,95 @@ GODEBUG=gocachetest=1 causes the go command to print details of its decisions about whether to reuse a cached test result. `, } + +var HelpBuildConstraint = &base.Command{ + UsageLine: "buildconstraint", + Short: "build constraints", + Long: ` +A build constraint, also known as a build tag, is a line comment that begins + + // +build + +that lists the conditions under which a file should be included in the package. +Constraints may appear in any kind of source file (not just Go), but +they must appear near the top of the file, preceded +only by blank lines and other line comments. These rules mean that in Go +files a build constraint must appear before the package clause. + +To distinguish build constraints from package documentation, a series of +build constraints must be followed by a blank line. + +A build constraint is evaluated as the OR of space-separated options. +Each option evaluates as the AND of its comma-separated terms. +Each term consists of letters, digits, underscores, and dots. +A term may be negated with a preceding !. +For example, the build constraint: + + // +build linux,386 darwin,!cgo + +corresponds to the boolean formula: + + (linux AND 386) OR (darwin AND (NOT cgo)) + +A file may have multiple build constraints. The overall constraint is the AND +of the individual constraints. That is, the build constraints: + + // +build linux darwin + // +build amd64 + +corresponds to the boolean formula: + + (linux OR darwin) AND amd64 + +During a particular build, the following words are satisfied: + + - the target operating system, as spelled by runtime.GOOS, set with the + GOOS environment variable. + - the target architecture, as spelled by runtime.GOARCH, set with the + GOARCH environment variable. + - the compiler being used, either "gc" or "gccgo" + - "cgo", if the cgo command is supported (see CGO_ENABLED in + 'go help environment'). + - a term for each Go major release, through the current version: + "go1.1" from Go version 1.1 onward, "go1.12" from Go 1.12, and so on. + - any additional tags given by the -tags flag (see 'go help build'). + +There are no separate build tags for beta or minor releases. + +If a file's name, after stripping the extension and a possible _test suffix, +matches any of the following patterns: + *_GOOS + *_GOARCH + *_GOOS_GOARCH +(example: source_windows_amd64.go) where GOOS and GOARCH represent +any known operating system and architecture values respectively, then +the file is considered to have an implicit build constraint requiring +those terms (in addition to any explicit constraints in the file). + +Using GOOS=android matches build tags and files as for GOOS=linux +in addition to android tags and files. + +Using GOOS=illumos matches build tags and files as for GOOS=solaris +in addition to illumos tags and files. + +To keep a file from being considered for the build: + + // +build ignore + +(any other unsatisfied word will work as well, but "ignore" is conventional.) + +To build a file only when using cgo, and only on Linux and OS X: + + // +build linux,cgo darwin,cgo + +Such a file is usually paired with another file implementing the +default functionality for other systems, which in this case would +carry the constraint: + + // +build !linux,!darwin !cgo + +Naming a file dns_windows.go will cause it to be included only when +building the package for Windows; similarly, math_386.s will be included +only when building the package for 32-bit x86. +`, +} diff --git a/libgo/go/cmd/go/internal/list/list.go b/libgo/go/cmd/go/internal/list/list.go index 8d979e276f1..6ca15611211 100644 --- a/libgo/go/cmd/go/internal/list/list.go +++ b/libgo/go/cmd/go/internal/list/list.go @@ -451,6 +451,7 @@ func runList(cmd *base.Command, args []string) { pkgs = load.PackagesAndErrors(args) } else { pkgs = load.Packages(args) + base.ExitIfErrors() } if cache.Default() == nil { @@ -471,9 +472,6 @@ func runList(cmd *base.Command, args []string) { c := cache.Default() // Add test binaries to packages to be listed. for _, p := range pkgs { - if p.Error != nil { - continue - } if len(p.TestGoFiles)+len(p.XTestGoFiles) > 0 { var pmain, ptest, pxtest *load.Package var err error diff --git a/libgo/go/cmd/go/internal/load/pkg.go b/libgo/go/cmd/go/internal/load/pkg.go index 06b6e23e633..e146e34ab52 100644 --- a/libgo/go/cmd/go/internal/load/pkg.go +++ b/libgo/go/cmd/go/internal/load/pkg.go @@ -187,20 +187,17 @@ type PackageInternal struct { Gccgoflags []string // -gccgoflags for this package } +// A NoGoError indicates that no Go files for the package were applicable to the +// build for that package. +// +// That may be because there were no files whatsoever, or because all files were +// excluded, or because all non-excluded files were test sources. type NoGoError struct { Package *Package } func (e *NoGoError) Error() string { - // Count files beginning with _ and ., which we will pretend don't exist at all. - dummy := 0 - for _, name := range e.Package.IgnoredGoFiles { - if strings.HasPrefix(name, "_") || strings.HasPrefix(name, ".") { - dummy++ - } - } - - if len(e.Package.IgnoredGoFiles) > dummy { + if len(e.Package.constraintIgnoredGoFiles()) > 0 { // Go files exist, but they were ignored due to build constraints. return "build constraints exclude all Go files in " + e.Package.Dir } @@ -213,6 +210,77 @@ func (e *NoGoError) Error() string { return "no Go files in " + e.Package.Dir } +// setLoadPackageDataError presents an error found when loading package data +// as a *PackageError. It has special cases for some common errors to improve +// messages shown to users and reduce redundancy. +// +// setLoadPackageDataError returns true if it's safe to load information about +// imported packages, for example, if there was a parse error loading imports +// in one file, but other files are okay. +func (p *Package) setLoadPackageDataError(err error, path string, stk *ImportStack, importPos []token.Position) { + matchErr, isMatchErr := err.(*search.MatchError) + if isMatchErr && matchErr.Match.Pattern() == path { + if matchErr.Match.IsLiteral() { + // The error has a pattern has a pattern similar to the import path. + // It may be slightly different (./foo matching example.com/foo), + // but close enough to seem redundant. + // Unwrap the error so we don't show the pattern. + err = matchErr.Err + } + } + + // Replace (possibly wrapped) *build.NoGoError with *load.NoGoError. + // The latter is more specific about the cause. + var nogoErr *build.NoGoError + if errors.As(err, &nogoErr) { + if p.Dir == "" && nogoErr.Dir != "" { + p.Dir = nogoErr.Dir + } + err = &NoGoError{Package: p} + } + + // Report the error on the importing package if the problem is with the import declaration + // for example, if the package doesn't exist or if the import path is malformed. + // On the other hand, don't include a position if the problem is with the imported package, + // for example there are no Go files (NoGoError), or there's a problem in the imported + // package's source files themselves. + // + // TODO(matloob): Perhaps make each of those the errors in the first group + // (including modload.ImportMissingError, and the corresponding + // "cannot find package %q in any of" GOPATH-mode error + // produced in build.(*Context).Import; modload.AmbiguousImportError, + // and modload.PackageNotInModuleError; and the malformed module path errors + // produced in golang.org/x/mod/module.CheckMod) implement an interface + // to make it easier to check for them? That would save us from having to + // move the modload errors into this package to avoid a package import cycle, + // and from having to export an error type for the errors produced in build. + if !isMatchErr && nogoErr != nil { + stk.Push(path) + defer stk.Pop() + } + + // Take only the first error from a scanner.ErrorList. PackageError only + // has room for one position, so we report the first error with a position + // instead of all of the errors without a position. + var pos string + if scanErr, ok := err.(scanner.ErrorList); ok && len(scanErr) > 0 { + scanPos := scanErr[0].Pos + scanPos.Filename = base.ShortPath(scanPos.Filename) + pos = scanPos.String() + err = errors.New(scanErr[0].Msg) + } + + p.Error = &PackageError{ + ImportStack: stk.Copy(), + Pos: pos, + Err: err, + } + + if path != stk.Top() { + p = setErrorPos(p, importPos) + } +} + // Resolve returns the resolved version of imports, // which should be p.TestImports or p.XTestImports, NOT p.Imports. // The imports in p.TestImports and p.XTestImports are not recursively @@ -304,19 +372,16 @@ func (p *Package) copyBuild(pp *build.Package) { // A PackageError describes an error loading information about a package. type PackageError struct { - ImportStack []string // shortest path from package named on command line to this one - Pos string // position of error - Err error // the error itself - IsImportCycle bool // the error is an import cycle - Hard bool // whether the error is soft or hard; soft errors are ignored in some places + ImportStack []string // shortest path from package named on command line to this one + Pos string // position of error + Err error // the error itself + IsImportCycle bool // the error is an import cycle + Hard bool // whether the error is soft or hard; soft errors are ignored in some places + alwaysPrintStack bool // whether to always print the ImportStack } func (p *PackageError) Error() string { - // Import cycles deserve special treatment. - if p.IsImportCycle { - return fmt.Sprintf("%s\npackage %s\n", p.Err, strings.Join(p.ImportStack, "\n\timports ")) - } - if p.Pos != "" { + if p.Pos != "" && (len(p.ImportStack) == 0 || !p.alwaysPrintStack) { // Omit import stack. The full path to the file where the error // is the most important thing. return p.Pos + ": " + p.Err.Error() @@ -328,17 +393,18 @@ func (p *PackageError) Error() string { // last path on the stack, we don't omit the path. An error like // "package A imports B: error loading C caused by B" would not be clearer // if "imports B" were omitted. - stack := p.ImportStack - var ierr ImportPathError - if len(stack) > 0 && errors.As(p.Err, &ierr) && ierr.ImportPath() == stack[len(stack)-1] { - stack = stack[:len(stack)-1] - } - if len(stack) == 0 { + if len(p.ImportStack) == 0 { return p.Err.Error() } - return "package " + strings.Join(stack, "\n\timports ") + ": " + p.Err.Error() + var optpos string + if p.Pos != "" { + optpos = "\n\t" + p.Pos + } + return "package " + strings.Join(p.ImportStack, "\n\timports ") + optpos + ": " + p.Err.Error() } +func (p *PackageError) Unwrap() error { return p.Err } + // PackageError implements MarshalJSON so that Err is marshaled as a string // and non-essential fields are omitted. func (p *PackageError) MarshalJSON() ([]byte, error) { @@ -409,6 +475,13 @@ func (s *ImportStack) Copy() []string { return append([]string{}, *s...) } +func (s *ImportStack) Top() string { + if len(*s) == 0 { + return "" + } + return (*s)[len(*s)-1] +} + // shorterThan reports whether sp is shorter than t. // We use this to record the shortest import sequence // that leads to a particular package. @@ -536,9 +609,6 @@ func loadImport(pre *preload, path, srcDir string, parent *Package, stk *ImportS panic("LoadImport called with empty package path") } - stk.Push(path) - defer stk.Pop() - var parentPath, parentRoot string parentIsStd := false if parent != nil { @@ -551,6 +621,11 @@ func loadImport(pre *preload, path, srcDir string, parent *Package, stk *ImportS pre.preloadImports(bp.Imports, bp) } if bp == nil { + if importErr, ok := err.(ImportPathError); !ok || importErr.ImportPath() != path { + // Only add path to the error's import stack if it's not already present on the error. + stk.Push(path) + defer stk.Pop() + } return &Package{ PackagePublic: PackagePublic{ ImportPath: path, @@ -565,7 +640,9 @@ func loadImport(pre *preload, path, srcDir string, parent *Package, stk *ImportS importPath := bp.ImportPath p := packageCache[importPath] if p != nil { + stk.Push(path) p = reusePackage(p, stk) + stk.Pop() } else { p = new(Package) p.Internal.Local = build.IsLocalImport(path) @@ -575,17 +652,15 @@ func loadImport(pre *preload, path, srcDir string, parent *Package, stk *ImportS // Load package. // loadPackageData may return bp != nil even if an error occurs, // in order to return partial information. - p.load(stk, bp, err) - if p.Error != nil && p.Error.Pos == "" { - p = setErrorPos(p, importPos) - } + p.load(path, stk, importPos, bp, err) if !cfg.ModulesEnabled && path != cleanImport(path) { p.Error = &PackageError{ ImportStack: stk.Copy(), - Err: fmt.Errorf("non-canonical import path: %q should be %q", path, pathpkg.Clean(path)), + Err: ImportErrorf(path, "non-canonical import path %q: should be %q", path, pathpkg.Clean(path)), } p.Incomplete = true + setErrorPos(p, importPos) } } @@ -594,7 +669,7 @@ func loadImport(pre *preload, path, srcDir string, parent *Package, stk *ImportS return setErrorPos(perr, importPos) } if mode&ResolveImport != 0 { - if perr := disallowVendor(srcDir, path, p, stk); perr != p { + if perr := disallowVendor(srcDir, path, parentPath, p, stk); perr != p { return setErrorPos(perr, importPos) } } @@ -1232,7 +1307,7 @@ func disallowInternal(srcDir string, importer *Package, importerPath string, p * // as if it were generated into the testing directory tree // (it's actually in a temporary directory outside any Go tree). // This cleans up a former kludge in passing functionality to the testing package. - if strings.HasPrefix(p.ImportPath, "testing/internal") && len(*stk) >= 2 && (*stk)[len(*stk)-2] == "testmain" { + if str.HasPathPrefix(p.ImportPath, "testing/internal") && importerPath == "testmain" { return p } @@ -1254,11 +1329,10 @@ func disallowInternal(srcDir string, importer *Package, importerPath string, p * return p } - // The stack includes p.ImportPath. - // If that's the only thing on the stack, we started + // importerPath is empty: we started // with a name given on the command line, not an // import. Anything listed on the command line is fine. - if len(*stk) == 1 { + if importerPath == "" { return p } @@ -1307,8 +1381,9 @@ func disallowInternal(srcDir string, importer *Package, importerPath string, p * // Internal is present, and srcDir is outside parent's tree. Not allowed. perr := *p perr.Error = &PackageError{ - ImportStack: stk.Copy(), - Err: ImportErrorf(p.ImportPath, "use of internal package "+p.ImportPath+" not allowed"), + alwaysPrintStack: true, + ImportStack: stk.Copy(), + Err: ImportErrorf(p.ImportPath, "use of internal package "+p.ImportPath+" not allowed"), } perr.Incomplete = true return &perr @@ -1336,16 +1411,15 @@ func findInternal(path string) (index int, ok bool) { // disallowVendor checks that srcDir is allowed to import p as path. // If the import is allowed, disallowVendor returns the original package p. // If not, it returns a new package containing just an appropriate error. -func disallowVendor(srcDir string, path string, p *Package, stk *ImportStack) *Package { - // The stack includes p.ImportPath. - // If that's the only thing on the stack, we started +func disallowVendor(srcDir string, path string, importerPath string, p *Package, stk *ImportStack) *Package { + // If the importerPath is empty, we started // with a name given on the command line, not an // import. Anything listed on the command line is fine. - if len(*stk) == 1 { + if importerPath == "" { return p } - if perr := disallowVendorVisibility(srcDir, p, stk); perr != p { + if perr := disallowVendorVisibility(srcDir, p, importerPath, stk); perr != p { return perr } @@ -1368,12 +1442,12 @@ func disallowVendor(srcDir string, path string, p *Package, stk *ImportStack) *P // is not subject to the rules, only subdirectories of vendor. // This allows people to have packages and commands named vendor, // for maximal compatibility with existing source trees. -func disallowVendorVisibility(srcDir string, p *Package, stk *ImportStack) *Package { - // The stack includes p.ImportPath. - // If that's the only thing on the stack, we started +func disallowVendorVisibility(srcDir string, p *Package, importerPath string, stk *ImportStack) *Package { + // The stack does not include p.ImportPath. + // If there's nothing on the stack, we started // with a name given on the command line, not an // import. Anything listed on the command line is fine. - if len(*stk) == 1 { + if importerPath == "" { return p } @@ -1517,7 +1591,8 @@ func (p *Package) DefaultExecName() string { // load populates p using information from bp, err, which should // be the result of calling build.Context.Import. -func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { +// stk contains the import stack, not including path itself. +func (p *Package) load(path string, stk *ImportStack, importPos []token.Position, bp *build.Package, err error) { p.copyBuild(bp) // The localPrefix is the path we interpret ./ imports relative to. @@ -1535,21 +1610,22 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { ImportStack: stk.Copy(), Err: err, } + + // Add the importer's position information if the import position exists, and + // the current package being examined is the importer. + // If we have not yet accepted package p onto the import stack, + // then the cause of the error is not within p itself: the error + // must be either in an explicit command-line argument, + // or on the importer side (indicated by a non-empty importPos). + if path != stk.Top() && len(importPos) > 0 { + p = setErrorPos(p, importPos) + } } } if err != nil { - if _, ok := err.(*build.NoGoError); ok { - err = &NoGoError{Package: p} - } p.Incomplete = true - - setError(base.ExpandScanner(err)) - if _, isScanErr := err.(scanner.ErrorList); !isScanErr { - return - } - // Fall through if there was an error parsing a file. 'go list -e' should - // still report imports and other metadata. + p.setLoadPackageDataError(err, path, stk, importPos) } useBindir := p.Name == "main" @@ -1563,6 +1639,8 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { if useBindir { // Report an error when the old code.google.com/p/go.tools paths are used. if InstallTargetDir(p) == StalePath { + // TODO(matloob): remove this branch, and StalePath itself. code.google.com/p/go is so + // old, even this code checking for it is stale now! newPath := strings.Replace(p.ImportPath, "code.google.com/p/go.", "golang.org/x/", 1) e := ImportErrorf(p.ImportPath, "the %v command has moved; use %v instead.", p.ImportPath, newPath) setError(e) @@ -1671,6 +1749,23 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { } } + // Check for case-insensitive collisions of import paths. + fold := str.ToFold(p.ImportPath) + if other := foldPath[fold]; other == "" { + foldPath[fold] = p.ImportPath + } else if other != p.ImportPath { + setError(ImportErrorf(p.ImportPath, "case-insensitive import collision: %q and %q", p.ImportPath, other)) + return + } + + if !SafeArg(p.ImportPath) { + setError(ImportErrorf(p.ImportPath, "invalid import path %q", p.ImportPath)) + return + } + + stk.Push(path) + defer stk.Pop() + // Check for case-insensitive collision of input files. // To avoid problems on case-insensitive files, we reject any package // where two different input files have equal names under a case-insensitive @@ -1699,10 +1794,6 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { setError(fmt.Errorf("invalid input directory name %q", name)) return } - if !SafeArg(p.ImportPath) { - setError(ImportErrorf(p.ImportPath, "invalid import path %q", p.ImportPath)) - return - } // Build list of imported packages and full dependency list. imports := make([]*Package, 0, len(p.Imports)) @@ -1766,15 +1857,6 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { return } - // Check for case-insensitive collisions of import paths. - fold := str.ToFold(p.ImportPath) - if other := foldPath[fold]; other == "" { - foldPath[fold] = p.ImportPath - } else if other != p.ImportPath { - setError(ImportErrorf(p.ImportPath, "case-insensitive import collision: %q and %q", p.ImportPath, other)) - return - } - if cfg.ModulesEnabled && p.Error == nil { mainPath := p.ImportPath if p.Internal.CmdlineFiles { @@ -1877,10 +1959,11 @@ func externalLinkingForced(p *Package) bool { // Some targets must use external linking even inside GOROOT. switch cfg.BuildContext.GOOS { case "android": - return true + if cfg.BuildContext.GOARCH != "arm64" { + return true + } case "darwin": - switch cfg.BuildContext.GOARCH { - case "arm", "arm64": + if cfg.BuildContext.GOARCH == "arm64" { return true } } @@ -1938,13 +2021,22 @@ func (p *Package) InternalXGoFiles() []string { // using absolute paths. "Possibly relevant" means that files are not excluded // due to build tags, but files with names beginning with . or _ are still excluded. func (p *Package) InternalAllGoFiles() []string { - var extra []string + return p.mkAbs(str.StringList(p.constraintIgnoredGoFiles(), p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles)) +} + +// constraintIgnoredGoFiles returns the list of Go files ignored for reasons +// other than having a name beginning with '.' or '_'. +func (p *Package) constraintIgnoredGoFiles() []string { + if len(p.IgnoredGoFiles) == 0 { + return nil + } + files := make([]string, 0, len(p.IgnoredGoFiles)) for _, f := range p.IgnoredGoFiles { - if f != "" && f[0] != '.' || f[0] != '_' { - extra = append(extra, f) + if f != "" && f[0] != '.' && f[0] != '_' { + files = append(files, f) } } - return p.mkAbs(str.StringList(extra, p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles)) + return files } // usesSwig reports whether the package needs to run SWIG. @@ -2038,7 +2130,7 @@ func Packages(args []string) []*Package { var pkgs []*Package for _, pkg := range PackagesAndErrors(args) { if pkg.Error != nil { - base.Errorf("can't load package: %s", pkg.Error) + base.Errorf("%v", pkg.Error) continue } pkgs = append(pkgs, pkg) @@ -2078,13 +2170,13 @@ func PackagesAndErrors(patterns []string) []*Package { for _, m := range matches { for _, pkg := range m.Pkgs { if pkg == "" { - panic(fmt.Sprintf("ImportPaths returned empty package for pattern %s", m.Pattern)) + panic(fmt.Sprintf("ImportPaths returned empty package for pattern %s", m.Pattern())) } p := loadImport(pre, pkg, base.Cwd, nil, &stk, nil, 0) - p.Match = append(p.Match, m.Pattern) + p.Match = append(p.Match, m.Pattern()) p.Internal.CmdlinePkg = true - if m.Literal { - // Note: do not set = m.Literal unconditionally + if m.IsLiteral() { + // Note: do not set = m.IsLiteral unconditionally // because maybe we'll see p matching both // a literal and also a non-literal pattern. p.Internal.CmdlinePkgLiteral = true @@ -2095,6 +2187,25 @@ func PackagesAndErrors(patterns []string) []*Package { seenPkg[p] = true pkgs = append(pkgs, p) } + + if len(m.Errs) > 0 { + // In addition to any packages that were actually resolved from the + // pattern, there was some error in resolving the pattern itself. + // Report it as a synthetic package. + p := new(Package) + p.ImportPath = m.Pattern() + // Pass an empty ImportStack and nil importPos: the error arose from a pattern, not an import. + var stk ImportStack + var importPos []token.Position + p.setLoadPackageDataError(m.Errs[0], m.Pattern(), &stk, importPos) + p.Incomplete = true + p.Match = append(p.Match, m.Pattern()) + p.Internal.CmdlinePkg = true + if m.IsLiteral() { + p.Internal.CmdlinePkgLiteral = true + } + pkgs = append(pkgs, p) + } } // Now that CmdlinePkg is set correctly, @@ -2130,7 +2241,7 @@ func PackagesForBuild(args []string) []*Package { printed := map[*PackageError]bool{} for _, pkg := range pkgs { if pkg.Error != nil { - base.Errorf("can't load package: %s", pkg.Error) + base.Errorf("%v", pkg.Error) printed[pkg.Error] = true } for _, err := range pkg.DepsErrors { @@ -2140,7 +2251,7 @@ func PackagesForBuild(args []string) []*Package { // Only print each once. if !printed[err] { printed[err] = true - base.Errorf("%s", err) + base.Errorf("%v", err) } } } @@ -2232,9 +2343,7 @@ func GoFilesPackage(gofiles []string) *Package { pkg := new(Package) pkg.Internal.Local = true pkg.Internal.CmdlineFiles = true - stk.Push("main") - pkg.load(&stk, bp, err) - stk.Pop() + pkg.load("command-line-arguments", &stk, nil, bp, err) pkg.Internal.LocalPrefix = dirToImportPath(dir) pkg.ImportPath = "command-line-arguments" pkg.Target = "" diff --git a/libgo/go/cmd/go/internal/load/test.go b/libgo/go/cmd/go/internal/load/test.go index fefc7d2e307..6d251e83583 100644 --- a/libgo/go/cmd/go/internal/load/test.go +++ b/libgo/go/cmd/go/internal/load/test.go @@ -6,7 +6,6 @@ package load import ( "bytes" - "cmd/go/internal/base" "cmd/go/internal/str" "errors" "fmt" @@ -26,6 +25,7 @@ import ( var TestMainDeps = []string{ // Dependencies for testmain. "os", + "reflect", "testing", "testing/internal/testdeps", } @@ -55,7 +55,6 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag } if len(p1.DepsErrors) > 0 { perr := p1.DepsErrors[0] - perr.Pos = "" // show full import stack err = perr break } @@ -271,7 +270,7 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * // afterward that gathers t.Cover information. t, err := loadTestFuncs(ptest) if err != nil && pmain.Error == nil { - pmain.Error = &PackageError{Err: err} + pmain.setLoadPackageDataError(err, p.ImportPath, &stk, nil) } t.Cover = cover if len(ptest.GoFiles)+len(ptest.CgoFiles) > 0 { @@ -540,7 +539,7 @@ var testFileSet = token.NewFileSet() func (t *testFuncs) load(filename, pkg string, doImport, seen *bool) error { f, err := parser.ParseFile(testFileSet, filename, nil, parser.ParseComments) if err != nil { - return base.ExpandScanner(err) + return err } for _, d := range f.Decls { n, ok := d.(*ast.FuncDecl) @@ -612,8 +611,9 @@ var testmainTmpl = lazytemplate.New("main", ` package main import ( -{{if not .TestMain}} "os" +{{if .TestMain}} + "reflect" {{end}} "testing" "testing/internal/testdeps" @@ -704,6 +704,7 @@ func main() { m := testing.MainStart(testdeps.TestDeps{}, tests, benchmarks, examples) {{with .TestMain}} {{.Package}}.{{.Name}}(m) + os.Exit(int(reflect.ValueOf(m).Elem().FieldByName("exitCode").Int())) {{else}} os.Exit(m.Run()) {{end}} diff --git a/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go b/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go index a14362bdc7d..c3e09bbab57 100644 --- a/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go +++ b/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go @@ -13,19 +13,19 @@ // or an F_OFD_SETLK command for 'fcntl', that allows for better concurrency and // does not require per-inode bookkeeping in the application. // -// TODO(bcmills): If we add a build tag for Illumos (see golang.org/issue/20603) -// then Illumos should use F_OFD_SETLK, and the resulting code would be as -// simple as filelock_unix.go. We will still need the code in this file for AIX -// or as long as Oracle Solaris provides only F_SETLK. +// TODO(golang.org/issue/35618): add a syscall.Flock binding for Illumos and +// switch it over to use filelock_unix.go. package filelock import ( "errors" "io" + "math/rand" "os" "sync" "syscall" + "time" ) type lockType int16 @@ -93,7 +93,67 @@ func lock(f File, lt lockType) (err error) { wait <- f } - err = setlkw(f.Fd(), lt) + // Spurious EDEADLK errors arise on platforms that compute deadlock graphs at + // the process, rather than thread, level. Consider processes P and Q, with + // threads P.1, P.2, and Q.3. The following trace is NOT a deadlock, but will be + // reported as a deadlock on systems that consider only process granularity: + // + // P.1 locks file A. + // Q.3 locks file B. + // Q.3 blocks on file A. + // P.2 blocks on file B. (This is erroneously reported as a deadlock.) + // P.1 unlocks file A. + // Q.3 unblocks and locks file A. + // Q.3 unlocks files A and B. + // P.2 unblocks and locks file B. + // P.2 unlocks file B. + // + // These spurious errors were observed in practice on AIX and Solaris in + // cmd/go: see https://golang.org/issue/32817. + // + // We work around this bug by treating EDEADLK as always spurious. If there + // really is a lock-ordering bug between the interacting processes, it will + // become a livelock instead, but that's not appreciably worse than if we had + // a proper flock implementation (which generally does not even attempt to + // diagnose deadlocks). + // + // In the above example, that changes the trace to: + // + // P.1 locks file A. + // Q.3 locks file B. + // Q.3 blocks on file A. + // P.2 spuriously fails to lock file B and goes to sleep. + // P.1 unlocks file A. + // Q.3 unblocks and locks file A. + // Q.3 unlocks files A and B. + // P.2 wakes up and locks file B. + // P.2 unlocks file B. + // + // We know that the retry loop will not introduce a *spurious* livelock + // because, according to the POSIX specification, EDEADLK is only to be + // returned when “the lock is blocked by a lock from another process”. + // If that process is blocked on some lock that we are holding, then the + // resulting livelock is due to a real deadlock (and would manifest as such + // when using, for example, the flock implementation of this package). + // If the other process is *not* blocked on some other lock that we are + // holding, then it will eventually release the requested lock. + + nextSleep := 1 * time.Millisecond + const maxSleep = 500 * time.Millisecond + for { + err = setlkw(f.Fd(), lt) + if err != syscall.EDEADLK { + break + } + time.Sleep(nextSleep) + + nextSleep += nextSleep + if nextSleep > maxSleep { + nextSleep = maxSleep + } + // Apply 10% jitter to avoid synchronizing collisions when we finally unblock. + nextSleep += time.Duration((0.1*rand.Float64() - 0.05) * float64(nextSleep)) + } if err != nil { unlock(f) diff --git a/libgo/go/cmd/go/internal/lockedfile/lockedfile_test.go b/libgo/go/cmd/go/internal/lockedfile/lockedfile_test.go index 8f7a7d5604a..416c69d83bc 100644 --- a/libgo/go/cmd/go/internal/lockedfile/lockedfile_test.go +++ b/libgo/go/cmd/go/internal/lockedfile/lockedfile_test.go @@ -8,8 +8,11 @@ package lockedfile_test import ( + "fmt" + "internal/testenv" "io/ioutil" "os" + "os/exec" "path/filepath" "testing" "time" @@ -172,3 +175,98 @@ func TestCanLockExistingFile(t *testing.T) { f.Close() wait(t) } + +// TestSpuriousEDEADLK verifies that the spurious EDEADLK reported in +// https://golang.org/issue/32817 no longer occurs. +func TestSpuriousEDEADLK(t *testing.T) { + // P.1 locks file A. + // Q.3 locks file B. + // Q.3 blocks on file A. + // P.2 blocks on file B. (Spurious EDEADLK occurs here.) + // P.1 unlocks file A. + // Q.3 unblocks and locks file A. + // Q.3 unlocks files A and B. + // P.2 unblocks and locks file B. + // P.2 unlocks file B. + + testenv.MustHaveExec(t) + + dirVar := t.Name() + "DIR" + + if dir := os.Getenv(dirVar); dir != "" { + // Q.3 locks file B. + b, err := lockedfile.Edit(filepath.Join(dir, "B")) + if err != nil { + t.Fatal(err) + } + defer b.Close() + + if err := ioutil.WriteFile(filepath.Join(dir, "locked"), []byte("ok"), 0666); err != nil { + t.Fatal(err) + } + + // Q.3 blocks on file A. + a, err := lockedfile.Edit(filepath.Join(dir, "A")) + // Q.3 unblocks and locks file A. + if err != nil { + t.Fatal(err) + } + defer a.Close() + + // Q.3 unlocks files A and B. + return + } + + dir, remove := mustTempDir(t) + defer remove() + + // P.1 locks file A. + a, err := lockedfile.Edit(filepath.Join(dir, "A")) + if err != nil { + t.Fatal(err) + } + + cmd := exec.Command(os.Args[0], "-test.run="+t.Name()) + cmd.Env = append(os.Environ(), fmt.Sprintf("%s=%s", dirVar, dir)) + + qDone := make(chan struct{}) + waitQ := mustBlock(t, "Edit A and B in subprocess", func() { + out, err := cmd.CombinedOutput() + if err != nil { + t.Errorf("%v:\n%s", err, out) + } + close(qDone) + }) + + // Wait until process Q has either failed or locked file B. + // Otherwise, P.2 might not block on file B as intended. +locked: + for { + if _, err := os.Stat(filepath.Join(dir, "locked")); !os.IsNotExist(err) { + break locked + } + select { + case <-qDone: + break locked + case <-time.After(1 * time.Millisecond): + } + } + + waitP2 := mustBlock(t, "Edit B", func() { + // P.2 blocks on file B. (Spurious EDEADLK occurs here.) + b, err := lockedfile.Edit(filepath.Join(dir, "B")) + // P.2 unblocks and locks file B. + if err != nil { + t.Error(err) + return + } + // P.2 unlocks file B. + b.Close() + }) + + // P.1 unlocks file A. + a.Close() + + waitQ(t) + waitP2(t) +} diff --git a/libgo/go/cmd/go/internal/modcmd/download.go b/libgo/go/cmd/go/internal/modcmd/download.go index 7d5294dcd00..584434935b4 100644 --- a/libgo/go/cmd/go/internal/modcmd/download.go +++ b/libgo/go/cmd/go/internal/modcmd/download.go @@ -24,7 +24,8 @@ var cmdDownload = &base.Command{ Long: ` Download downloads the named modules, which can be module patterns selecting dependencies of the main module or module queries of the form path@version. -With no arguments, download applies to all dependencies of the main module. +With no arguments, download applies to all dependencies of the main module +(equivalent to 'go mod download all'). The go command will automatically download modules as needed during ordinary execution. The "go mod download" command is useful mainly for pre-filling diff --git a/libgo/go/cmd/go/internal/modcmd/vendor.go b/libgo/go/cmd/go/internal/modcmd/vendor.go index 0c00d1222e0..8509ceb7a8b 100644 --- a/libgo/go/cmd/go/internal/modcmd/vendor.go +++ b/libgo/go/cmd/go/internal/modcmd/vendor.go @@ -123,6 +123,11 @@ func runVendor(cmd *base.Command, args []string) { fmt.Fprintf(os.Stderr, "go: no dependencies to vendor\n") return } + + if err := os.MkdirAll(vdir, 0777); err != nil { + base.Fatalf("go mod vendor: %v", err) + } + if err := ioutil.WriteFile(filepath.Join(vdir, "modules.txt"), buf.Bytes(), 0666); err != nil { base.Fatalf("go mod vendor: %v", err) } diff --git a/libgo/go/cmd/go/internal/modcmd/verify.go b/libgo/go/cmd/go/internal/modcmd/verify.go index ac3f1351c87..b7fd7fa8e01 100644 --- a/libgo/go/cmd/go/internal/modcmd/verify.go +++ b/libgo/go/cmd/go/internal/modcmd/verify.go @@ -10,6 +10,7 @@ import ( "fmt" "io/ioutil" "os" + "runtime" "cmd/go/internal/base" "cmd/go/internal/cfg" @@ -52,17 +53,41 @@ func runVerify(cmd *base.Command, args []string) { base.Fatalf("go: cannot find main module; see 'go help modules'") } } + + // Only verify up to GOMAXPROCS zips at once. + type token struct{} + sem := make(chan token, runtime.GOMAXPROCS(0)) + + // Use a slice of result channels, so that the output is deterministic. + mods := modload.LoadBuildList()[1:] + errsChans := make([]<-chan []error, len(mods)) + + for i, mod := range mods { + sem <- token{} + errsc := make(chan []error, 1) + errsChans[i] = errsc + mod := mod // use a copy to avoid data races + go func() { + errsc <- verifyMod(mod) + <-sem + }() + } + ok := true - for _, mod := range modload.LoadBuildList()[1:] { - ok = verifyMod(mod) && ok + for _, errsc := range errsChans { + errs := <-errsc + for _, err := range errs { + base.Errorf("%s", err) + ok = false + } } if ok { fmt.Printf("all modules verified\n") } } -func verifyMod(mod module.Version) bool { - ok := true +func verifyMod(mod module.Version) []error { + var errs []error zip, zipErr := modfetch.CachePath(mod, "zip") if zipErr == nil { _, zipErr = os.Stat(zip) @@ -73,10 +98,10 @@ func verifyMod(mod module.Version) bool { if zipErr != nil && errors.Is(zipErr, os.ErrNotExist) && dirErr != nil && errors.Is(dirErr, os.ErrNotExist) { // Nothing downloaded yet. Nothing to verify. - return true + return nil } - base.Errorf("%s %s: missing ziphash: %v", mod.Path, mod.Version, err) - return false + errs = append(errs, fmt.Errorf("%s %s: missing ziphash: %v", mod.Path, mod.Version, err)) + return errs } h := string(bytes.TrimSpace(data)) @@ -85,11 +110,10 @@ func verifyMod(mod module.Version) bool { } else { hZ, err := dirhash.HashZip(zip, dirhash.DefaultHash) if err != nil { - base.Errorf("%s %s: %v", mod.Path, mod.Version, err) - return false + errs = append(errs, fmt.Errorf("%s %s: %v", mod.Path, mod.Version, err)) + return errs } else if hZ != h { - base.Errorf("%s %s: zip has been modified (%v)", mod.Path, mod.Version, zip) - ok = false + errs = append(errs, fmt.Errorf("%s %s: zip has been modified (%v)", mod.Path, mod.Version, zip)) } } if dirErr != nil && errors.Is(dirErr, os.ErrNotExist) { @@ -98,13 +122,12 @@ func verifyMod(mod module.Version) bool { hD, err := dirhash.HashDir(dir, mod.Path+"@"+mod.Version, dirhash.DefaultHash) if err != nil { - base.Errorf("%s %s: %v", mod.Path, mod.Version, err) - return false + errs = append(errs, fmt.Errorf("%s %s: %v", mod.Path, mod.Version, err)) + return errs } if hD != h { - base.Errorf("%s %s: dir has been modified (%v)", mod.Path, mod.Version, dir) - ok = false + errs = append(errs, fmt.Errorf("%s %s: dir has been modified (%v)", mod.Path, mod.Version, dir)) } } - return ok + return errs } diff --git a/libgo/go/cmd/go/internal/modconv/convert_test.go b/libgo/go/cmd/go/internal/modconv/convert_test.go index a2a26019677..a04a13b14f5 100644 --- a/libgo/go/cmd/go/internal/modconv/convert_test.go +++ b/libgo/go/cmd/go/internal/modconv/convert_test.go @@ -18,7 +18,6 @@ import ( "cmd/go/internal/cfg" "cmd/go/internal/modfetch" - "cmd/go/internal/modfetch/codehost" "golang.org/x/mod/modfile" "golang.org/x/mod/module" @@ -42,8 +41,7 @@ func testMain(m *testing.M) int { log.Fatal(err) } defer os.RemoveAll(dir) - modfetch.PkgMod = filepath.Join(dir, "pkg/mod") - codehost.WorkRoot = filepath.Join(dir, "codework") + cfg.GOMODCACHE = filepath.Join(dir, "pkg/mod") return m.Run() } diff --git a/libgo/go/cmd/go/internal/modfetch/cache.go b/libgo/go/cmd/go/internal/modfetch/cache.go index d6ff068e7bc..e3074b775e6 100644 --- a/libgo/go/cmd/go/internal/modfetch/cache.go +++ b/libgo/go/cmd/go/internal/modfetch/cache.go @@ -26,17 +26,17 @@ import ( "golang.org/x/mod/semver" ) -var PkgMod string // $GOPATH/pkg/mod; set by package modload - func cacheDir(path string) (string, error) { - if PkgMod == "" { - return "", fmt.Errorf("internal error: modfetch.PkgMod not set") + if cfg.GOMODCACHE == "" { + // modload.Init exits if GOPATH[0] is empty, and cfg.GOMODCACHE + // is set to GOPATH[0]/pkg/mod if GOMODCACHE is empty, so this should never happen. + return "", fmt.Errorf("internal error: cfg.GOMODCACHE not set") } enc, err := module.EscapePath(path) if err != nil { return "", err } - return filepath.Join(PkgMod, "cache/download", enc, "/@v"), nil + return filepath.Join(cfg.GOMODCACHE, "cache/download", enc, "/@v"), nil } func CachePath(m module.Version, suffix string) (string, error) { @@ -63,8 +63,10 @@ func CachePath(m module.Version, suffix string) (string, error) { // along with the directory if the directory does not exist or if the directory // is not completely populated. func DownloadDir(m module.Version) (string, error) { - if PkgMod == "" { - return "", fmt.Errorf("internal error: modfetch.PkgMod not set") + if cfg.GOMODCACHE == "" { + // modload.Init exits if GOPATH[0] is empty, and cfg.GOMODCACHE + // is set to GOPATH[0]/pkg/mod if GOMODCACHE is empty, so this should never happen. + return "", fmt.Errorf("internal error: cfg.GOMODCACHE not set") } enc, err := module.EscapePath(m.Path) if err != nil { @@ -81,7 +83,7 @@ func DownloadDir(m module.Version) (string, error) { return "", err } - dir := filepath.Join(PkgMod, enc+"@"+encVer) + dir := filepath.Join(cfg.GOMODCACHE, enc+"@"+encVer) if fi, err := os.Stat(dir); os.IsNotExist(err) { return dir, err } else if err != nil { @@ -131,11 +133,13 @@ func lockVersion(mod module.Version) (unlock func(), err error) { // user's working directory. // If err is nil, the caller MUST eventually call the unlock function. func SideLock() (unlock func(), err error) { - if PkgMod == "" { - base.Fatalf("go: internal error: modfetch.PkgMod not set") + if cfg.GOMODCACHE == "" { + // modload.Init exits if GOPATH[0] is empty, and cfg.GOMODCACHE + // is set to GOPATH[0]/pkg/mod if GOMODCACHE is empty, so this should never happen. + base.Fatalf("go: internal error: cfg.GOMODCACHE not set") } - path := filepath.Join(PkgMod, "cache", "lock") + path := filepath.Join(cfg.GOMODCACHE, "cache", "lock") if err := os.MkdirAll(filepath.Dir(path), 0777); err != nil { return nil, fmt.Errorf("failed to create cache directory: %w", err) } @@ -456,7 +460,7 @@ func readDiskStat(path, rev string) (file string, info *RevInfo, err error) { // just to find out about a commit we already know about // (and have cached under its pseudo-version). func readDiskStatByHash(path, rev string) (file string, info *RevInfo, err error) { - if PkgMod == "" { + if cfg.GOMODCACHE == "" { // Do not download to current directory. return "", nil, errNotCached } diff --git a/libgo/go/cmd/go/internal/modfetch/codehost/codehost.go b/libgo/go/cmd/go/internal/modfetch/codehost/codehost.go index 5867288c966..d85eddf767b 100644 --- a/libgo/go/cmd/go/internal/modfetch/codehost/codehost.go +++ b/libgo/go/cmd/go/internal/modfetch/codehost/codehost.go @@ -153,15 +153,11 @@ func ShortenSHA1(rev string) string { return rev } -// WorkRoot is the root of the cached work directory. -// It is set by cmd/go/internal/modload.InitMod. -var WorkRoot string - // WorkDir returns the name of the cached work directory to use for the // given repository type and name. func WorkDir(typ, name string) (dir, lockfile string, err error) { - if WorkRoot == "" { - return "", "", fmt.Errorf("codehost.WorkRoot not set") + if cfg.GOMODCACHE == "" { + return "", "", fmt.Errorf("neither GOPATH nor GOMODCACHE are set") } // We name the work directory for the SHA256 hash of the type and name. @@ -173,7 +169,7 @@ func WorkDir(typ, name string) (dir, lockfile string, err error) { return "", "", fmt.Errorf("codehost.WorkDir: type cannot contain colon") } key := typ + ":" + name - dir = filepath.Join(WorkRoot, fmt.Sprintf("%x", sha256.Sum256([]byte(key)))) + dir = filepath.Join(cfg.GOMODCACHE, "cache/vcs", fmt.Sprintf("%x", sha256.Sum256([]byte(key)))) if cfg.BuildX { fmt.Fprintf(os.Stderr, "mkdir -p %s # %s %s\n", filepath.Dir(dir), typ, name) diff --git a/libgo/go/cmd/go/internal/modfetch/codehost/git.go b/libgo/go/cmd/go/internal/modfetch/codehost/git.go index f08df512f02..31921324a7d 100644 --- a/libgo/go/cmd/go/internal/modfetch/codehost/git.go +++ b/libgo/go/cmd/go/internal/modfetch/codehost/git.go @@ -27,11 +27,6 @@ import ( "golang.org/x/mod/semver" ) -// GitRepo returns the code repository at the given Git remote reference. -func GitRepo(remote string) (Repo, error) { - return newGitRepoCached(remote, false) -} - // LocalGitRepo is like Repo but accepts both Git remote references // and paths to repositories on the local file system. func LocalGitRepo(remote string) (Repo, error) { diff --git a/libgo/go/cmd/go/internal/modfetch/codehost/git_test.go b/libgo/go/cmd/go/internal/modfetch/codehost/git_test.go index cc32a1eb51c..ba27c70f5a0 100644 --- a/libgo/go/cmd/go/internal/modfetch/codehost/git_test.go +++ b/libgo/go/cmd/go/internal/modfetch/codehost/git_test.go @@ -57,7 +57,6 @@ func testMain(m *testing.M) int { log.Fatal(err) } defer os.RemoveAll(dir) - WorkRoot = dir if testenv.HasExternalNetwork() && testenv.HasExec() { // Clone gitrepo1 into a local directory. diff --git a/libgo/go/cmd/go/internal/modfetch/codehost/shell.go b/libgo/go/cmd/go/internal/modfetch/codehost/shell.go index 835bc53c0dd..2762c557203 100644 --- a/libgo/go/cmd/go/internal/modfetch/codehost/shell.go +++ b/libgo/go/cmd/go/internal/modfetch/codehost/shell.go @@ -20,6 +20,7 @@ import ( "strings" "time" + "cmd/go/internal/cfg" "cmd/go/internal/modfetch/codehost" ) @@ -29,7 +30,7 @@ func usage() { } func main() { - codehost.WorkRoot = "/tmp/vcswork" + cfg.GOMODCACHE = "/tmp/vcswork" log.SetFlags(0) log.SetPrefix("shell: ") flag.Usage = usage diff --git a/libgo/go/cmd/go/internal/modfetch/coderepo.go b/libgo/go/cmd/go/internal/modfetch/coderepo.go index d1d24a40c96..d043903336c 100644 --- a/libgo/go/cmd/go/internal/modfetch/coderepo.go +++ b/libgo/go/cmd/go/internal/modfetch/coderepo.go @@ -563,7 +563,7 @@ func (r *codeRepo) validatePseudoVersion(info *codehost.RevInfo, version string) return err } if !t.Equal(info.Time.Truncate(time.Second)) { - return fmt.Errorf("does not match version-control timestamp (%s)", info.Time.UTC().Format(time.RFC3339)) + return fmt.Errorf("does not match version-control timestamp (expected %s)", info.Time.UTC().Format(pseudoVersionTimestampFormat)) } tagPrefix := "" @@ -1012,28 +1012,3 @@ func hasPathPrefix(s, prefix string) bool { return s[len(prefix)] == '/' && s[:len(prefix)] == prefix } } - -func isVendoredPackage(name string) bool { - var i int - if strings.HasPrefix(name, "vendor/") { - i += len("vendor/") - } else if j := strings.Index(name, "/vendor/"); j >= 0 { - // This offset looks incorrect; this should probably be - // - // i = j + len("/vendor/") - // - // (See https://golang.org/issue/31562.) - // - // Unfortunately, we can't fix it without invalidating checksums. - // Fortunately, the error appears to be strictly conservative: we'll retain - // vendored packages that we should have pruned, but we won't prune - // non-vendored packages that we should have retained. - // - // Since this defect doesn't seem to break anything, it's not worth fixing - // for now. - i += len("/vendor/") - } else { - return false - } - return strings.Contains(name[i:], "/") -} diff --git a/libgo/go/cmd/go/internal/modfetch/coderepo_test.go b/libgo/go/cmd/go/internal/modfetch/coderepo_test.go index 39830948fb0..f69c193b86c 100644 --- a/libgo/go/cmd/go/internal/modfetch/coderepo_test.go +++ b/libgo/go/cmd/go/internal/modfetch/coderepo_test.go @@ -44,7 +44,7 @@ func testMain(m *testing.M) int { } defer os.RemoveAll(dir) - codehost.WorkRoot = dir + cfg.GOMODCACHE = dir return m.Run() } diff --git a/libgo/go/cmd/go/internal/modfetch/fetch.go b/libgo/go/cmd/go/internal/modfetch/fetch.go index aadf8834574..fd7a5cef831 100644 --- a/libgo/go/cmd/go/internal/modfetch/fetch.go +++ b/libgo/go/cmd/go/internal/modfetch/fetch.go @@ -35,9 +35,10 @@ var downloadCache par.Cache // local download cache and returns the name of the directory // corresponding to the root of the module's file tree. func Download(mod module.Version) (dir string, err error) { - if PkgMod == "" { - // Do not download to current directory. - return "", fmt.Errorf("missing modfetch.PkgMod") + if cfg.GOMODCACHE == "" { + // modload.Init exits if GOPATH[0] is empty, and cfg.GOMODCACHE + // is set to GOPATH[0]/pkg/mod if GOMODCACHE is empty, so this should never happen. + base.Fatalf("go: internal error: cfg.GOMODCACHE not set") } // The par.Cache here avoids duplicate work. @@ -57,11 +58,10 @@ func Download(mod module.Version) (dir string, err error) { } func download(mod module.Version) (dir string, err error) { - // If the directory exists, and no .partial file exists, - // the module has already been completely extracted. - // .partial files may be created when future versions of cmd/go - // extract module zip directories in place instead of extracting - // to a random temporary directory and renaming. + // If the directory exists, and no .partial file exists, the module has + // already been completely extracted. .partial files may be created when a + // module zip directory is extracted in place instead of being extracted to a + // temporary directory and renamed. dir, err = DownloadDir(mod) if err == nil { return dir, nil @@ -115,31 +115,61 @@ func download(mod module.Version) (dir string, err error) { return "", err } - // Extract the zip file to a temporary directory, then rename it to the - // final path. That way, we can use the existence of the source directory to - // signal that it has been extracted successfully, and if someone deletes - // the entire directory (e.g. as an attempt to prune out file corruption) - // the module cache will still be left in a recoverable state. + // Extract the module zip directory. + // + // By default, we extract to a temporary directory, then atomically rename to + // its final location. We use the existence of the source directory to signal + // that it has been extracted successfully (see DownloadDir). If someone + // deletes the entire directory (e.g., as an attempt to prune out file + // corruption), the module cache will still be left in a recoverable + // state. + // + // Unfortunately, os.Rename may fail with ERROR_ACCESS_DENIED on Windows if + // another process opens files in the temporary directory. This is partially + // mitigated by using robustio.Rename, which retries os.Rename for a short + // time. + // + // To avoid this error completely, if unzipInPlace is set, we instead create a + // .partial file (indicating the directory isn't fully extracted), then we + // extract the directory at its final location, then we delete the .partial + // file. This is not the default behavior because older versions of Go may + // simply stat the directory to check whether it exists without looking for a + // .partial file. If multiple versions run concurrently, the older version may + // assume a partially extracted directory is complete. + // TODO(golang.org/issue/36568): when these older versions are no longer + // supported, remove the old default behavior and the unzipInPlace flag. if err := os.MkdirAll(parentDir, 0777); err != nil { return "", err } - tmpDir, err := ioutil.TempDir(parentDir, tmpPrefix) - if err != nil { - return "", err - } - defer func() { + + if unzipInPlace { + if err := ioutil.WriteFile(partialPath, nil, 0666); err != nil { + return "", err + } + if err := modzip.Unzip(dir, mod, zipfile); err != nil { + fmt.Fprintf(os.Stderr, "-> %s\n", err) + if rmErr := RemoveAll(dir); rmErr == nil { + os.Remove(partialPath) + } + return "", err + } + if err := os.Remove(partialPath); err != nil { + return "", err + } + } else { + tmpDir, err := ioutil.TempDir(parentDir, tmpPrefix) if err != nil { + return "", err + } + if err := modzip.Unzip(tmpDir, mod, zipfile); err != nil { + fmt.Fprintf(os.Stderr, "-> %s\n", err) RemoveAll(tmpDir) + return "", err + } + if err := robustio.Rename(tmpDir, dir); err != nil { + RemoveAll(tmpDir) + return "", err } - }() - - if err := modzip.Unzip(tmpDir, mod, zipfile); err != nil { - fmt.Fprintf(os.Stderr, "-> %s\n", err) - return "", err - } - - if err := robustio.Rename(tmpDir, dir); err != nil { - return "", err } if !cfg.ModCacheRW { @@ -150,6 +180,17 @@ func download(mod module.Version) (dir string, err error) { return dir, nil } +var unzipInPlace bool + +func init() { + for _, f := range strings.Split(os.Getenv("GODEBUG"), ",") { + if f == "modcacheunzipinplace=1" { + unzipInPlace = true + break + } + } +} + var downloadZipCache par.Cache // DownloadZip downloads the specific module version to the @@ -321,7 +362,7 @@ func RemoveAll(dir string) error { } return nil }) - return os.RemoveAll(dir) + return robustio.RemoveAll(dir) } var GoSumFile string // path to go.sum; set by package modload @@ -416,7 +457,7 @@ func readGoSum(dst map[module.Version][]string, file string, data []byte) error // checkMod checks the given module's checksum. func checkMod(mod module.Version) { - if PkgMod == "" { + if cfg.GOMODCACHE == "" { // Do not use current directory. return } @@ -473,6 +514,7 @@ func checkModSum(mod module.Version, h string) error { goSum.mu.Lock() inited, err := initGoSum() if err != nil { + goSum.mu.Unlock() return err } done := inited && haveModSumLocked(mod, h) @@ -553,7 +595,7 @@ func checkSumDB(mod module.Version, h string) error { // Sum returns the checksum for the downloaded copy of the given module, // if present in the download cache. func Sum(mod module.Version) string { - if PkgMod == "" { + if cfg.GOMODCACHE == "" { // Do not use current directory. return "" } diff --git a/libgo/go/cmd/go/internal/modfetch/proxy.go b/libgo/go/cmd/go/internal/modfetch/proxy.go index dcea71adb3a..1c35d0b99bd 100644 --- a/libgo/go/cmd/go/internal/modfetch/proxy.go +++ b/libgo/go/cmd/go/internal/modfetch/proxy.go @@ -101,27 +101,51 @@ cached module versions with GOPROXY=https://example.com/proxy. var proxyOnce struct { sync.Once - list []string + list []proxySpec err error } -func proxyURLs() ([]string, error) { +type proxySpec struct { + // url is the proxy URL or one of "off", "direct", "noproxy". + url string + + // fallBackOnError is true if a request should be attempted on the next proxy + // in the list after any error from this proxy. If fallBackOnError is false, + // the request will only be attempted on the next proxy if the error is + // equivalent to os.ErrNotFound, which is true for 404 and 410 responses. + fallBackOnError bool +} + +func proxyList() ([]proxySpec, error) { proxyOnce.Do(func() { if cfg.GONOPROXY != "" && cfg.GOPROXY != "direct" { - proxyOnce.list = append(proxyOnce.list, "noproxy") + proxyOnce.list = append(proxyOnce.list, proxySpec{url: "noproxy"}) } - for _, proxyURL := range strings.Split(cfg.GOPROXY, ",") { - proxyURL = strings.TrimSpace(proxyURL) - if proxyURL == "" { + + goproxy := cfg.GOPROXY + for goproxy != "" { + var url string + fallBackOnError := false + if i := strings.IndexAny(goproxy, ",|"); i >= 0 { + url = goproxy[:i] + fallBackOnError = goproxy[i] == '|' + goproxy = goproxy[i+1:] + } else { + url = goproxy + goproxy = "" + } + + url = strings.TrimSpace(url) + if url == "" { continue } - if proxyURL == "off" { + if url == "off" { // "off" always fails hard, so can stop walking list. - proxyOnce.list = append(proxyOnce.list, "off") + proxyOnce.list = append(proxyOnce.list, proxySpec{url: "off"}) break } - if proxyURL == "direct" { - proxyOnce.list = append(proxyOnce.list, "direct") + if url == "direct" { + proxyOnce.list = append(proxyOnce.list, proxySpec{url: "direct"}) // For now, "direct" is the end of the line. We may decide to add some // sort of fallback behavior for them in the future, so ignore // subsequent entries for forward-compatibility. @@ -131,18 +155,29 @@ func proxyURLs() ([]string, error) { // Single-word tokens are reserved for built-in behaviors, and anything // containing the string ":/" or matching an absolute file path must be a // complete URL. For all other paths, implicitly add "https://". - if strings.ContainsAny(proxyURL, ".:/") && !strings.Contains(proxyURL, ":/") && !filepath.IsAbs(proxyURL) && !path.IsAbs(proxyURL) { - proxyURL = "https://" + proxyURL + if strings.ContainsAny(url, ".:/") && !strings.Contains(url, ":/") && !filepath.IsAbs(url) && !path.IsAbs(url) { + url = "https://" + url } // Check that newProxyRepo accepts the URL. // It won't do anything with the path. - _, err := newProxyRepo(proxyURL, "golang.org/x/text") - if err != nil { + if _, err := newProxyRepo(url, "golang.org/x/text"); err != nil { proxyOnce.err = err return } - proxyOnce.list = append(proxyOnce.list, proxyURL) + + proxyOnce.list = append(proxyOnce.list, proxySpec{ + url: url, + fallBackOnError: fallBackOnError, + }) + } + + if len(proxyOnce.list) == 0 || + len(proxyOnce.list) == 1 && proxyOnce.list[0].url == "noproxy" { + // There were no proxies, other than the implicit "noproxy" added when + // GONOPROXY is set. This can happen if GOPROXY is a non-empty string + // like "," or " ". + proxyOnce.err = fmt.Errorf("GOPROXY list is not the empty string, but contains no entries") } }) @@ -150,44 +185,60 @@ func proxyURLs() ([]string, error) { } // TryProxies iterates f over each configured proxy (including "noproxy" and -// "direct" if applicable) until f returns an error that is not -// equivalent to os.ErrNotExist. +// "direct" if applicable) until f returns no error or until f returns an +// error that is not equivalent to os.ErrNotExist on a proxy configured +// not to fall back on errors. // // TryProxies then returns that final error. // // If GOPROXY is set to "off", TryProxies invokes f once with the argument // "off". func TryProxies(f func(proxy string) error) error { - proxies, err := proxyURLs() + proxies, err := proxyList() if err != nil { return err } if len(proxies) == 0 { - return f("off") + panic("GOPROXY list is empty") } - var lastAttemptErr error + // We try to report the most helpful error to the user. "direct" and "noproxy" + // errors are best, followed by proxy errors other than ErrNotExist, followed + // by ErrNotExist. + // + // Note that errProxyOff, errNoproxy, and errUseProxy are equivalent to + // ErrNotExist. errUseProxy should only be returned if "noproxy" is the only + // proxy. errNoproxy should never be returned, since there should always be a + // more useful error from "noproxy" first. + const ( + notExistRank = iota + proxyRank + directRank + ) + var bestErr error + bestErrRank := notExistRank for _, proxy := range proxies { - err = f(proxy) - if !errors.Is(err, os.ErrNotExist) { - lastAttemptErr = err - break + err := f(proxy.url) + if err == nil { + return nil + } + isNotExistErr := errors.Is(err, os.ErrNotExist) + + if proxy.url == "direct" || (proxy.url == "noproxy" && err != errUseProxy) { + bestErr = err + bestErrRank = directRank + } else if bestErrRank <= proxyRank && !isNotExistErr { + bestErr = err + bestErrRank = proxyRank + } else if bestErrRank == notExistRank { + bestErr = err } - // The error indicates that the module does not exist. - // In general we prefer to report the last such error, - // because it indicates the error that occurs after all other - // options have been exhausted. - // - // However, for modules in the NOPROXY list, the most useful error occurs - // first (with proxy set to "noproxy"), and the subsequent errors are all - // errNoProxy (which is not particularly helpful). Do not overwrite a more - // useful error with errNoproxy. - if lastAttemptErr == nil || !errors.Is(err, errNoproxy) { - lastAttemptErr = err + if !proxy.fallBackOnError && !isNotExistErr { + break } } - return lastAttemptErr + return bestErr } type proxyRepo struct { @@ -205,12 +256,12 @@ func newProxyRepo(baseURL, path string) (Repo, error) { // ok case "file": if *base != (url.URL{Scheme: base.Scheme, Path: base.Path, RawPath: base.RawPath}) { - return nil, fmt.Errorf("invalid file:// proxy URL with non-path elements: %s", web.Redacted(base)) + return nil, fmt.Errorf("invalid file:// proxy URL with non-path elements: %s", base.Redacted()) } case "": - return nil, fmt.Errorf("invalid proxy URL missing scheme: %s", web.Redacted(base)) + return nil, fmt.Errorf("invalid proxy URL missing scheme: %s", base.Redacted()) default: - return nil, fmt.Errorf("invalid proxy URL scheme (must be https, http, file): %s", web.Redacted(base)) + return nil, fmt.Errorf("invalid proxy URL scheme (must be https, http, file): %s", base.Redacted()) } enc, err := module.EscapePath(path) diff --git a/libgo/go/cmd/go/internal/modfetch/pseudo.go b/libgo/go/cmd/go/internal/modfetch/pseudo.go index 57dee11d071..20c0b060ab4 100644 --- a/libgo/go/cmd/go/internal/modfetch/pseudo.go +++ b/libgo/go/cmd/go/internal/modfetch/pseudo.go @@ -48,6 +48,8 @@ import ( var pseudoVersionRE = lazyregexp.New(`^v[0-9]+\.(0\.0-|\d+\.\d+-([^+]*\.)?0\.)\d{14}-[A-Za-z0-9]+(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$`) +const pseudoVersionTimestampFormat = "20060102150405" + // PseudoVersion returns a pseudo-version for the given major version ("v1") // preexisting older tagged version ("" or "v1.2.3" or "v1.2.3-pre"), revision time, // and revision identifier (usually a 12-byte commit hash prefix). @@ -55,7 +57,7 @@ func PseudoVersion(major, older string, t time.Time, rev string) string { if major == "" { major = "v0" } - segment := fmt.Sprintf("%s-%s", t.UTC().Format("20060102150405"), rev) + segment := fmt.Sprintf("%s-%s", t.UTC().Format(pseudoVersionTimestampFormat), rev) build := semver.Build(older) older = semver.Canonical(older) if older == "" { diff --git a/libgo/go/cmd/go/internal/modfetch/sumdb.go b/libgo/go/cmd/go/internal/modfetch/sumdb.go index 1ed71dfb85c..7973f474268 100644 --- a/libgo/go/cmd/go/internal/modfetch/sumdb.go +++ b/libgo/go/cmd/go/internal/modfetch/sumdb.go @@ -26,6 +26,7 @@ import ( "cmd/go/internal/lockedfile" "cmd/go/internal/str" "cmd/go/internal/web" + "golang.org/x/mod/module" "golang.org/x/mod/sumdb" "golang.org/x/mod/sumdb/note" @@ -130,7 +131,7 @@ func (c *dbClient) ReadRemote(path string) ([]byte, error) { targ := web.Join(c.base, path) data, err := web.GetBytes(targ) if false { - fmt.Fprintf(os.Stderr, "%.3fs %s\n", time.Since(start).Seconds(), web.Redacted(targ)) + fmt.Fprintf(os.Stderr, "%.3fs %s\n", time.Since(start).Seconds(), targ.Redacted()) } return data, err } @@ -146,49 +147,50 @@ func (c *dbClient) initBase() { } // Try proxies in turn until we find out how to connect to this database. - urls, err := proxyURLs() - if err != nil { - c.baseErr = err - return - } - for _, proxyURL := range urls { - if proxyURL == "noproxy" { - continue - } - if proxyURL == "direct" || proxyURL == "off" { - break - } - proxy, err := url.Parse(proxyURL) - if err != nil { - c.baseErr = err - return - } - // Quoting https://golang.org/design/25530-sumdb#proxying-a-checksum-database: - // - // Before accessing any checksum database URL using a proxy, - // the proxy client should first fetch /sumdb//supported. - // If that request returns a successful (HTTP 200) response, then the proxy supports - // proxying checksum database requests. In that case, the client should use - // the proxied access method only, never falling back to a direct connection to the database. - // If the /sumdb//supported check fails with a “not found” (HTTP 404) - // or “gone” (HTTP 410) response, the proxy is unwilling to proxy the checksum database, - // and the client should connect directly to the database. - // Any other response is treated as the database being unavailable. - _, err = web.GetBytes(web.Join(proxy, "sumdb/"+c.name+"/supported")) - if err == nil { + // + // Before accessing any checksum database URL using a proxy, the proxy + // client should first fetch /sumdb//supported. + // + // If that request returns a successful (HTTP 200) response, then the proxy + // supports proxying checksum database requests. In that case, the client + // should use the proxied access method only, never falling back to a direct + // connection to the database. + // + // If the /sumdb//supported check fails with a “not found” (HTTP + // 404) or “gone” (HTTP 410) response, or if the proxy is configured to fall + // back on errors, the client will try the next proxy. If there are no + // proxies left or if the proxy is "direct" or "off", the client should + // connect directly to that database. + // + // Any other response is treated as the database being unavailable. + // + // See https://golang.org/design/25530-sumdb#proxying-a-checksum-database. + err := TryProxies(func(proxy string) error { + switch proxy { + case "noproxy": + return errUseProxy + case "direct", "off": + return errProxyOff + default: + proxyURL, err := url.Parse(proxy) + if err != nil { + return err + } + if _, err := web.GetBytes(web.Join(proxyURL, "sumdb/"+c.name+"/supported")); err != nil { + return err + } // Success! This proxy will help us. - c.base = web.Join(proxy, "sumdb/"+c.name) - return - } - // If the proxy serves a non-404/410, give up. - if !errors.Is(err, os.ErrNotExist) { - c.baseErr = err - return + c.base = web.Join(proxyURL, "sumdb/"+c.name) + return nil } + }) + if errors.Is(err, os.ErrNotExist) { + // No proxies, or all proxies failed (with 404, 410, or were were allowed + // to fall back), or we reached an explicit "direct" or "off". + c.base = c.direct + } else if err != nil { + c.baseErr = err } - - // No proxies, or all proxies said 404, or we reached an explicit "direct". - c.base = c.direct } // ReadConfig reads the key from c.key @@ -198,8 +200,10 @@ func (c *dbClient) ReadConfig(file string) (data []byte, err error) { return []byte(c.key), nil } - // GOPATH/pkg is PkgMod/.. - targ := filepath.Join(PkgMod, "../sumdb/"+file) + if cfg.SumdbDir == "" { + return nil, errors.New("could not locate sumdb file: missing $GOPATH") + } + targ := filepath.Join(cfg.SumdbDir, file) data, err = lockedfile.Read(targ) if errors.Is(err, os.ErrNotExist) { // Treat non-existent as empty, to bootstrap the "latest" file @@ -215,7 +219,10 @@ func (*dbClient) WriteConfig(file string, old, new []byte) error { // Should not happen. return fmt.Errorf("cannot write key") } - targ := filepath.Join(PkgMod, "../sumdb/"+file) + if cfg.SumdbDir == "" { + return errors.New("could not locate sumdb file: missing $GOPATH") + } + targ := filepath.Join(cfg.SumdbDir, file) os.MkdirAll(filepath.Dir(targ), 0777) f, err := lockedfile.Edit(targ) if err != nil { @@ -245,7 +252,7 @@ func (*dbClient) WriteConfig(file string, old, new []byte) error { // GOPATH/pkg/mod/cache/download/sumdb, // which will be deleted by "go clean -modcache". func (*dbClient) ReadCache(file string) ([]byte, error) { - targ := filepath.Join(PkgMod, "cache/download/sumdb", file) + targ := filepath.Join(cfg.GOMODCACHE, "cache/download/sumdb", file) data, err := lockedfile.Read(targ) // lockedfile.Write does not atomically create the file with contents. // There is a moment between file creation and locking the file for writing, @@ -259,7 +266,7 @@ func (*dbClient) ReadCache(file string) ([]byte, error) { // WriteCache updates cached lookups or tiles. func (*dbClient) WriteCache(file string, data []byte) { - targ := filepath.Join(PkgMod, "cache/download/sumdb", file) + targ := filepath.Join(cfg.GOMODCACHE, "cache/download/sumdb", file) os.MkdirAll(filepath.Dir(targ), 0777) lockedfile.Write(targ, bytes.NewReader(data), 0666) } diff --git a/libgo/go/cmd/go/internal/modfetch/zip_sum_test/testdata/zip_sums.csv b/libgo/go/cmd/go/internal/modfetch/zip_sum_test/testdata/zip_sums.csv index 6eb8d7fd839..0906975f553 100644 --- a/libgo/go/cmd/go/internal/modfetch/zip_sum_test/testdata/zip_sums.csv +++ b/libgo/go/cmd/go/internal/modfetch/zip_sum_test/testdata/zip_sums.csv @@ -40,7 +40,6 @@ git.torproject.org/pluggable-transports/goptlib.git,v1.1.0,h1:LMQAA8pAho+QtYrrVN gitee.com/nggs/util,v0.0.0-20190830024003-3e49d2efc84b,h1:6KQpPEs326uPrICQy9x/PxmR8U0v/XsFzpt0k1nFKcY=,a062c99c2b560a36168fe51eab8f17f4fadf5d534238881628e83d8d61e51c2a github.com/1and1/oneandone-cloudserver-sdk-go,v1.0.1,h1:RMTyvS5bjvSWiUcfqfr/E2pxHEMrALvU+E12n6biymg=,7f068808fc0857d7de8c8f829cc380dce1c6611a3fc819daf4421e9bcb75a07c github.com/99designs/gqlgen,v0.10.1,h1:1BgB6XKGTHq7uH4G1/PYyKe2Kz7/vw3AlvMZlD3TEEY=,04b9e7d8a3df6543cd870325b1140ce9ac3f4bbfd8c90ebecec4f908dd420d08 -github.com/AlexStocks/log4go,v1.0.5,h1:45boeHy0qh0NFBaEhrFT/pUKzQUGf7q2Ux1iQDr/f6o=,59371c2108f62aa9a2233ca8f7de57868ad2c64313b2d68434e0ed6a1748ce2c github.com/AndreasBriese/bbloom,v0.0.0-20190306092124-e2d15f34fcf9,h1:HD8gA2tkByhMAwYaFAX9w2l7vxvBQ5NMoxDrkhqhtn4=,6d7c1af06f8597fde1e86166f26416057392f1b0bdb84f2af555aa461282dd18 github.com/AsynkronIT/goconsole,v0.0.0-20160504192649-bfa12eebf716,h1:Pk/Kzi5O0T4QxfqvbaUsh8UklbJ9BklZ/ClZBptX5WU=,5a2507b89bb4436881718d785a0ef383652aa99782508b7444cf20255082dab9 github.com/Azure/azure-amqp-common-go,v1.1.4,h1:DmPXxmLZwi/71CgRTZIKR6yiKEW3eC42S4gSBhfG7y0=,4b800793ff4fefa86a427c445e3a4671b8d1dcd87a44075f6309cace6b0e01e2 @@ -243,7 +242,6 @@ github.com/beego/x2j,v0.0.0-20131220205130-a0352aadc542,h1:nYXb+3jF6Oq/j8R/y90Xr github.com/beevik/etree,v1.1.0,h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs=,614a33736f8b9262a809f101df5bf71f47777879b1191165b6247d6b67c7468c github.com/beevik/guid,v0.0.0-20170504223318-d0ea8faecee0,h1:oLd/YLOTOgA4D4aAUhIE8vhl/LAP1ZJrj0mDQpl7GB8=,5add94fcade6c7afa236112c8da300d47ec499ad1789a5e805c8198062dd0749 github.com/beevik/ntp,v0.2.0,h1:sGsd+kAXzT0bfVfzJfce04g+dSRfrs+tbQW8lweuYgw=,42e14f30c23ba2f5ddaff76101016d87f0f0a0f1d96d3d20e42fd02842091c76 -github.com/belogik/goes,v0.0.0-20151229125003-e54d722c3aff,h1:/kO0p2RTGLB8R5gub7ps0GmYpB2O8LXEoPq8tzFDCUI=,f926f1040febe5318efa145541a6fc7898d32514bc13899e812185f05710c5db github.com/beorn7/perks,v1.0.1,h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=,25bd9e2d94aca770e6dbc1f53725f84f6af4432f631d35dd2c46f96ef0512f1a github.com/bep/debounce,v1.2.0,h1:wXds8Kq8qRfwAOpAxHrJDbCXgC5aHSzgQb/0gKsHQqo=,ddc0a77e4819b6b826d69fdf1a5a153f3f867a31e030cfe28296355b670adf21 github.com/bep/gitmap,v1.1.1,h1:Nf8ySnC3I7/xPjuWeCwzukUFv185iTUQ6nOvLy9gCJA=,364163e67741ae331d164fd881964160f19fdbdfe094e0e762314cc37aac646a @@ -1461,7 +1459,6 @@ github.com/opencontainers/runc,v0.1.1,h1:GlxAyO6x8rfZYN9Tt0Kti5a/cP41iuiO2yYT0IJ github.com/opencontainers/runtime-spec,v1.0.1,h1:wY4pOY8fBdSIvs9+IDHC55thBuEulhzfSgKeC1yFvzQ=,1958458b00ce912425f5c7d2ee836431b296a3f9320d565512d8c96b107fffbf github.com/opencontainers/runtime-tools,v0.9.0,h1:FYgwVsKRI/H9hU32MJ/4MLOzXWodKK5zsQavY8NPMkU=,53c720dbb7452cfb2fd3945e37c26b5a0140cb1012d35a2b72a5e035f28a32c4 github.com/opencontainers/selinux,v1.3.0,h1:xsI95WzPZu5exzA6JzkLSfdr/DilzOhCJOqGe5TgR0g=,88286825b32cd46a0469e578f378a185032da2d5b03893623861ef3af59359d8 -github.com/openshift/api,v3.9.0+incompatible,h1:fJ/KsefYuZAjmrr3+5U9yZIZbTOpVkDDLDLFresAeYs=,fc087ac9809ce58bdd15614e04c13f8ecc4a17e71addbe6eb6b777c377b01243 github.com/openshift/client-go,v3.9.0+incompatible,h1:13k3Ok0B7TA2hA3bQW2aFqn6y04JaJWdk7ITTyg+Ek0=,661b7f28b4905f1936dd58e373374513d54663ec85aecafede1c7d9c260e9369 github.com/openshift/library-go,v0.0.0-20191101161407-e7c97b468b83,h1:wwR+laNaFKVGiizoIDL/cAKIZVoKXJ9jbjUoUlq2p5I=,c74f8134013f978ef154d6accf9b4b0c5126941f2d45e6eb223db7098f7ab2a4 github.com/opentracing-contrib/go-observer,v0.0.0-20170622124052-a52f23424492,h1:lM6RxxfUMrYL/f8bWEUqdXrANWtrL7Nndbm9iFN0DlU=,50023eee1ef04412410f43d8b5dcf3ef481c0fc39067add27799654705fa84b2 @@ -1882,7 +1879,6 @@ github.com/zondax/ledger-go,v0.9.0,h1:oTrtFqPFA4VdCPRvqMaN45mQnJxkPc0JxoVZfCoUpj github.com/zquestz/grab,v0.0.0-20190224022517-abcee96e61b1,h1:1qKTeMTSIEvRIjvVYzgcRp0xVp0eoiRTTiHSncb5gD8=,4decd67f1252df4ee34968cb0cb4e7dc6010302b24ce8edd418f1c2520f1c351 gitlab.com/NebulousLabs/errors,v0.0.0-20171229012116-7ead97ef90b8,h1:gZfMjx7Jr6N8b7iJO4eUjDsn6xJqoyXg8D+ogdoAfKY=,b355474f1a2ef2722ae450ef6df7209d223188ae413706be122b472fcc053c48 gitlab.com/NebulousLabs/fastrand,v0.0.0-20181126182046-603482d69e40,h1:dizWJqTWjwyD8KGcMOwgrkqu1JIkofYgKkmDeNE7oAs=,a56acdda993c7a4795028fe38844d54de9b1877d22e8ae09f205e488ce2284bc -gitlab.com/yumeko/MumbleEmu,v0.0.0-20170923112213-54c9892f02e9,h1:QSaGLacCEAlWXhL/xGZyS3+2aDVvBZe5jcmrDWwXhqs=,51cc295a04dc3b9c39b341f21b95fc42765e3bb61fe30ec2a59fe867c1b5e5ed go.bug.st/serial.v1,v0.0.0-20180827123349-5f7892a7bb45,h1:mACY1anK6HNCZtm/DK2Rf2ZPHggVqeB0+7rY9Gl6wyI=,f0ea4cd4c51228f1a3cf14c6b92888169944f267e1ee778909512a4c8ac4762f go.cryptoscope.co/luigi,v0.3.4,h1:eDrtCoUL5Vl2Atr5ty2dq0uFbzFCc6Pz1HEqU1e7I1I=,949612e92dcb2fc919e506740f36d0cfe0797c1f85579a98763aad0135a4580a go.dedis.ch/fixbuf,v1.0.3,h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs=,dfa737543a5873b14cdfd0eec675c63044b16d3dbe481b2289c758ae4186ae95 @@ -2085,7 +2081,6 @@ layeh.com/radius,v0.0.0-20190322222518-890bc1058917,h1:BDXFaFzUt5EIqe/4wrTc4AcYZ leb.io/aeshash,v0.0.0-20190627052759-9e6b40329b3b,h1:MG17Tc0pA3XmFTsPwklMMEfcos3pTFnVYM4A0YfVSbU=,a78b48ac18e98ea68dacce16cd94c9074688a0b125f824f047313a33b264ea88 leb.io/hashland,v0.0.0-20171003003232-07375b562dea,h1:s9IkzZTqYqw77voO6taUZHc0C1B096h4T/kQtujGApE=,0698177f24cbde0a7b45495e7fe976fe7623f2b9205995b7d91fd2e7b0f0e243 leb.io/hrff,v0.0.0-20170927164517-757f8bd43e20,h1:9CHS8LIq9MDwUsAaCHUsbUq7zb5lSjLQYWlJ/AbMZKg=,538008712599401a903a7982714c0a9ae745221042d3dfb1437bc508d8fb9e96 -llvm.org/llvm,v0.0.0-20191022153947-000000375505,h1:cncItmsQ0kcXFrnkQZv2TGle2ELPCEDi3Q36Kf2T3yg=,3f48da9846fc0f69ccc447ead4480f8c7f2b44b0c24b98a793d36d8cb2a572c0 modernc.org/cc,v1.0.0,h1:nPibNuDEx6tvYrUAtvDTTw98rx5juGsa5zuDnKwEEQQ=,24711e9b28b0d79dd32438eeb7debd86b850350f5f7749b7af640422ecf6b93b modernc.org/golex,v1.0.0,h1:wWpDlbK8ejRfSyi0frMyhilD3JBvtcx2AdGDnU+JtsE=,335133038991d7feaba5349ac2385db7b49601bba0904abf680803ee2d3c99df modernc.org/mathutil,v1.0.0,h1:93vKjrJopTPrtTNpZ8XIovER7iCIH1QU7wNbOQXC60I=,766ad95195543fe1ac217ce9f54e1fb43119c25db2b89013b9ef5477ad2dd9d1 diff --git a/libgo/go/cmd/go/internal/modfetch/zip_sum_test/zip_sum_test.go b/libgo/go/cmd/go/internal/modfetch/zip_sum_test/zip_sum_test.go index 331d634d102..eac9b32fa85 100644 --- a/libgo/go/cmd/go/internal/modfetch/zip_sum_test/zip_sum_test.go +++ b/libgo/go/cmd/go/internal/modfetch/zip_sum_test/zip_sum_test.go @@ -126,7 +126,7 @@ func TestZipSums(t *testing.T) { test.m.Path = "" // mark for deletion needUpdate = true } else { - t.Errorf("%s: could not download mdoule: %s", test.m, err) + t.Errorf("%s: could not download module: %s", test.m, err) } return } diff --git a/libgo/go/cmd/go/internal/modget/get.go b/libgo/go/cmd/go/internal/modget/get.go index 2a0f6346581..4c6982426fb 100644 --- a/libgo/go/cmd/go/internal/modget/get.go +++ b/libgo/go/cmd/go/internal/modget/get.go @@ -114,7 +114,10 @@ require downgrading other dependencies, and 'go get' does this automatically as well. The -insecure flag permits fetching from repositories and resolving -custom domains using insecure schemes such as HTTP. Use with caution. +custom domains using insecure schemes such as HTTP. Use with caution. The +GOINSECURE environment variable is usually a better alternative, since it +provides control over which modules may be retrieved using an insecure scheme. +See 'go help environment' for details. The second step is to download (if needed), build, and install the named packages. @@ -307,6 +310,20 @@ func runGet(cmd *base.Command, args []string) { continue } + // Guard against 'go get x.go', a common mistake. + // Note that package and module paths may end with '.go', so only print an error + // if the argument has no version and either has no slash or refers to an existing file. + if strings.HasSuffix(arg, ".go") && vers == "" { + if !strings.Contains(arg, "/") { + base.Errorf("go get %s: arguments must be package or module paths", arg) + continue + } + if fi, err := os.Stat(arg); err == nil && !fi.IsDir() { + base.Errorf("go get: %s exists as a file, but 'go get' requires package arguments", arg) + continue + } + } + // If no version suffix is specified, assume @upgrade. // If -u=patch was specified, assume @patch instead. if vers == "" { @@ -326,15 +343,22 @@ func runGet(cmd *base.Command, args []string) { // patterns like golang.org/x/tools/..., which can't be expanded // during package loading until they're in the build list. switch { - case search.IsRelativePath(path): - // Relative paths like ../../foo or ../../foo... are restricted to - // matching packages in the main module. If the path is explicit and - // contains no wildcards (...), check that it is a package in - // the main module. If the path contains wildcards but matches no - // packages, we'll warn after package loading. + case filepath.IsAbs(path) || search.IsRelativePath(path): + // Absolute paths like C:\foo and relative paths like ../foo... + // are restricted to matching packages in the main module. If the path + // is explicit and contains no wildcards (...), check that it is a + // package in the main module. If the path contains wildcards but + // matches no packages, we'll warn after package loading. if !strings.Contains(path, "...") { - pkgPath := modload.DirImportPath(filepath.FromSlash(path)) - if pkgs := modload.TargetPackages(pkgPath); len(pkgs) == 0 { + m := search.NewMatch(path) + if pkgPath := modload.DirImportPath(path); pkgPath != "." { + m = modload.TargetPackages(pkgPath) + } + if len(m.Pkgs) == 0 { + for _, err := range m.Errs { + base.Errorf("go get %s: %v", arg, err) + } + abs, err := filepath.Abs(path) if err != nil { abs = path @@ -374,7 +398,7 @@ func runGet(cmd *base.Command, args []string) { default: // The argument is a package or module path. if modload.HasModRoot() { - if pkgs := modload.TargetPackages(path); len(pkgs) != 0 { + if m := modload.TargetPackages(path); len(m.Pkgs) != 0 { // The path is in the main module. Nothing to query. if vers != "upgrade" && vers != "patch" { base.Errorf("go get %s: can't request explicit version of path in main module", arg) @@ -520,8 +544,12 @@ func runGet(cmd *base.Command, args []string) { // If the pattern did not match any packages, look up a new module. // If the pattern doesn't match anything on the last iteration, // we'll print a warning after the outer loop. - if !search.IsRelativePath(arg.path) && !match.Literal && arg.path != "all" { + if !match.IsLocal() && !match.IsLiteral() && arg.path != "all" { addQuery(&query{querySpec: querySpec{path: arg.path, vers: arg.vers}, arg: arg.raw}) + } else { + for _, err := range match.Errs { + base.Errorf("go get: %v", err) + } } continue } diff --git a/libgo/go/cmd/go/internal/modload/build.go b/libgo/go/cmd/go/internal/modload/build.go index 2a69d5953d3..e7e7d56bb4d 100644 --- a/libgo/go/cmd/go/internal/modload/build.go +++ b/libgo/go/cmd/go/internal/modload/build.go @@ -205,6 +205,7 @@ func PackageBuildInfo(path string, deps []string) string { if isStandardImportPath(path) || !Enabled() { return "" } + target := mustFindModule(path, path) mdeps := make(map[module.Version]bool) for _, dep := range deps { @@ -221,26 +222,25 @@ func PackageBuildInfo(path string, deps []string) string { var buf bytes.Buffer fmt.Fprintf(&buf, "path\t%s\n", path) - tv := target.Version - if tv == "" { - tv = "(devel)" - } - fmt.Fprintf(&buf, "mod\t%s\t%s\t%s\n", target.Path, tv, modfetch.Sum(target)) - for _, mod := range mods { - mv := mod.Version + + writeEntry := func(token string, m module.Version) { + mv := m.Version if mv == "" { mv = "(devel)" } - r := Replacement(mod) - h := "" - if r.Path == "" { - h = "\t" + modfetch.Sum(mod) - } - fmt.Fprintf(&buf, "dep\t%s\t%s%s\n", mod.Path, mv, h) - if r.Path != "" { - fmt.Fprintf(&buf, "=>\t%s\t%s\t%s\n", r.Path, r.Version, modfetch.Sum(r)) + fmt.Fprintf(&buf, "%s\t%s\t%s", token, m.Path, mv) + if r := Replacement(m); r.Path == "" { + fmt.Fprintf(&buf, "\t%s\n", modfetch.Sum(m)) + } else { + fmt.Fprintf(&buf, "\n=>\t%s\t%s\t%s\n", r.Path, r.Version, modfetch.Sum(r)) } } + + writeEntry("mod", target) + for _, mod := range mods { + writeEntry("dep", mod) + } + return buf.String() } diff --git a/libgo/go/cmd/go/internal/modload/help.go b/libgo/go/cmd/go/internal/modload/help.go index bd19bb43aa0..d80206b1948 100644 --- a/libgo/go/cmd/go/internal/modload/help.go +++ b/libgo/go/cmd/go/internal/modload/help.go @@ -363,15 +363,15 @@ variable (see 'go help env'). The default setting for GOPROXY is Go module mirror run by Google and fall back to a direct connection if the proxy reports that it does not have the module (HTTP error 404 or 410). See https://proxy.golang.org/privacy for the service's privacy policy. -If GOPROXY is set to the string "direct", downloads use a direct connection -to source control servers. Setting GOPROXY to "off" disallows downloading -modules from any source. Otherwise, GOPROXY is expected to be a comma-separated -list of the URLs of module proxies, in which case the go command will fetch -modules from those proxies. For each request, the go command tries each proxy -in sequence, only moving to the next if the current proxy returns a 404 or 410 -HTTP response. The string "direct" may appear in the proxy list, -to cause a direct connection to be attempted at that point in the search. -Any proxies listed after "direct" are never consulted. + +If GOPROXY is set to the string "direct", downloads use a direct connection to +source control servers. Setting GOPROXY to "off" disallows downloading modules +from any source. Otherwise, GOPROXY is expected to be list of module proxy URLs +separated by either comma (,) or pipe (|) characters, which control error +fallback behavior. For each request, the go command tries each proxy in +sequence. If there is an error, the go command will try the next proxy in the +list if the error is a 404 or 410 HTTP response or if the current proxy is +followed by a pipe character, indicating it is safe to fall back on any error. The GOPRIVATE and GONOPROXY environment variables allow bypassing the proxy for selected modules. See 'go help module-private' for details. diff --git a/libgo/go/cmd/go/internal/modload/import.go b/libgo/go/cmd/go/internal/modload/import.go index d7fca8fd2c5..4d2bc805e2f 100644 --- a/libgo/go/cmd/go/internal/modload/import.go +++ b/libgo/go/cmd/go/internal/modload/import.go @@ -62,11 +62,15 @@ func (e *ImportMissingError) ImportPath() string { // modules in the build list, or found in both the main module and its vendor // directory. type AmbiguousImportError struct { - ImportPath string + importPath string Dirs []string Modules []module.Version // Either empty or 1:1 with Dirs. } +func (e *AmbiguousImportError) ImportPath() string { + return e.importPath +} + func (e *AmbiguousImportError) Error() string { locType := "modules" if len(e.Modules) == 0 { @@ -74,7 +78,7 @@ func (e *AmbiguousImportError) Error() string { } var buf strings.Builder - fmt.Fprintf(&buf, "ambiguous import: found package %s in multiple %s:", e.ImportPath, locType) + fmt.Fprintf(&buf, "ambiguous import: found package %s in multiple %s:", e.importPath, locType) for i, dir := range e.Dirs { buf.WriteString("\n\t") @@ -93,6 +97,8 @@ func (e *AmbiguousImportError) Error() string { return buf.String() } +var _ load.ImportPathError = &AmbiguousImportError{} + // Import finds the module and directory in the build list // containing the package with the given import path. // The answer must be unique: Import returns an error @@ -120,7 +126,9 @@ func Import(path string) (m module.Version, dir string, err error) { pathIsStd := search.IsStandardImportPath(path) if pathIsStd && goroot.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, path) { if targetInGorootSrc { - if dir, ok := dirInModule(path, targetPrefix, ModRoot(), true); ok { + if dir, ok, err := dirInModule(path, targetPrefix, ModRoot(), true); err != nil { + return module.Version{}, dir, err + } else if ok { return Target, dir, nil } } @@ -131,10 +139,10 @@ func Import(path string) (m module.Version, dir string, err error) { // -mod=vendor is special. // Everything must be in the main module or the main module's vendor directory. if cfg.BuildMod == "vendor" { - mainDir, mainOK := dirInModule(path, targetPrefix, ModRoot(), true) - vendorDir, vendorOK := dirInModule(path, "", filepath.Join(ModRoot(), "vendor"), false) + mainDir, mainOK, mainErr := dirInModule(path, targetPrefix, ModRoot(), true) + vendorDir, vendorOK, _ := dirInModule(path, "", filepath.Join(ModRoot(), "vendor"), false) if mainOK && vendorOK { - return module.Version{}, "", &AmbiguousImportError{ImportPath: path, Dirs: []string{mainDir, vendorDir}} + return module.Version{}, "", &AmbiguousImportError{importPath: path, Dirs: []string{mainDir, vendorDir}} } // Prefer to return main directory if there is one, // Note that we're not checking that the package exists. @@ -142,6 +150,9 @@ func Import(path string) (m module.Version, dir string, err error) { if !vendorOK && mainDir != "" { return Target, mainDir, nil } + if mainErr != nil { + return module.Version{}, "", mainErr + } readVendorList() return vendorPkgModule[path], vendorDir, nil } @@ -164,8 +175,9 @@ func Import(path string) (m module.Version, dir string, err error) { // not ambiguous. return module.Version{}, "", err } - dir, ok := dirInModule(path, m.Path, root, isLocal) - if ok { + if dir, ok, err := dirInModule(path, m.Path, root, isLocal); err != nil { + return module.Version{}, "", err + } else if ok { mods = append(mods, m) dirs = append(dirs, dir) } @@ -174,7 +186,7 @@ func Import(path string) (m module.Version, dir string, err error) { return mods[0], dirs[0], nil } if len(mods) > 0 { - return module.Version{}, "", &AmbiguousImportError{ImportPath: path, Dirs: dirs, Modules: mods} + return module.Version{}, "", &AmbiguousImportError{importPath: path, Dirs: dirs, Modules: mods} } // Look up module containing the package, for addition to the build list. @@ -241,8 +253,9 @@ func Import(path string) (m module.Version, dir string, err error) { // Report fetch error as above. return module.Version{}, "", err } - _, ok := dirInModule(path, m.Path, root, isLocal) - if ok { + if _, ok, err := dirInModule(path, m.Path, root, isLocal); err != nil { + return m, "", err + } else if ok { return m, "", &ImportMissingError{Path: path, Module: m} } } @@ -313,19 +326,29 @@ func maybeInModule(path, mpath string) bool { len(path) > len(mpath) && path[len(mpath)] == '/' && path[:len(mpath)] == mpath } -var haveGoModCache, haveGoFilesCache par.Cache +var ( + haveGoModCache par.Cache // dir → bool + haveGoFilesCache par.Cache // dir → goFilesEntry +) + +type goFilesEntry struct { + haveGoFiles bool + err error +} // dirInModule locates the directory that would hold the package named by the given path, // if it were in the module with module path mpath and root mdir. // If path is syntactically not within mpath, // or if mdir is a local file tree (isLocal == true) and the directory // that would hold path is in a sub-module (covered by a go.mod below mdir), -// dirInModule returns "", false. +// dirInModule returns "", false, nil. // // Otherwise, dirInModule returns the name of the directory where // Go source files would be expected, along with a boolean indicating // whether there are in fact Go source files in that directory. -func dirInModule(path, mpath, mdir string, isLocal bool) (dir string, haveGoFiles bool) { +// A non-nil error indicates that the existence of the directory and/or +// source files could not be determined, for example due to a permission error. +func dirInModule(path, mpath, mdir string, isLocal bool) (dir string, haveGoFiles bool, err error) { // Determine where to expect the package. if path == mpath { dir = mdir @@ -334,7 +357,7 @@ func dirInModule(path, mpath, mdir string, isLocal bool) (dir string, haveGoFile } else if len(path) > len(mpath) && path[len(mpath)] == '/' && path[:len(mpath)] == mpath { dir = filepath.Join(mdir, path[len(mpath)+1:]) } else { - return "", false + return "", false, nil } // Check that there aren't other modules in the way. @@ -351,7 +374,7 @@ func dirInModule(path, mpath, mdir string, isLocal bool) (dir string, haveGoFile }).(bool) if haveGoMod { - return "", false + return "", false, nil } parent := filepath.Dir(d) if parent == d { @@ -368,23 +391,58 @@ func dirInModule(path, mpath, mdir string, isLocal bool) (dir string, haveGoFile // Are there Go source files in the directory? // We don't care about build tags, not even "+build ignore". // We're just looking for a plausible directory. - haveGoFiles = haveGoFilesCache.Do(dir, func() interface{} { - f, err := os.Open(dir) - if err != nil { - return false + res := haveGoFilesCache.Do(dir, func() interface{} { + ok, err := isDirWithGoFiles(dir) + return goFilesEntry{haveGoFiles: ok, err: err} + }).(goFilesEntry) + + return dir, res.haveGoFiles, res.err +} + +func isDirWithGoFiles(dir string) (bool, error) { + f, err := os.Open(dir) + if err != nil { + if os.IsNotExist(err) { + return false, nil + } + return false, err + } + defer f.Close() + + names, firstErr := f.Readdirnames(-1) + if firstErr != nil { + if fi, err := f.Stat(); err == nil && !fi.IsDir() { + return false, nil } - defer f.Close() - names, _ := f.Readdirnames(-1) - for _, name := range names { - if strings.HasSuffix(name, ".go") { - info, err := os.Stat(filepath.Join(dir, name)) - if err == nil && info.Mode().IsRegular() { - return true + + // Rewrite the error from ReadDirNames to include the path if not present. + // See https://golang.org/issue/38923. + var pe *os.PathError + if !errors.As(firstErr, &pe) { + firstErr = &os.PathError{Op: "readdir", Path: dir, Err: firstErr} + } + } + + for _, name := range names { + if strings.HasSuffix(name, ".go") { + info, err := os.Stat(filepath.Join(dir, name)) + if err == nil && info.Mode().IsRegular() { + // If any .go source file exists, the package exists regardless of + // errors for other source files. Leave further error reporting for + // later. + return true, nil + } + if firstErr == nil { + if os.IsNotExist(err) { + // If the file was concurrently deleted, or was a broken symlink, + // convert the error to an opaque error instead of one matching + // os.IsNotExist. + err = errors.New(err.Error()) } + firstErr = err } } - return false - }).(bool) + } - return dir, haveGoFiles + return false, firstErr } diff --git a/libgo/go/cmd/go/internal/modload/init.go b/libgo/go/cmd/go/internal/modload/init.go index 61cbdf2c543..664a2a15943 100644 --- a/libgo/go/cmd/go/internal/modload/init.go +++ b/libgo/go/cmd/go/internal/modload/init.go @@ -26,7 +26,6 @@ import ( "cmd/go/internal/lockedfile" "cmd/go/internal/modconv" "cmd/go/internal/modfetch" - "cmd/go/internal/modfetch/codehost" "cmd/go/internal/mvs" "cmd/go/internal/search" @@ -59,27 +58,6 @@ var ( allowMissingModuleImports bool ) -var modFile *modfile.File - -// A modFileIndex is an index of data corresponding to a modFile -// at a specific point in time. -type modFileIndex struct { - data []byte - dataNeedsFix bool // true if fixVersion applied a change while parsing data - module module.Version - goVersion string - require map[module.Version]requireMeta - replace map[module.Version]module.Version - exclude map[module.Version]bool -} - -// index is the index of the go.mod file as of when it was last read or written. -var index *modFileIndex - -type requireMeta struct { - indirect bool -} - // ModFile returns the parsed go.mod file. // // Note that after calling ImportPaths or LoadBuildList, @@ -199,17 +177,6 @@ func Init() { base.Fatalf("$GOPATH/go.mod exists but should not") } - oldSrcMod := filepath.Join(list[0], "src/mod") - pkgMod := filepath.Join(list[0], "pkg/mod") - infoOld, errOld := os.Stat(oldSrcMod) - _, errMod := os.Stat(pkgMod) - if errOld == nil && infoOld.IsDir() && errMod != nil && os.IsNotExist(errMod) { - os.Rename(oldSrcMod, pkgMod) - } - - modfetch.PkgMod = pkgMod - codehost.WorkRoot = filepath.Join(pkgMod, "cache/vcs") - cfg.ModulesEnabled = true load.ModBinDir = BinDir load.ModLookup = Lookup @@ -246,13 +213,6 @@ func Init() { func init() { load.ModInit = Init - - // Set modfetch.PkgMod and codehost.WorkRoot unconditionally, - // so that go clean -modcache and go mod download can run even without modules enabled. - if list := filepath.SplitList(cfg.BuildContext.GOPATH); len(list) > 0 && list[0] != "" { - modfetch.PkgMod = filepath.Join(list[0], "pkg/mod") - codehost.WorkRoot = filepath.Join(list[0], "pkg/mod/cache/vcs") - } } // WillBeEnabled checks whether modules should be enabled but does not @@ -555,101 +515,6 @@ func setDefaultBuildMod() { } } -// checkVendorConsistency verifies that the vendor/modules.txt file matches (if -// go 1.14) or at least does not contradict (go 1.13 or earlier) the -// requirements and replacements listed in the main module's go.mod file. -func checkVendorConsistency() { - readVendorList() - - pre114 := false - if modFile.Go == nil || semver.Compare("v"+modFile.Go.Version, "v1.14") < 0 { - // Go versions before 1.14 did not include enough information in - // vendor/modules.txt to check for consistency. - // If we know that we're on an earlier version, relax the consistency check. - pre114 = true - } - - vendErrors := new(strings.Builder) - vendErrorf := func(mod module.Version, format string, args ...interface{}) { - detail := fmt.Sprintf(format, args...) - if mod.Version == "" { - fmt.Fprintf(vendErrors, "\n\t%s: %s", mod.Path, detail) - } else { - fmt.Fprintf(vendErrors, "\n\t%s@%s: %s", mod.Path, mod.Version, detail) - } - } - - for _, r := range modFile.Require { - if !vendorMeta[r.Mod].Explicit { - if pre114 { - // Before 1.14, modules.txt did not indicate whether modules were listed - // explicitly in the main module's go.mod file. - // However, we can at least detect a version mismatch if packages were - // vendored from a non-matching version. - if vv, ok := vendorVersion[r.Mod.Path]; ok && vv != r.Mod.Version { - vendErrorf(r.Mod, fmt.Sprintf("is explicitly required in go.mod, but vendor/modules.txt indicates %s@%s", r.Mod.Path, vv)) - } - } else { - vendErrorf(r.Mod, "is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt") - } - } - } - - describe := func(m module.Version) string { - if m.Version == "" { - return m.Path - } - return m.Path + "@" + m.Version - } - - // We need to verify *all* replacements that occur in modfile: even if they - // don't directly apply to any module in the vendor list, the replacement - // go.mod file can affect the selected versions of other (transitive) - // dependencies - for _, r := range modFile.Replace { - vr := vendorMeta[r.Old].Replacement - if vr == (module.Version{}) { - if pre114 && (r.Old.Version == "" || vendorVersion[r.Old.Path] != r.Old.Version) { - // Before 1.14, modules.txt omitted wildcard replacements and - // replacements for modules that did not have any packages to vendor. - } else { - vendErrorf(r.Old, "is replaced in go.mod, but not marked as replaced in vendor/modules.txt") - } - } else if vr != r.New { - vendErrorf(r.Old, "is replaced by %s in go.mod, but marked as replaced by %s in vendor/modules.txt", describe(r.New), describe(vr)) - } - } - - for _, mod := range vendorList { - meta := vendorMeta[mod] - if meta.Explicit { - if _, inGoMod := index.require[mod]; !inGoMod { - vendErrorf(mod, "is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod") - } - } - } - - for _, mod := range vendorReplaced { - r := Replacement(mod) - if r == (module.Version{}) { - vendErrorf(mod, "is marked as replaced in vendor/modules.txt, but not replaced in go.mod") - continue - } - if meta := vendorMeta[mod]; r != meta.Replacement { - vendErrorf(mod, "is marked as replaced by %s in vendor/modules.txt, but replaced by %s in go.mod", describe(meta.Replacement), describe(r)) - } - } - - if vendErrors.Len() > 0 { - base.Fatalf("go: inconsistent vendoring in %s:%s\n\nrun 'go mod vendor' to sync, or use -mod=mod or -mod=readonly to ignore the vendor directory", modRoot, vendErrors) - } -} - -// Allowed reports whether module m is allowed (not excluded) by the main module's go.mod. -func Allowed(m module.Version) bool { - return index == nil || !index.exclude[m] -} - func legacyModInit() { if modFile == nil { path, err := findModulePath(modRoot) @@ -740,13 +605,14 @@ func findAltConfig(dir string) (root, name string) { panic("dir not set") } dir = filepath.Clean(dir) + if rel := search.InDir(dir, cfg.BuildContext.GOROOT); rel != "" { + // Don't suggest creating a module from $GOROOT/.git/config + // or a config file found in any parent of $GOROOT (see #34191). + return "", "" + } for { for _, name := range altConfigs { if fi, err := os.Stat(filepath.Join(dir, name)); err == nil && !fi.IsDir() { - if rel := search.InDir(dir, cfg.BuildContext.GOROOT); rel == "." { - // Don't suggest creating a module from $GOROOT/.git/config. - return "", "" - } return dir, name } } @@ -983,113 +849,3 @@ func WriteGoMod() { base.Fatalf("go: updating go.mod: %v", err) } } - -// indexModFile rebuilds the index of modFile. -// If modFile has been changed since it was first read, -// modFile.Cleanup must be called before indexModFile. -func indexModFile(data []byte, modFile *modfile.File, needsFix bool) *modFileIndex { - i := new(modFileIndex) - i.data = data - i.dataNeedsFix = needsFix - - i.module = module.Version{} - if modFile.Module != nil { - i.module = modFile.Module.Mod - } - - i.goVersion = "" - if modFile.Go != nil { - i.goVersion = modFile.Go.Version - } - - i.require = make(map[module.Version]requireMeta, len(modFile.Require)) - for _, r := range modFile.Require { - i.require[r.Mod] = requireMeta{indirect: r.Indirect} - } - - i.replace = make(map[module.Version]module.Version, len(modFile.Replace)) - for _, r := range modFile.Replace { - if prev, dup := i.replace[r.Old]; dup && prev != r.New { - base.Fatalf("go: conflicting replacements for %v:\n\t%v\n\t%v", r.Old, prev, r.New) - } - i.replace[r.Old] = r.New - } - - i.exclude = make(map[module.Version]bool, len(modFile.Exclude)) - for _, x := range modFile.Exclude { - i.exclude[x.Mod] = true - } - - return i -} - -// modFileIsDirty reports whether the go.mod file differs meaningfully -// from what was indexed. -// If modFile has been changed (even cosmetically) since it was first read, -// modFile.Cleanup must be called before modFileIsDirty. -func (i *modFileIndex) modFileIsDirty(modFile *modfile.File) bool { - if i == nil { - return modFile != nil - } - - if i.dataNeedsFix { - return true - } - - if modFile.Module == nil { - if i.module != (module.Version{}) { - return true - } - } else if modFile.Module.Mod != i.module { - return true - } - - if modFile.Go == nil { - if i.goVersion != "" { - return true - } - } else if modFile.Go.Version != i.goVersion { - if i.goVersion == "" && cfg.BuildMod == "readonly" { - // go.mod files did not always require a 'go' version, so do not error out - // if one is missing — we may be inside an older module in the module - // cache, and should bias toward providing useful behavior. - } else { - return true - } - } - - if len(modFile.Require) != len(i.require) || - len(modFile.Replace) != len(i.replace) || - len(modFile.Exclude) != len(i.exclude) { - return true - } - - for _, r := range modFile.Require { - if meta, ok := i.require[r.Mod]; !ok { - return true - } else if r.Indirect != meta.indirect { - if cfg.BuildMod == "readonly" { - // The module's requirements are consistent; only the "// indirect" - // comments that are wrong. But those are only guaranteed to be accurate - // after a "go mod tidy" — it's a good idea to run those before - // committing a change, but it's certainly not mandatory. - } else { - return true - } - } - } - - for _, r := range modFile.Replace { - if r.New != i.replace[r.Old] { - return true - } - } - - for _, x := range modFile.Exclude { - if !i.exclude[x.Mod] { - return true - } - } - - return false -} diff --git a/libgo/go/cmd/go/internal/modload/load.go b/libgo/go/cmd/go/internal/modload/load.go index 7a8391d7e1a..f5f74baf24e 100644 --- a/libgo/go/cmd/go/internal/modload/load.go +++ b/libgo/go/cmd/go/internal/modload/load.go @@ -6,30 +6,25 @@ package modload import ( "bytes" + "cmd/go/internal/base" + "cmd/go/internal/cfg" + "cmd/go/internal/imports" + "cmd/go/internal/modfetch" + "cmd/go/internal/mvs" + "cmd/go/internal/par" + "cmd/go/internal/search" + "cmd/go/internal/str" "errors" "fmt" "go/build" - "io/ioutil" "os" "path" pathpkg "path" "path/filepath" "sort" "strings" - "sync" - "cmd/go/internal/base" - "cmd/go/internal/cfg" - "cmd/go/internal/imports" - "cmd/go/internal/modfetch" - "cmd/go/internal/mvs" - "cmd/go/internal/par" - "cmd/go/internal/search" - "cmd/go/internal/str" - - "golang.org/x/mod/modfile" "golang.org/x/mod/module" - "golang.org/x/mod/semver" ) // buildList is the list of modules to use for building packages. @@ -65,23 +60,13 @@ func ImportPaths(patterns []string) []*search.Match { // packages. The build tags should typically be imports.Tags() or // imports.AnyTags(); a nil map has no special meaning. func ImportPathsQuiet(patterns []string, tags map[string]bool) []*search.Match { - var fsDirs [][]string updateMatches := func(matches []*search.Match, iterating bool) { - for i, m := range matches { + for _, m := range matches { switch { - case build.IsLocalImport(m.Pattern) || filepath.IsAbs(m.Pattern): + case m.IsLocal(): // Evaluate list of file system directories on first iteration. - if fsDirs == nil { - fsDirs = make([][]string, len(matches)) - } - if fsDirs[i] == nil { - var dirs []string - if m.Literal { - dirs = []string{m.Pattern} - } else { - dirs = search.MatchPackagesInFS(m.Pattern).Pkgs - } - fsDirs[i] = dirs + if m.Dirs == nil { + matchLocalDirs(m) } // Make a copy of the directory list and translate to import paths. @@ -90,102 +75,53 @@ func ImportPathsQuiet(patterns []string, tags map[string]bool) []*search.Match { // from not being in the build list to being in it and back as // the exact version of a particular module increases during // the loader iterations. - m.Pkgs = str.StringList(fsDirs[i]) - pkgs := m.Pkgs m.Pkgs = m.Pkgs[:0] - for _, pkg := range pkgs { - var dir string - if !filepath.IsAbs(pkg) { - dir = filepath.Join(base.Cwd, pkg) - } else { - dir = filepath.Clean(pkg) - } + for _, dir := range m.Dirs { + pkg, err := resolveLocalPackage(dir) + if err != nil { + if !m.IsLiteral() && (err == errPkgIsBuiltin || err == errPkgIsGorootSrc) { + continue // Don't include "builtin" or GOROOT/src in wildcard patterns. + } - // golang.org/issue/32917: We should resolve a relative path to a - // package path only if the relative path actually contains the code - // for that package. - if !dirContainsPackage(dir) { // If we're outside of a module, ensure that the failure mode // indicates that. ModRoot() - // If the directory is local but does not exist, don't return it - // while loader is iterating, since this might trigger a fetch. - // After loader is done iterating, we still need to return the - // path, so that "go list -e" produces valid output. if !iterating { - // We don't have a valid path to resolve to, so report the - // unresolved path. - m.Pkgs = append(m.Pkgs, pkg) + m.AddError(err) } continue } - - // Note: The checks for @ here are just to avoid misinterpreting - // the module cache directories (formerly GOPATH/src/mod/foo@v1.5.2/bar). - // It's not strictly necessary but helpful to keep the checks. - if modRoot != "" && dir == modRoot { - pkg = targetPrefix - } else if modRoot != "" && strings.HasPrefix(dir, modRoot+string(filepath.Separator)) && !strings.Contains(dir[len(modRoot):], "@") { - suffix := filepath.ToSlash(dir[len(modRoot):]) - if strings.HasPrefix(suffix, "/vendor/") { - // TODO getmode vendor check - pkg = strings.TrimPrefix(suffix, "/vendor/") - } else if targetInGorootSrc && Target.Path == "std" { - // Don't add the prefix "std/" to packages in the "std" module. - // It's the one module path that isn't a prefix of its packages. - pkg = strings.TrimPrefix(suffix, "/") - if pkg == "builtin" { - // "builtin" is a pseudo-package with a real source file. - // It's not included in "std", so it shouldn't be included in - // "./..." within module "std" either. - continue - } - } else { - modPkg := targetPrefix + suffix - if _, ok := dirInModule(modPkg, targetPrefix, modRoot, true); ok { - pkg = modPkg - } else if !iterating { - ModRoot() - base.Errorf("go: directory %s is outside main module", base.ShortPath(dir)) - } - } - } else if sub := search.InDir(dir, cfg.GOROOTsrc); sub != "" && sub != "." && !strings.Contains(sub, "@") { - pkg = filepath.ToSlash(sub) - } else if path := pathInModuleCache(dir); path != "" { - pkg = path - } else { - pkg = "" - if !iterating { - ModRoot() - base.Errorf("go: directory %s outside available modules", base.ShortPath(dir)) - } - } m.Pkgs = append(m.Pkgs, pkg) } - case strings.Contains(m.Pattern, "..."): - m.Pkgs = matchPackages(m.Pattern, loaded.tags, true, buildList) + case m.IsLiteral(): + m.Pkgs = []string{m.Pattern()} + + case strings.Contains(m.Pattern(), "..."): + m.Errs = m.Errs[:0] + matchPackages(m, loaded.tags, includeStd, buildList) - case m.Pattern == "all": + case m.Pattern() == "all": loaded.testAll = true if iterating { // Enumerate the packages in the main module. // We'll load the dependencies as we find them. - m.Pkgs = matchPackages("...", loaded.tags, false, []module.Version{Target}) + m.Errs = m.Errs[:0] + matchPackages(m, loaded.tags, omitStd, []module.Version{Target}) } else { // Starting with the packages in the main module, // enumerate the full list of "all". m.Pkgs = loaded.computePatternAll(m.Pkgs) } - case search.IsMetaPackage(m.Pattern): // std, cmd - if len(m.Pkgs) == 0 { - m.Pkgs = search.MatchPackages(m.Pattern).Pkgs + case m.Pattern() == "std" || m.Pattern() == "cmd": + if m.Pkgs == nil { + m.MatchPackages() // Locate the packages within GOROOT/src. } default: - m.Pkgs = []string{m.Pattern} + panic(fmt.Sprintf("internal error: modload missing case for pattern %s", m.Pattern())) } } } @@ -194,10 +130,7 @@ func ImportPathsQuiet(patterns []string, tags map[string]bool) []*search.Match { var matches []*search.Match for _, pattern := range search.CleanPatterns(patterns) { - matches = append(matches, &search.Match{ - Pattern: pattern, - Literal: !strings.Contains(pattern, "...") && !search.IsMetaPackage(pattern), - }) + matches = append(matches, search.NewMatch(pattern)) } loaded = newLoader(tags) @@ -238,6 +171,139 @@ func checkMultiplePaths() { base.ExitIfErrors() } +// matchLocalDirs is like m.MatchDirs, but tries to avoid scanning directories +// outside of the standard library and active modules. +func matchLocalDirs(m *search.Match) { + if !m.IsLocal() { + panic(fmt.Sprintf("internal error: resolveLocalDirs on non-local pattern %s", m.Pattern())) + } + + if i := strings.Index(m.Pattern(), "..."); i >= 0 { + // The pattern is local, but it is a wildcard. Its packages will + // only resolve to paths if they are inside of the standard + // library, the main module, or some dependency of the main + // module. Verify that before we walk the filesystem: a filesystem + // walk in a directory like /var or /etc can be very expensive! + dir := filepath.Dir(filepath.Clean(m.Pattern()[:i+3])) + absDir := dir + if !filepath.IsAbs(dir) { + absDir = filepath.Join(base.Cwd, dir) + } + if search.InDir(absDir, cfg.GOROOTsrc) == "" && search.InDir(absDir, ModRoot()) == "" && pathInModuleCache(absDir) == "" { + m.Dirs = []string{} + m.AddError(fmt.Errorf("directory prefix %s outside available modules", base.ShortPath(absDir))) + return + } + } + + m.MatchDirs() +} + +// resolveLocalPackage resolves a filesystem path to a package path. +func resolveLocalPackage(dir string) (string, error) { + var absDir string + if filepath.IsAbs(dir) { + absDir = filepath.Clean(dir) + } else { + absDir = filepath.Join(base.Cwd, dir) + } + + bp, err := cfg.BuildContext.ImportDir(absDir, 0) + if err != nil && (bp == nil || len(bp.IgnoredGoFiles) == 0) { + // golang.org/issue/32917: We should resolve a relative path to a + // package path only if the relative path actually contains the code + // for that package. + // + // If the named directory does not exist or contains no Go files, + // the package does not exist. + // Other errors may affect package loading, but not resolution. + if _, err := os.Stat(absDir); err != nil { + if os.IsNotExist(err) { + // Canonicalize OS-specific errors to errDirectoryNotFound so that error + // messages will be easier for users to search for. + return "", &os.PathError{Op: "stat", Path: absDir, Err: errDirectoryNotFound} + } + return "", err + } + if _, noGo := err.(*build.NoGoError); noGo { + // A directory that does not contain any Go source files — even ignored + // ones! — is not a Go package, and we can't resolve it to a package + // path because that path could plausibly be provided by some other + // module. + // + // Any other error indicates that the package “exists” (at least in the + // sense that it cannot exist in any other module), but has some other + // problem (such as a syntax error). + return "", err + } + } + + if modRoot != "" && absDir == modRoot { + if absDir == cfg.GOROOTsrc { + return "", errPkgIsGorootSrc + } + return targetPrefix, nil + } + + // Note: The checks for @ here are just to avoid misinterpreting + // the module cache directories (formerly GOPATH/src/mod/foo@v1.5.2/bar). + // It's not strictly necessary but helpful to keep the checks. + if modRoot != "" && strings.HasPrefix(absDir, modRoot+string(filepath.Separator)) && !strings.Contains(absDir[len(modRoot):], "@") { + suffix := filepath.ToSlash(absDir[len(modRoot):]) + if strings.HasPrefix(suffix, "/vendor/") { + if cfg.BuildMod != "vendor" { + return "", fmt.Errorf("without -mod=vendor, directory %s has no package path", absDir) + } + + readVendorList() + pkg := strings.TrimPrefix(suffix, "/vendor/") + if _, ok := vendorPkgModule[pkg]; !ok { + return "", fmt.Errorf("directory %s is not a package listed in vendor/modules.txt", absDir) + } + return pkg, nil + } + + if targetPrefix == "" { + pkg := strings.TrimPrefix(suffix, "/") + if pkg == "builtin" { + // "builtin" is a pseudo-package with a real source file. + // It's not included in "std", so it shouldn't resolve from "." + // within module "std" either. + return "", errPkgIsBuiltin + } + return pkg, nil + } + + pkg := targetPrefix + suffix + if _, ok, err := dirInModule(pkg, targetPrefix, modRoot, true); err != nil { + return "", err + } else if !ok { + return "", &PackageNotInModuleError{Mod: Target, Pattern: pkg} + } + return pkg, nil + } + + if sub := search.InDir(absDir, cfg.GOROOTsrc); sub != "" && sub != "." && !strings.Contains(sub, "@") { + pkg := filepath.ToSlash(sub) + if pkg == "builtin" { + return "", errPkgIsBuiltin + } + return pkg, nil + } + + pkg := pathInModuleCache(absDir) + if pkg == "" { + return "", fmt.Errorf("directory %s outside available modules", base.ShortPath(absDir)) + } + return pkg, nil +} + +var ( + errDirectoryNotFound = errors.New("directory not found") + errPkgIsGorootSrc = errors.New("GOROOT/src is not an importable package") + errPkgIsBuiltin = errors.New(`"builtin" is a pseudo-package, not an importable package`) +) + // pathInModuleCache returns the import path of the directory dir, // if dir is in the module cache copy of a module in our build list. func pathInModuleCache(dir string) string { @@ -267,32 +333,6 @@ func pathInModuleCache(dir string) string { return "" } -var dirContainsPackageCache sync.Map // absolute dir → bool - -func dirContainsPackage(dir string) bool { - isPkg, ok := dirContainsPackageCache.Load(dir) - if !ok { - _, err := cfg.BuildContext.ImportDir(dir, 0) - if err == nil { - isPkg = true - } else { - if fi, statErr := os.Stat(dir); statErr != nil || !fi.IsDir() { - // A non-directory or inaccessible directory is not a Go package. - isPkg = false - } else if _, noGo := err.(*build.NoGoError); noGo { - // A directory containing no Go source files is not a Go package. - isPkg = false - } else { - // An error other than *build.NoGoError indicates that the package exists - // but has some other problem (such as a syntax error). - isPkg = true - } - } - isPkg, _ = dirContainsPackageCache.LoadOrStore(dir, isPkg) - } - return isPkg.(bool) -} - // ImportFromFiles adds modules to the build list as needed // to satisfy the imports in the named Go source files. func ImportFromFiles(gofiles []string) { @@ -386,7 +426,7 @@ func loadAll(testAll bool) []string { loaded.testRoots = true } all := TargetPackages("...") - loaded.load(func() []string { return all }) + loaded.load(func() []string { return all.Pkgs }) checkMultiplePaths() WriteGoMod() @@ -398,6 +438,9 @@ func loadAll(testAll bool) []string { } paths = append(paths, pkg.path) } + for _, err := range all.Errs { + base.Errorf("%v", err) + } base.ExitIfErrors() return paths } @@ -405,12 +448,14 @@ func loadAll(testAll bool) []string { // TargetPackages returns the list of packages in the target (top-level) module // matching pattern, which may be relative to the working directory, under all // build tag settings. -func TargetPackages(pattern string) []string { +func TargetPackages(pattern string) *search.Match { // TargetPackages is relative to the main module, so ensure that the main // module is a thing that can contain packages. ModRoot() - return matchPackages(pattern, imports.AnyTags(), false, []module.Version{Target}) + m := search.NewMatch(pattern) + matchPackages(m, imports.AnyTags(), omitStd, []module.Version{Target}) + return m } // BuildList returns the module build list, @@ -655,13 +700,13 @@ func (ld *loader) load(roots func() []string) { if err.newMissingVersion != "" { base.Fatalf("go: %s: package provided by %s at latest version %s but not at required version %s", pkg.stackText(), err.Module.Path, err.Module.Version, err.newMissingVersion) } + fmt.Fprintf(os.Stderr, "go: found %s in %s %s\n", pkg.path, err.Module.Path, err.Module.Version) if added[pkg.path] { base.Fatalf("go: %s: looping trying to add package", pkg.stackText()) } added[pkg.path] = true numAdded++ if !haveMod[err.Module] { - fmt.Fprintf(os.Stderr, "go: found %s in %s %s\n", pkg.path, err.Module.Path, err.Module.Version) haveMod[err.Module] = true modAddedBy[err.Module] = pkg buildList = append(buildList, err.Module) @@ -761,7 +806,7 @@ func (ld *loader) doPkg(item interface{}) { // Leave for error during load. return } - if build.IsLocalImport(pkg.path) { + if build.IsLocalImport(pkg.path) || filepath.IsAbs(pkg.path) { // Leave for error during load. // (Module mode does not allow local imports.) return @@ -996,354 +1041,3 @@ func WhyDepth(path string) int { } return n } - -// Replacement returns the replacement for mod, if any, from go.mod. -// If there is no replacement for mod, Replacement returns -// a module.Version with Path == "". -func Replacement(mod module.Version) module.Version { - if index != nil { - if r, ok := index.replace[mod]; ok { - return r - } - if r, ok := index.replace[module.Version{Path: mod.Path}]; ok { - return r - } - } - return module.Version{} -} - -// mvsReqs implements mvs.Reqs for module semantic versions, -// with any exclusions or replacements applied internally. -type mvsReqs struct { - buildList []module.Version - cache par.Cache - versions sync.Map -} - -// Reqs returns the current module requirement graph. -// Future calls to SetBuildList do not affect the operation -// of the returned Reqs. -func Reqs() mvs.Reqs { - r := &mvsReqs{ - buildList: buildList, - } - return r -} - -func (r *mvsReqs) Required(mod module.Version) ([]module.Version, error) { - type cached struct { - list []module.Version - err error - } - - c := r.cache.Do(mod, func() interface{} { - list, err := r.required(mod) - if err != nil { - return cached{nil, err} - } - for i, mv := range list { - if index != nil { - for index.exclude[mv] { - mv1, err := r.next(mv) - if err != nil { - return cached{nil, err} - } - if mv1.Version == "none" { - return cached{nil, fmt.Errorf("%s(%s) depends on excluded %s(%s) with no newer version available", mod.Path, mod.Version, mv.Path, mv.Version)} - } - mv = mv1 - } - } - list[i] = mv - } - - return cached{list, nil} - }).(cached) - - return c.list, c.err -} - -var vendorOnce sync.Once - -type vendorMetadata struct { - Explicit bool - Replacement module.Version -} - -var ( - vendorList []module.Version // modules that contribute packages to the build, in order of appearance - vendorReplaced []module.Version // all replaced modules; may or may not also contribute packages - vendorVersion map[string]string // module path → selected version (if known) - vendorPkgModule map[string]module.Version // package → containing module - vendorMeta map[module.Version]vendorMetadata -) - -// readVendorList reads the list of vendored modules from vendor/modules.txt. -func readVendorList() { - vendorOnce.Do(func() { - vendorList = nil - vendorPkgModule = make(map[string]module.Version) - vendorVersion = make(map[string]string) - vendorMeta = make(map[module.Version]vendorMetadata) - data, err := ioutil.ReadFile(filepath.Join(ModRoot(), "vendor/modules.txt")) - if err != nil { - if !errors.Is(err, os.ErrNotExist) { - base.Fatalf("go: %s", err) - } - return - } - - var mod module.Version - for _, line := range strings.Split(string(data), "\n") { - if strings.HasPrefix(line, "# ") { - f := strings.Fields(line) - - if len(f) < 3 { - continue - } - if semver.IsValid(f[2]) { - // A module, but we don't yet know whether it is in the build list or - // only included to indicate a replacement. - mod = module.Version{Path: f[1], Version: f[2]} - f = f[3:] - } else if f[2] == "=>" { - // A wildcard replacement found in the main module's go.mod file. - mod = module.Version{Path: f[1]} - f = f[2:] - } else { - // Not a version or a wildcard replacement. - // We don't know how to interpret this module line, so ignore it. - mod = module.Version{} - continue - } - - if len(f) >= 2 && f[0] == "=>" { - meta := vendorMeta[mod] - if len(f) == 2 { - // File replacement. - meta.Replacement = module.Version{Path: f[1]} - vendorReplaced = append(vendorReplaced, mod) - } else if len(f) == 3 && semver.IsValid(f[2]) { - // Path and version replacement. - meta.Replacement = module.Version{Path: f[1], Version: f[2]} - vendorReplaced = append(vendorReplaced, mod) - } else { - // We don't understand this replacement. Ignore it. - } - vendorMeta[mod] = meta - } - continue - } - - // Not a module line. Must be a package within a module or a metadata - // directive, either of which requires a preceding module line. - if mod.Path == "" { - continue - } - - if strings.HasPrefix(line, "## ") { - // Metadata. Take the union of annotations across multiple lines, if present. - meta := vendorMeta[mod] - for _, entry := range strings.Split(strings.TrimPrefix(line, "## "), ";") { - entry = strings.TrimSpace(entry) - if entry == "explicit" { - meta.Explicit = true - } - // All other tokens are reserved for future use. - } - vendorMeta[mod] = meta - continue - } - - if f := strings.Fields(line); len(f) == 1 && module.CheckImportPath(f[0]) == nil { - // A package within the current module. - vendorPkgModule[f[0]] = mod - - // Since this module provides a package for the build, we know that it - // is in the build list and is the selected version of its path. - // If this information is new, record it. - if v, ok := vendorVersion[mod.Path]; !ok || semver.Compare(v, mod.Version) < 0 { - vendorList = append(vendorList, mod) - vendorVersion[mod.Path] = mod.Version - } - } - } - }) -} - -func (r *mvsReqs) modFileToList(f *modfile.File) []module.Version { - list := make([]module.Version, 0, len(f.Require)) - for _, r := range f.Require { - list = append(list, r.Mod) - } - return list -} - -// required returns a unique copy of the requirements of mod. -func (r *mvsReqs) required(mod module.Version) ([]module.Version, error) { - if mod == Target { - if modFile != nil && modFile.Go != nil { - r.versions.LoadOrStore(mod, modFile.Go.Version) - } - return append([]module.Version(nil), r.buildList[1:]...), nil - } - - if cfg.BuildMod == "vendor" { - // For every module other than the target, - // return the full list of modules from modules.txt. - readVendorList() - return append([]module.Version(nil), vendorList...), nil - } - - origPath := mod.Path - if repl := Replacement(mod); repl.Path != "" { - if repl.Version == "" { - // TODO: need to slip the new version into the tags list etc. - dir := repl.Path - if !filepath.IsAbs(dir) { - dir = filepath.Join(ModRoot(), dir) - } - gomod := filepath.Join(dir, "go.mod") - data, err := ioutil.ReadFile(gomod) - if err != nil { - return nil, fmt.Errorf("parsing %s: %v", base.ShortPath(gomod), err) - } - f, err := modfile.ParseLax(gomod, data, nil) - if err != nil { - return nil, fmt.Errorf("parsing %s: %v", base.ShortPath(gomod), err) - } - if f.Go != nil { - r.versions.LoadOrStore(mod, f.Go.Version) - } - return r.modFileToList(f), nil - } - mod = repl - } - - if mod.Version == "none" { - return nil, nil - } - - if !semver.IsValid(mod.Version) { - // Disallow the broader queries supported by fetch.Lookup. - base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", mod.Path, mod.Version) - } - - data, err := modfetch.GoMod(mod.Path, mod.Version) - if err != nil { - return nil, err - } - f, err := modfile.ParseLax("go.mod", data, nil) - if err != nil { - return nil, module.VersionError(mod, fmt.Errorf("parsing go.mod: %v", err)) - } - - if f.Module == nil { - return nil, module.VersionError(mod, errors.New("parsing go.mod: missing module line")) - } - if mpath := f.Module.Mod.Path; mpath != origPath && mpath != mod.Path { - return nil, module.VersionError(mod, fmt.Errorf(`parsing go.mod: - module declares its path as: %s - but was required as: %s`, mpath, mod.Path)) - } - if f.Go != nil { - r.versions.LoadOrStore(mod, f.Go.Version) - } - - return r.modFileToList(f), nil -} - -func (*mvsReqs) Max(v1, v2 string) string { - if v1 != "" && semver.Compare(v1, v2) == -1 { - return v2 - } - return v1 -} - -// Upgrade is a no-op, here to implement mvs.Reqs. -// The upgrade logic for go get -u is in ../modget/get.go. -func (*mvsReqs) Upgrade(m module.Version) (module.Version, error) { - return m, nil -} - -func versions(path string) ([]string, error) { - // Note: modfetch.Lookup and repo.Versions are cached, - // so there's no need for us to add extra caching here. - var versions []string - err := modfetch.TryProxies(func(proxy string) error { - repo, err := modfetch.Lookup(proxy, path) - if err == nil { - versions, err = repo.Versions("") - } - return err - }) - return versions, err -} - -// Previous returns the tagged version of m.Path immediately prior to -// m.Version, or version "none" if no prior version is tagged. -func (*mvsReqs) Previous(m module.Version) (module.Version, error) { - list, err := versions(m.Path) - if err != nil { - return module.Version{}, err - } - i := sort.Search(len(list), func(i int) bool { return semver.Compare(list[i], m.Version) >= 0 }) - if i > 0 { - return module.Version{Path: m.Path, Version: list[i-1]}, nil - } - return module.Version{Path: m.Path, Version: "none"}, nil -} - -// next returns the next version of m.Path after m.Version. -// It is only used by the exclusion processing in the Required method, -// not called directly by MVS. -func (*mvsReqs) next(m module.Version) (module.Version, error) { - list, err := versions(m.Path) - if err != nil { - return module.Version{}, err - } - i := sort.Search(len(list), func(i int) bool { return semver.Compare(list[i], m.Version) > 0 }) - if i < len(list) { - return module.Version{Path: m.Path, Version: list[i]}, nil - } - return module.Version{Path: m.Path, Version: "none"}, nil -} - -// fetch downloads the given module (or its replacement) -// and returns its location. -// -// The isLocal return value reports whether the replacement, -// if any, is local to the filesystem. -func fetch(mod module.Version) (dir string, isLocal bool, err error) { - if mod == Target { - return ModRoot(), true, nil - } - if r := Replacement(mod); r.Path != "" { - if r.Version == "" { - dir = r.Path - if !filepath.IsAbs(dir) { - dir = filepath.Join(ModRoot(), dir) - } - // Ensure that the replacement directory actually exists: - // dirInModule does not report errors for missing modules, - // so if we don't report the error now, later failures will be - // very mysterious. - if _, err := os.Stat(dir); err != nil { - if os.IsNotExist(err) { - // Semantically the module version itself “exists” — we just don't - // have its source code. Remove the equivalence to os.ErrNotExist, - // and make the message more concise while we're at it. - err = fmt.Errorf("replacement directory %s does not exist", r.Path) - } else { - err = fmt.Errorf("replacement directory %s: %w", r.Path, err) - } - return dir, true, module.VersionError(mod, err) - } - return dir, true, nil - } - mod = r - } - - dir, err = modfetch.Download(mod) - return dir, false, err -} diff --git a/libgo/go/cmd/go/internal/modload/modfile.go b/libgo/go/cmd/go/internal/modload/modfile.go new file mode 100644 index 00000000000..9f4ec5a49fc --- /dev/null +++ b/libgo/go/cmd/go/internal/modload/modfile.go @@ -0,0 +1,164 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package modload + +import ( + "cmd/go/internal/base" + "cmd/go/internal/cfg" + + "golang.org/x/mod/modfile" + "golang.org/x/mod/module" +) + +var modFile *modfile.File + +// A modFileIndex is an index of data corresponding to a modFile +// at a specific point in time. +type modFileIndex struct { + data []byte + dataNeedsFix bool // true if fixVersion applied a change while parsing data + module module.Version + goVersion string + require map[module.Version]requireMeta + replace map[module.Version]module.Version + exclude map[module.Version]bool +} + +// index is the index of the go.mod file as of when it was last read or written. +var index *modFileIndex + +type requireMeta struct { + indirect bool +} + +// Allowed reports whether module m is allowed (not excluded) by the main module's go.mod. +func Allowed(m module.Version) bool { + return index == nil || !index.exclude[m] +} + +// Replacement returns the replacement for mod, if any, from go.mod. +// If there is no replacement for mod, Replacement returns +// a module.Version with Path == "". +func Replacement(mod module.Version) module.Version { + if index != nil { + if r, ok := index.replace[mod]; ok { + return r + } + if r, ok := index.replace[module.Version{Path: mod.Path}]; ok { + return r + } + } + return module.Version{} +} + +// indexModFile rebuilds the index of modFile. +// If modFile has been changed since it was first read, +// modFile.Cleanup must be called before indexModFile. +func indexModFile(data []byte, modFile *modfile.File, needsFix bool) *modFileIndex { + i := new(modFileIndex) + i.data = data + i.dataNeedsFix = needsFix + + i.module = module.Version{} + if modFile.Module != nil { + i.module = modFile.Module.Mod + } + + i.goVersion = "" + if modFile.Go != nil { + i.goVersion = modFile.Go.Version + } + + i.require = make(map[module.Version]requireMeta, len(modFile.Require)) + for _, r := range modFile.Require { + i.require[r.Mod] = requireMeta{indirect: r.Indirect} + } + + i.replace = make(map[module.Version]module.Version, len(modFile.Replace)) + for _, r := range modFile.Replace { + if prev, dup := i.replace[r.Old]; dup && prev != r.New { + base.Fatalf("go: conflicting replacements for %v:\n\t%v\n\t%v", r.Old, prev, r.New) + } + i.replace[r.Old] = r.New + } + + i.exclude = make(map[module.Version]bool, len(modFile.Exclude)) + for _, x := range modFile.Exclude { + i.exclude[x.Mod] = true + } + + return i +} + +// modFileIsDirty reports whether the go.mod file differs meaningfully +// from what was indexed. +// If modFile has been changed (even cosmetically) since it was first read, +// modFile.Cleanup must be called before modFileIsDirty. +func (i *modFileIndex) modFileIsDirty(modFile *modfile.File) bool { + if i == nil { + return modFile != nil + } + + if i.dataNeedsFix { + return true + } + + if modFile.Module == nil { + if i.module != (module.Version{}) { + return true + } + } else if modFile.Module.Mod != i.module { + return true + } + + if modFile.Go == nil { + if i.goVersion != "" { + return true + } + } else if modFile.Go.Version != i.goVersion { + if i.goVersion == "" && cfg.BuildMod == "readonly" { + // go.mod files did not always require a 'go' version, so do not error out + // if one is missing — we may be inside an older module in the module + // cache, and should bias toward providing useful behavior. + } else { + return true + } + } + + if len(modFile.Require) != len(i.require) || + len(modFile.Replace) != len(i.replace) || + len(modFile.Exclude) != len(i.exclude) { + return true + } + + for _, r := range modFile.Require { + if meta, ok := i.require[r.Mod]; !ok { + return true + } else if r.Indirect != meta.indirect { + if cfg.BuildMod == "readonly" { + // The module's requirements are consistent; only the "// indirect" + // comments that are wrong. But those are only guaranteed to be accurate + // after a "go mod tidy" — it's a good idea to run those before + // committing a change, but it's certainly not mandatory. + } else { + return true + } + } + } + + for _, r := range modFile.Replace { + if r.New != i.replace[r.Old] { + return true + } + } + + for _, x := range modFile.Exclude { + if !i.exclude[x.Mod] { + return true + } + } + + return false +} diff --git a/libgo/go/cmd/go/internal/modload/mvs.go b/libgo/go/cmd/go/internal/modload/mvs.go new file mode 100644 index 00000000000..5dd009d31df --- /dev/null +++ b/libgo/go/cmd/go/internal/modload/mvs.go @@ -0,0 +1,259 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package modload + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "sort" + "sync" + + "cmd/go/internal/base" + "cmd/go/internal/cfg" + "cmd/go/internal/lockedfile" + "cmd/go/internal/modfetch" + "cmd/go/internal/mvs" + "cmd/go/internal/par" + + "golang.org/x/mod/modfile" + "golang.org/x/mod/module" + "golang.org/x/mod/semver" +) + +// mvsReqs implements mvs.Reqs for module semantic versions, +// with any exclusions or replacements applied internally. +type mvsReqs struct { + buildList []module.Version + cache par.Cache + versions sync.Map +} + +// Reqs returns the current module requirement graph. +// Future calls to SetBuildList do not affect the operation +// of the returned Reqs. +func Reqs() mvs.Reqs { + r := &mvsReqs{ + buildList: buildList, + } + return r +} + +func (r *mvsReqs) Required(mod module.Version) ([]module.Version, error) { + type cached struct { + list []module.Version + err error + } + + c := r.cache.Do(mod, func() interface{} { + list, err := r.required(mod) + if err != nil { + return cached{nil, err} + } + for i, mv := range list { + if index != nil { + for index.exclude[mv] { + mv1, err := r.next(mv) + if err != nil { + return cached{nil, err} + } + if mv1.Version == "none" { + return cached{nil, fmt.Errorf("%s(%s) depends on excluded %s(%s) with no newer version available", mod.Path, mod.Version, mv.Path, mv.Version)} + } + mv = mv1 + } + } + list[i] = mv + } + + return cached{list, nil} + }).(cached) + + return c.list, c.err +} + +func (r *mvsReqs) modFileToList(f *modfile.File) []module.Version { + list := make([]module.Version, 0, len(f.Require)) + for _, r := range f.Require { + list = append(list, r.Mod) + } + return list +} + +// required returns a unique copy of the requirements of mod. +func (r *mvsReqs) required(mod module.Version) ([]module.Version, error) { + if mod == Target { + if modFile != nil && modFile.Go != nil { + r.versions.LoadOrStore(mod, modFile.Go.Version) + } + return append([]module.Version(nil), r.buildList[1:]...), nil + } + + if cfg.BuildMod == "vendor" { + // For every module other than the target, + // return the full list of modules from modules.txt. + readVendorList() + return append([]module.Version(nil), vendorList...), nil + } + + origPath := mod.Path + if repl := Replacement(mod); repl.Path != "" { + if repl.Version == "" { + // TODO: need to slip the new version into the tags list etc. + dir := repl.Path + if !filepath.IsAbs(dir) { + dir = filepath.Join(ModRoot(), dir) + } + gomod := filepath.Join(dir, "go.mod") + data, err := lockedfile.Read(gomod) + if err != nil { + return nil, fmt.Errorf("parsing %s: %v", base.ShortPath(gomod), err) + } + f, err := modfile.ParseLax(gomod, data, nil) + if err != nil { + return nil, fmt.Errorf("parsing %s: %v", base.ShortPath(gomod), err) + } + if f.Go != nil { + r.versions.LoadOrStore(mod, f.Go.Version) + } + return r.modFileToList(f), nil + } + mod = repl + } + + if mod.Version == "none" { + return nil, nil + } + + if !semver.IsValid(mod.Version) { + // Disallow the broader queries supported by fetch.Lookup. + base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", mod.Path, mod.Version) + } + + data, err := modfetch.GoMod(mod.Path, mod.Version) + if err != nil { + return nil, err + } + f, err := modfile.ParseLax("go.mod", data, nil) + if err != nil { + return nil, module.VersionError(mod, fmt.Errorf("parsing go.mod: %v", err)) + } + + if f.Module == nil { + return nil, module.VersionError(mod, errors.New("parsing go.mod: missing module line")) + } + if mpath := f.Module.Mod.Path; mpath != origPath && mpath != mod.Path { + return nil, module.VersionError(mod, fmt.Errorf(`parsing go.mod: + module declares its path as: %s + but was required as: %s`, mpath, origPath)) + } + if f.Go != nil { + r.versions.LoadOrStore(mod, f.Go.Version) + } + + return r.modFileToList(f), nil +} + +// Max returns the maximum of v1 and v2 according to semver.Compare. +// +// As a special case, the version "" is considered higher than all other +// versions. The main module (also known as the target) has no version and must +// be chosen over other versions of the same module in the module dependency +// graph. +func (*mvsReqs) Max(v1, v2 string) string { + if v1 != "" && semver.Compare(v1, v2) == -1 { + return v2 + } + return v1 +} + +// Upgrade is a no-op, here to implement mvs.Reqs. +// The upgrade logic for go get -u is in ../modget/get.go. +func (*mvsReqs) Upgrade(m module.Version) (module.Version, error) { + return m, nil +} + +func versions(path string) ([]string, error) { + // Note: modfetch.Lookup and repo.Versions are cached, + // so there's no need for us to add extra caching here. + var versions []string + err := modfetch.TryProxies(func(proxy string) error { + repo, err := modfetch.Lookup(proxy, path) + if err == nil { + versions, err = repo.Versions("") + } + return err + }) + return versions, err +} + +// Previous returns the tagged version of m.Path immediately prior to +// m.Version, or version "none" if no prior version is tagged. +func (*mvsReqs) Previous(m module.Version) (module.Version, error) { + list, err := versions(m.Path) + if err != nil { + return module.Version{}, err + } + i := sort.Search(len(list), func(i int) bool { return semver.Compare(list[i], m.Version) >= 0 }) + if i > 0 { + return module.Version{Path: m.Path, Version: list[i-1]}, nil + } + return module.Version{Path: m.Path, Version: "none"}, nil +} + +// next returns the next version of m.Path after m.Version. +// It is only used by the exclusion processing in the Required method, +// not called directly by MVS. +func (*mvsReqs) next(m module.Version) (module.Version, error) { + list, err := versions(m.Path) + if err != nil { + return module.Version{}, err + } + i := sort.Search(len(list), func(i int) bool { return semver.Compare(list[i], m.Version) > 0 }) + if i < len(list) { + return module.Version{Path: m.Path, Version: list[i]}, nil + } + return module.Version{Path: m.Path, Version: "none"}, nil +} + +// fetch downloads the given module (or its replacement) +// and returns its location. +// +// The isLocal return value reports whether the replacement, +// if any, is local to the filesystem. +func fetch(mod module.Version) (dir string, isLocal bool, err error) { + if mod == Target { + return ModRoot(), true, nil + } + if r := Replacement(mod); r.Path != "" { + if r.Version == "" { + dir = r.Path + if !filepath.IsAbs(dir) { + dir = filepath.Join(ModRoot(), dir) + } + // Ensure that the replacement directory actually exists: + // dirInModule does not report errors for missing modules, + // so if we don't report the error now, later failures will be + // very mysterious. + if _, err := os.Stat(dir); err != nil { + if os.IsNotExist(err) { + // Semantically the module version itself “exists” — we just don't + // have its source code. Remove the equivalence to os.ErrNotExist, + // and make the message more concise while we're at it. + err = fmt.Errorf("replacement directory %s does not exist", r.Path) + } else { + err = fmt.Errorf("replacement directory %s: %w", r.Path, err) + } + return dir, true, module.VersionError(mod, err) + } + return dir, true, nil + } + mod = r + } + + dir, err = modfetch.Download(mod) + return dir, false, err +} diff --git a/libgo/go/cmd/go/internal/modload/query.go b/libgo/go/cmd/go/internal/modload/query.go index 031e45938a5..acc886bf213 100644 --- a/libgo/go/cmd/go/internal/modload/query.go +++ b/libgo/go/cmd/go/internal/modload/query.go @@ -381,7 +381,8 @@ type QueryResult struct { // module and only the version "latest", without checking for other possible // modules. func QueryPackage(path, query string, allowed func(module.Version) bool) ([]QueryResult, error) { - if search.IsMetaPackage(path) || strings.Contains(path, "...") { + m := search.NewMatch(path) + if m.IsLocal() || !m.IsLiteral() { return nil, fmt.Errorf("pattern %s is not an importable package", path) } return QueryPattern(path, query, allowed) @@ -402,30 +403,42 @@ func QueryPackage(path, query string, allowed func(module.Version) bool) ([]Quer // possible modules. func QueryPattern(pattern, query string, allowed func(module.Version) bool) ([]QueryResult, error) { base := pattern - var match func(m module.Version, root string, isLocal bool) (pkgs []string) + + firstError := func(m *search.Match) error { + if len(m.Errs) == 0 { + return nil + } + return m.Errs[0] + } + + var match func(mod module.Version, root string, isLocal bool) *search.Match if i := strings.Index(pattern, "..."); i >= 0 { base = pathpkg.Dir(pattern[:i+3]) - match = func(m module.Version, root string, isLocal bool) []string { - return matchPackages(pattern, imports.AnyTags(), false, []module.Version{m}) + match = func(mod module.Version, root string, isLocal bool) *search.Match { + m := search.NewMatch(pattern) + matchPackages(m, imports.AnyTags(), omitStd, []module.Version{mod}) + return m } } else { - match = func(m module.Version, root string, isLocal bool) []string { - prefix := m.Path - if m == Target { + match = func(mod module.Version, root string, isLocal bool) *search.Match { + m := search.NewMatch(pattern) + prefix := mod.Path + if mod == Target { prefix = targetPrefix } - if _, ok := dirInModule(pattern, prefix, root, isLocal); ok { - return []string{pattern} - } else { - return nil + if _, ok, err := dirInModule(pattern, prefix, root, isLocal); err != nil { + m.AddError(err) + } else if ok { + m.Pkgs = []string{pattern} } + return m } } if HasModRoot() { - pkgs := match(Target, modRoot, true) - if len(pkgs) > 0 { + m := match(Target, modRoot, true) + if len(m.Pkgs) > 0 { if query != "latest" { return nil, fmt.Errorf("can't query specific version for package %s in the main module (%s)", pattern, Target.Path) } @@ -435,9 +448,12 @@ func QueryPattern(pattern, query string, allowed func(module.Version) bool) ([]Q return []QueryResult{{ Mod: Target, Rev: &modfetch.RevInfo{Version: Target.Version}, - Packages: pkgs, + Packages: m.Pkgs, }}, nil } + if err := firstError(m); err != nil { + return nil, err + } } var ( @@ -445,13 +461,18 @@ func QueryPattern(pattern, query string, allowed func(module.Version) bool) ([]Q candidateModules = modulePrefixesExcludingTarget(base) ) if len(candidateModules) == 0 { - return nil, fmt.Errorf("package %s is not in the main module (%s)", pattern, Target.Path) + return nil, &PackageNotInModuleError{ + Mod: Target, + Query: query, + Pattern: pattern, + } } err := modfetch.TryProxies(func(proxy string) error { queryModule := func(path string) (r QueryResult, err error) { + current := findCurrentVersion(path) r.Mod.Path = path - r.Rev, err = queryProxy(proxy, path, query, "", allowed) + r.Rev, err = queryProxy(proxy, path, query, current, allowed) if err != nil { return r, err } @@ -460,8 +481,12 @@ func QueryPattern(pattern, query string, allowed func(module.Version) bool) ([]Q if err != nil { return r, err } - r.Packages = match(r.Mod, root, isLocal) + m := match(r.Mod, root, isLocal) + r.Packages = m.Pkgs if len(r.Packages) == 0 { + if err := firstError(m); err != nil { + return r, err + } return r, &PackageNotInModuleError{ Mod: r.Mod, Replacement: Replacement(r.Mod), @@ -503,6 +528,15 @@ func modulePrefixesExcludingTarget(path string) []string { return prefixes } +func findCurrentVersion(path string) string { + for _, m := range buildList { + if m.Path == path { + return m.Version + } + } + return "" +} + type prefixResult struct { QueryResult err error @@ -541,7 +575,9 @@ func queryPrefixModules(candidateModules []string, queryModule func(path string) case nil: found = append(found, r.QueryResult) case *PackageNotInModuleError: - if noPackage == nil { + // Given the option, prefer to attribute “package not in module” + // to modules other than the main one. + if noPackage == nil || noPackage.Mod == Target { noPackage = rErr } case *NoMatchingVersionError: @@ -626,6 +662,13 @@ type PackageNotInModuleError struct { } func (e *PackageNotInModuleError) Error() string { + if e.Mod == Target { + if strings.Contains(e.Pattern, "...") { + return fmt.Sprintf("main module (%s) does not contain packages matching %s", Target.Path, e.Pattern) + } + return fmt.Sprintf("main module (%s) does not contain package %s", Target.Path, e.Pattern) + } + found := "" if r := e.Replacement; r.Path != "" { replacement := r.Path @@ -647,14 +690,21 @@ func (e *PackageNotInModuleError) Error() string { return fmt.Sprintf("module %s@%s found%s, but does not contain package %s", e.Mod.Path, e.Query, found, e.Pattern) } +func (e *PackageNotInModuleError) ImportPath() string { + if !strings.Contains(e.Pattern, "...") { + return e.Pattern + } + return "" +} + // ModuleHasRootPackage returns whether module m contains a package m.Path. func ModuleHasRootPackage(m module.Version) (bool, error) { root, isLocal, err := fetch(m) if err != nil { return false, err } - _, ok := dirInModule(m.Path, m.Path, root, isLocal) - return ok, nil + _, ok, err := dirInModule(m.Path, m.Path, root, isLocal) + return ok, err } func versionHasGoMod(m module.Version) (bool, error) { diff --git a/libgo/go/cmd/go/internal/modload/query_test.go b/libgo/go/cmd/go/internal/modload/query_test.go index 15470e26853..247e4c40d24 100644 --- a/libgo/go/cmd/go/internal/modload/query_test.go +++ b/libgo/go/cmd/go/internal/modload/query_test.go @@ -15,8 +15,6 @@ import ( "testing" "cmd/go/internal/cfg" - "cmd/go/internal/modfetch" - "cmd/go/internal/modfetch/codehost" "golang.org/x/mod/module" ) @@ -36,8 +34,7 @@ func testMain(m *testing.M) int { os.Setenv("GOPATH", dir) cfg.BuildContext.GOPATH = dir - modfetch.PkgMod = filepath.Join(dir, "pkg/mod") - codehost.WorkRoot = filepath.Join(dir, "codework") + cfg.GOMODCACHE = filepath.Join(dir, "pkg/mod") return m.Run() } diff --git a/libgo/go/cmd/go/internal/modload/search.go b/libgo/go/cmd/go/internal/modload/search.go index a303f51858a..146c94a6aeb 100644 --- a/libgo/go/cmd/go/internal/modload/search.go +++ b/libgo/go/cmd/go/internal/modload/search.go @@ -8,9 +8,9 @@ import ( "fmt" "os" "path/filepath" + "runtime" "strings" - "cmd/go/internal/base" "cmd/go/internal/cfg" "cmd/go/internal/imports" "cmd/go/internal/search" @@ -18,14 +18,24 @@ import ( "golang.org/x/mod/module" ) -// matchPackages returns a list of packages in the list of modules -// matching the pattern. Package loading assumes the given set of tags. -func matchPackages(pattern string, tags map[string]bool, useStd bool, modules []module.Version) []string { - match := func(string) bool { return true } +type stdFilter int8 + +const ( + omitStd = stdFilter(iota) + includeStd +) + +// matchPackages is like m.MatchPackages, but uses a local variable (rather than +// a global) for tags, can include or exclude packages in the standard library, +// and is restricted to the given list of modules. +func matchPackages(m *search.Match, tags map[string]bool, filter stdFilter, modules []module.Version) { + m.Pkgs = []string{} + + isMatch := func(string) bool { return true } treeCanMatch := func(string) bool { return true } - if !search.IsMetaPackage(pattern) { - match = search.MatchPattern(pattern) - treeCanMatch = search.TreeCanMatchPattern(pattern) + if !m.IsMeta() { + isMatch = search.MatchPattern(m.Pattern()) + treeCanMatch = search.TreeCanMatchPattern(m.Pattern()) } have := map[string]bool{ @@ -34,7 +44,6 @@ func matchPackages(pattern string, tags map[string]bool, useStd bool, modules [] if !cfg.BuildContext.CgoEnabled { have["runtime/cgo"] = true // ignore during walk } - var pkgs []string type pruning int8 const ( @@ -44,8 +53,9 @@ func matchPackages(pattern string, tags map[string]bool, useStd bool, modules [] walkPkgs := func(root, importPathRoot string, prune pruning) { root = filepath.Clean(root) - filepath.Walk(root, func(path string, fi os.FileInfo, err error) error { + err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error { if err != nil { + m.AddError(err) return nil } @@ -94,9 +104,9 @@ func matchPackages(pattern string, tags map[string]bool, useStd bool, modules [] if !have[name] { have[name] = true - if match(name) { + if isMatch(name) { if _, _, err := scanDir(path, tags); err != imports.ErrNoGo { - pkgs = append(pkgs, name) + m.Pkgs = append(m.Pkgs, name) } } } @@ -106,9 +116,12 @@ func matchPackages(pattern string, tags map[string]bool, useStd bool, modules [] } return nil }) + if err != nil { + m.AddError(err) + } } - if useStd { + if filter == includeStd && runtime.Compiler != "gccgo" { walkPkgs(cfg.GOROOTsrc, "", pruneGoMod) if treeCanMatch("cmd") { walkPkgs(filepath.Join(cfg.GOROOTsrc, "cmd"), "cmd", pruneGoMod) @@ -120,7 +133,7 @@ func matchPackages(pattern string, tags map[string]bool, useStd bool, modules [] walkPkgs(ModRoot(), targetPrefix, pruneGoMod|pruneVendor) walkPkgs(filepath.Join(ModRoot(), "vendor"), "", pruneVendor) } - return pkgs + return } for _, mod := range modules { @@ -143,7 +156,7 @@ func matchPackages(pattern string, tags map[string]bool, useStd bool, modules [] var err error root, isLocal, err = fetch(mod) if err != nil { - base.Errorf("go: %v", err) + m.AddError(err) continue } modPrefix = mod.Path @@ -156,5 +169,5 @@ func matchPackages(pattern string, tags map[string]bool, useStd bool, modules [] walkPkgs(root, modPrefix, prune) } - return pkgs + return } diff --git a/libgo/go/cmd/go/internal/modload/vendor.go b/libgo/go/cmd/go/internal/modload/vendor.go new file mode 100644 index 00000000000..71f68efbcc1 --- /dev/null +++ b/libgo/go/cmd/go/internal/modload/vendor.go @@ -0,0 +1,217 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package modload + +import ( + "errors" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strings" + "sync" + + "cmd/go/internal/base" + + "golang.org/x/mod/module" + "golang.org/x/mod/semver" +) + +var ( + vendorOnce sync.Once + vendorList []module.Version // modules that contribute packages to the build, in order of appearance + vendorReplaced []module.Version // all replaced modules; may or may not also contribute packages + vendorVersion map[string]string // module path → selected version (if known) + vendorPkgModule map[string]module.Version // package → containing module + vendorMeta map[module.Version]vendorMetadata +) + +type vendorMetadata struct { + Explicit bool + Replacement module.Version +} + +// readVendorList reads the list of vendored modules from vendor/modules.txt. +func readVendorList() { + vendorOnce.Do(func() { + vendorList = nil + vendorPkgModule = make(map[string]module.Version) + vendorVersion = make(map[string]string) + vendorMeta = make(map[module.Version]vendorMetadata) + data, err := ioutil.ReadFile(filepath.Join(ModRoot(), "vendor/modules.txt")) + if err != nil { + if !errors.Is(err, os.ErrNotExist) { + base.Fatalf("go: %s", err) + } + return + } + + var mod module.Version + for _, line := range strings.Split(string(data), "\n") { + if strings.HasPrefix(line, "# ") { + f := strings.Fields(line) + + if len(f) < 3 { + continue + } + if semver.IsValid(f[2]) { + // A module, but we don't yet know whether it is in the build list or + // only included to indicate a replacement. + mod = module.Version{Path: f[1], Version: f[2]} + f = f[3:] + } else if f[2] == "=>" { + // A wildcard replacement found in the main module's go.mod file. + mod = module.Version{Path: f[1]} + f = f[2:] + } else { + // Not a version or a wildcard replacement. + // We don't know how to interpret this module line, so ignore it. + mod = module.Version{} + continue + } + + if len(f) >= 2 && f[0] == "=>" { + meta := vendorMeta[mod] + if len(f) == 2 { + // File replacement. + meta.Replacement = module.Version{Path: f[1]} + vendorReplaced = append(vendorReplaced, mod) + } else if len(f) == 3 && semver.IsValid(f[2]) { + // Path and version replacement. + meta.Replacement = module.Version{Path: f[1], Version: f[2]} + vendorReplaced = append(vendorReplaced, mod) + } else { + // We don't understand this replacement. Ignore it. + } + vendorMeta[mod] = meta + } + continue + } + + // Not a module line. Must be a package within a module or a metadata + // directive, either of which requires a preceding module line. + if mod.Path == "" { + continue + } + + if strings.HasPrefix(line, "## ") { + // Metadata. Take the union of annotations across multiple lines, if present. + meta := vendorMeta[mod] + for _, entry := range strings.Split(strings.TrimPrefix(line, "## "), ";") { + entry = strings.TrimSpace(entry) + if entry == "explicit" { + meta.Explicit = true + } + // All other tokens are reserved for future use. + } + vendorMeta[mod] = meta + continue + } + + if f := strings.Fields(line); len(f) == 1 && module.CheckImportPath(f[0]) == nil { + // A package within the current module. + vendorPkgModule[f[0]] = mod + + // Since this module provides a package for the build, we know that it + // is in the build list and is the selected version of its path. + // If this information is new, record it. + if v, ok := vendorVersion[mod.Path]; !ok || semver.Compare(v, mod.Version) < 0 { + vendorList = append(vendorList, mod) + vendorVersion[mod.Path] = mod.Version + } + } + } + }) +} + +// checkVendorConsistency verifies that the vendor/modules.txt file matches (if +// go 1.14) or at least does not contradict (go 1.13 or earlier) the +// requirements and replacements listed in the main module's go.mod file. +func checkVendorConsistency() { + readVendorList() + + pre114 := false + if modFile.Go == nil || semver.Compare("v"+modFile.Go.Version, "v1.14") < 0 { + // Go versions before 1.14 did not include enough information in + // vendor/modules.txt to check for consistency. + // If we know that we're on an earlier version, relax the consistency check. + pre114 = true + } + + vendErrors := new(strings.Builder) + vendErrorf := func(mod module.Version, format string, args ...interface{}) { + detail := fmt.Sprintf(format, args...) + if mod.Version == "" { + fmt.Fprintf(vendErrors, "\n\t%s: %s", mod.Path, detail) + } else { + fmt.Fprintf(vendErrors, "\n\t%s@%s: %s", mod.Path, mod.Version, detail) + } + } + + for _, r := range modFile.Require { + if !vendorMeta[r.Mod].Explicit { + if pre114 { + // Before 1.14, modules.txt did not indicate whether modules were listed + // explicitly in the main module's go.mod file. + // However, we can at least detect a version mismatch if packages were + // vendored from a non-matching version. + if vv, ok := vendorVersion[r.Mod.Path]; ok && vv != r.Mod.Version { + vendErrorf(r.Mod, fmt.Sprintf("is explicitly required in go.mod, but vendor/modules.txt indicates %s@%s", r.Mod.Path, vv)) + } + } else { + vendErrorf(r.Mod, "is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt") + } + } + } + + describe := func(m module.Version) string { + if m.Version == "" { + return m.Path + } + return m.Path + "@" + m.Version + } + + // We need to verify *all* replacements that occur in modfile: even if they + // don't directly apply to any module in the vendor list, the replacement + // go.mod file can affect the selected versions of other (transitive) + // dependencies + for _, r := range modFile.Replace { + vr := vendorMeta[r.Old].Replacement + if vr == (module.Version{}) { + if pre114 && (r.Old.Version == "" || vendorVersion[r.Old.Path] != r.Old.Version) { + // Before 1.14, modules.txt omitted wildcard replacements and + // replacements for modules that did not have any packages to vendor. + } else { + vendErrorf(r.Old, "is replaced in go.mod, but not marked as replaced in vendor/modules.txt") + } + } else if vr != r.New { + vendErrorf(r.Old, "is replaced by %s in go.mod, but marked as replaced by %s in vendor/modules.txt", describe(r.New), describe(vr)) + } + } + + for _, mod := range vendorList { + meta := vendorMeta[mod] + if meta.Explicit { + if _, inGoMod := index.require[mod]; !inGoMod { + vendErrorf(mod, "is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod") + } + } + } + + for _, mod := range vendorReplaced { + r := Replacement(mod) + if r == (module.Version{}) { + vendErrorf(mod, "is marked as replaced in vendor/modules.txt, but not replaced in go.mod") + continue + } + if meta := vendorMeta[mod]; r != meta.Replacement { + vendErrorf(mod, "is marked as replaced by %s in vendor/modules.txt, but replaced by %s in go.mod", describe(meta.Replacement), describe(r)) + } + } + + if vendErrors.Len() > 0 { + base.Fatalf("go: inconsistent vendoring in %s:%s\n\nrun 'go mod vendor' to sync, or use -mod=mod or -mod=readonly to ignore the vendor directory", modRoot, vendErrors) + } +} diff --git a/libgo/go/cmd/go/internal/mvs/mvs.go b/libgo/go/cmd/go/internal/mvs/mvs.go index dd3b3ccb865..1f8eaa1f601 100644 --- a/libgo/go/cmd/go/internal/mvs/mvs.go +++ b/libgo/go/cmd/go/internal/mvs/mvs.go @@ -115,7 +115,21 @@ func (e *BuildListError) Error() string { } // BuildList returns the build list for the target module. -// The first element is the target itself, with the remainder of the list sorted by path. +// +// target is the root vertex of a module requirement graph. For cmd/go, this is +// typically the main module, but note that this algorithm is not intended to +// be Go-specific: module paths and versions are treated as opaque values. +// +// reqs describes the module requirement graph and provides an opaque method +// for comparing versions. +// +// BuildList traverses the graph and returns a list containing the highest +// version for each visited module. The first element of the returned list is +// target itself; reqs.Max requires target.Version to compare higher than all +// other versions, so no other version can be selected. The remaining elements +// of the list are sorted by path. +// +// See https://research.swtch.com/vgo-mvs for details. func BuildList(target module.Version, reqs Reqs) ([]module.Version, error) { return buildList(target, reqs, nil) } @@ -220,10 +234,9 @@ func buildList(target module.Version, reqs Reqs, upgrade func(module.Version) (m // The final list is the minimum version of each module found in the graph. if v := min[target.Path]; v != target.Version { - // TODO(jayconrod): there is a special case in modload.mvsReqs.Max - // that prevents us from selecting a newer version of a module - // when the module has no version. This may only be the case for target. - // Should we always panic when target has a version? + // target.Version will be "" for modload, the main client of MVS. + // "" denotes the main module, which has no version. However, MVS treats + // version strings as opaque, so "" is not a special value here. // See golang.org/issue/31491, golang.org/issue/29773. panic(fmt.Sprintf("mistake: chose version %q instead of target %+v", v, target)) // TODO: Don't panic. } diff --git a/libgo/go/cmd/go/internal/renameio/renameio_test.go b/libgo/go/cmd/go/internal/renameio/renameio_test.go index ee2f3ba1bb8..df8ddabdb82 100644 --- a/libgo/go/cmd/go/internal/renameio/renameio_test.go +++ b/libgo/go/cmd/go/internal/renameio/renameio_test.go @@ -9,11 +9,13 @@ package renameio import ( "encoding/binary" "errors" + "internal/testenv" "io/ioutil" "math/rand" "os" "path/filepath" "runtime" + "strings" "sync" "sync/atomic" "syscall" @@ -24,6 +26,10 @@ import ( ) func TestConcurrentReadsAndWrites(t *testing.T) { + if runtime.GOOS == "darwin" && strings.HasSuffix(testenv.Builder(), "-10_14") { + testenv.SkipFlaky(t, 33041) + } + dir, err := ioutil.TempDir("", "renameio") if err != nil { t.Fatal(err) diff --git a/libgo/go/cmd/go/internal/search/search.go b/libgo/go/cmd/go/internal/search/search.go index ad33e60af14..4efef24152b 100644 --- a/libgo/go/cmd/go/internal/search/search.go +++ b/libgo/go/cmd/go/internal/search/search.go @@ -9,7 +9,6 @@ import ( "cmd/go/internal/cfg" "fmt" "go/build" - "log" "os" "path" "path/filepath" @@ -19,25 +18,97 @@ import ( // A Match represents the result of matching a single package pattern. type Match struct { - Pattern string // the pattern itself - Literal bool // whether it is a literal (no wildcards) - Pkgs []string // matching packages (dirs or import paths) + pattern string // the pattern itself + Dirs []string // if the pattern is local, directories that potentially contain matching packages + Pkgs []string // matching packages (import paths) + Errs []error // errors matching the patterns to packages, NOT errors loading those packages + + // Errs may be non-empty even if len(Pkgs) > 0, indicating that some matching + // packages could be located but results may be incomplete. + // If len(Pkgs) == 0 && len(Errs) == 0, the pattern is well-formed but did not + // match any packages. } -// MatchPackages returns all the packages that can be found -// under the $GOPATH directories and $GOROOT matching pattern. -// The pattern is either "all" (all packages), "std" (standard packages), -// "cmd" (standard commands), or a path including "...". -func MatchPackages(pattern string) *Match { - m := &Match{ - Pattern: pattern, - Literal: false, +// NewMatch returns a Match describing the given pattern, +// without resolving its packages or errors. +func NewMatch(pattern string) *Match { + return &Match{pattern: pattern} +} + +// Pattern returns the pattern to be matched. +func (m *Match) Pattern() string { return m.pattern } + +// AddError appends a MatchError wrapping err to m.Errs. +func (m *Match) AddError(err error) { + m.Errs = append(m.Errs, &MatchError{Match: m, Err: err}) +} + +// Literal reports whether the pattern is free of wildcards and meta-patterns. +// +// A literal pattern must match at most one package. +func (m *Match) IsLiteral() bool { + return !strings.Contains(m.pattern, "...") && !m.IsMeta() +} + +// Local reports whether the pattern must be resolved from a specific root or +// directory, such as a filesystem path or a single module. +func (m *Match) IsLocal() bool { + return build.IsLocalImport(m.pattern) || filepath.IsAbs(m.pattern) +} + +// Meta reports whether the pattern is a “meta-package” keyword that represents +// multiple packages, such as "std", "cmd", or "all". +func (m *Match) IsMeta() bool { + return IsMetaPackage(m.pattern) +} + +// IsMetaPackage checks if name is a reserved package name that expands to multiple packages. +func IsMetaPackage(name string) bool { + return name == "std" || name == "cmd" || name == "all" +} + +// A MatchError indicates an error that occurred while attempting to match a +// pattern. +type MatchError struct { + Match *Match + Err error +} + +func (e *MatchError) Error() string { + if e.Match.IsLiteral() { + return fmt.Sprintf("%s: %v", e.Match.Pattern(), e.Err) + } + return fmt.Sprintf("pattern %s: %v", e.Match.Pattern(), e.Err) +} + +func (e *MatchError) Unwrap() error { + return e.Err +} + +// MatchPackages sets m.Pkgs to a non-nil slice containing all the packages that +// can be found under the $GOPATH directories and $GOROOT that match the +// pattern. The pattern must be either "all" (all packages), "std" (standard +// packages), "cmd" (standard commands), or a path including "...". +// +// If any errors may have caused the set of packages to be incomplete, +// MatchPackages appends those errors to m.Errs. +func (m *Match) MatchPackages() { + m.Pkgs = []string{} + if m.IsLocal() { + m.AddError(fmt.Errorf("internal error: MatchPackages: %s is not a valid package pattern", m.pattern)) + return } + + if m.IsLiteral() { + m.Pkgs = []string{m.pattern} + return + } + match := func(string) bool { return true } treeCanMatch := func(string) bool { return true } - if !IsMetaPackage(pattern) { - match = MatchPattern(pattern) - treeCanMatch = TreeCanMatchPattern(pattern) + if !m.IsMeta() { + match = MatchPattern(m.pattern) + treeCanMatch = TreeCanMatchPattern(m.pattern) } have := map[string]bool{ @@ -48,17 +119,20 @@ func MatchPackages(pattern string) *Match { } for _, src := range cfg.BuildContext.SrcDirs() { - if (pattern == "std" || pattern == "cmd") && src != cfg.GOROOTsrc { + if (m.pattern == "std" || m.pattern == "cmd") && src != cfg.GOROOTsrc { continue } src = filepath.Clean(src) + string(filepath.Separator) root := src - if pattern == "cmd" { + if m.pattern == "cmd" { root += "cmd" + string(filepath.Separator) } - filepath.Walk(root, func(path string, fi os.FileInfo, err error) error { - if err != nil || path == src { - return nil + err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error { + if err != nil { + return err // Likely a permission error, which could interfere with matching. + } + if path == src { + return nil // GOROOT/src and GOPATH/src cannot contain packages. } want := true @@ -69,7 +143,7 @@ func MatchPackages(pattern string) *Match { } name := filepath.ToSlash(path[len(src):]) - if pattern == "std" && (!IsStandardImportPath(name) || name == "cmd") { + if m.pattern == "std" && (!IsStandardImportPath(name) || name == "cmd") { // The name "std" is only the standard library. // If the name is cmd, it's the root of the command tree. want = false @@ -100,23 +174,30 @@ func MatchPackages(pattern string) *Match { pkg, err := cfg.BuildContext.ImportDir(path, 0) if err != nil { if _, noGo := err.(*build.NoGoError); noGo { + // The package does not actually exist, so record neither the package + // nor the error. return nil } + // There was an error importing path, but not matching it, + // which is all that Match promises to do. + // Ignore the import error. } // If we are expanding "cmd", skip main // packages under cmd/vendor. At least as of // March, 2017, there is one there for the // vendored pprof tool. - if pattern == "cmd" && strings.HasPrefix(pkg.ImportPath, "cmd/vendor") && pkg.Name == "main" { + if m.pattern == "cmd" && pkg != nil && strings.HasPrefix(pkg.ImportPath, "cmd/vendor") && pkg.Name == "main" { return nil } m.Pkgs = append(m.Pkgs, name) return nil }) + if err != nil { + m.AddError(err) + } } - return m } var modRoot string @@ -125,24 +206,31 @@ func SetModRoot(dir string) { modRoot = dir } -// MatchPackagesInFS is like MatchPackages but is passed a pattern that -// begins with an absolute path or "./" or "../". On Windows, the pattern may -// use slash or backslash separators or a mix of both. +// MatchDirs sets m.Dirs to a non-nil slice containing all directories that +// potentially match a local pattern. The pattern must begin with an absolute +// path, or "./", or "../". On Windows, the pattern may use slash or backslash +// separators or a mix of both. // -// MatchPackagesInFS scans the tree rooted at the directory that contains the -// first "..." wildcard and returns a match with packages that -func MatchPackagesInFS(pattern string) *Match { - m := &Match{ - Pattern: pattern, - Literal: false, +// If any errors may have caused the set of directories to be incomplete, +// MatchDirs appends those errors to m.Errs. +func (m *Match) MatchDirs() { + m.Dirs = []string{} + if !m.IsLocal() { + m.AddError(fmt.Errorf("internal error: MatchDirs: %s is not a valid filesystem pattern", m.pattern)) + return + } + + if m.IsLiteral() { + m.Dirs = []string{m.pattern} + return } // Clean the path and create a matching predicate. // filepath.Clean removes "./" prefixes (and ".\" on Windows). We need to // preserve these, since they are meaningful in MatchPattern and in // returned import paths. - cleanPattern := filepath.Clean(pattern) - isLocal := strings.HasPrefix(pattern, "./") || (os.PathSeparator == '\\' && strings.HasPrefix(pattern, `.\`)) + cleanPattern := filepath.Clean(m.pattern) + isLocal := strings.HasPrefix(m.pattern, "./") || (os.PathSeparator == '\\' && strings.HasPrefix(m.pattern, `.\`)) prefix := "" if cleanPattern != "." && isLocal { prefix = "./" @@ -166,16 +254,20 @@ func MatchPackagesInFS(pattern string) *Match { if modRoot != "" { abs, err := filepath.Abs(dir) if err != nil { - base.Fatalf("go: %v", err) + m.AddError(err) + return } if !hasFilepathPrefix(abs, modRoot) { - base.Fatalf("go: pattern %s refers to dir %s, outside module root %s", pattern, abs, modRoot) - return nil + m.AddError(fmt.Errorf("directory %s is outside module root (%s)", abs, modRoot)) + return } } - filepath.Walk(dir, func(path string, fi os.FileInfo, err error) error { - if err != nil || !fi.IsDir() { + err := filepath.Walk(dir, func(path string, fi os.FileInfo, err error) error { + if err != nil { + return err // Likely a permission error, which could interfere with matching. + } + if !fi.IsDir() { return nil } top := false @@ -218,15 +310,21 @@ func MatchPackagesInFS(pattern string) *Match { // behavior means people miss serious mistakes. // See golang.org/issue/11407. if p, err := cfg.BuildContext.ImportDir(path, 0); err != nil && (p == nil || len(p.InvalidGoFiles) == 0) { - if _, noGo := err.(*build.NoGoError); !noGo { - log.Print(err) + if _, noGo := err.(*build.NoGoError); noGo { + // The package does not actually exist, so record neither the package + // nor the error. + return nil } - return nil + // There was an error importing path, but not matching it, + // which is all that Match promises to do. + // Ignore the import error. } - m.Pkgs = append(m.Pkgs, name) + m.Dirs = append(m.Dirs, name) return nil }) - return m + if err != nil { + m.AddError(err) + } } // TreeCanMatchPattern(pattern)(name) reports whether @@ -316,8 +414,8 @@ func replaceVendor(x, repl string) string { // WarnUnmatched warns about patterns that didn't match any packages. func WarnUnmatched(matches []*Match) { for _, m := range matches { - if len(m.Pkgs) == 0 { - fmt.Fprintf(os.Stderr, "go: warning: %q matched no packages\n", m.Pattern) + if len(m.Pkgs) == 0 && len(m.Errs) == 0 { + fmt.Fprintf(os.Stderr, "go: warning: %q matched no packages\n", m.pattern) } } } @@ -334,40 +432,30 @@ func ImportPaths(patterns []string) []*Match { func ImportPathsQuiet(patterns []string) []*Match { var out []*Match for _, a := range CleanPatterns(patterns) { - if IsMetaPackage(a) { - out = append(out, MatchPackages(a)) - continue - } - - if build.IsLocalImport(a) || filepath.IsAbs(a) { - var m *Match - if strings.Contains(a, "...") { - m = MatchPackagesInFS(a) - } else { - m = &Match{Pattern: a, Literal: true, Pkgs: []string{a}} - } + m := NewMatch(a) + if m.IsLocal() { + m.MatchDirs() // Change the file import path to a regular import path if the package // is in GOPATH or GOROOT. We don't report errors here; LoadImport // (or something similar) will report them later. - for i, dir := range m.Pkgs { + m.Pkgs = make([]string, len(m.Dirs)) + for i, dir := range m.Dirs { + absDir := dir if !filepath.IsAbs(dir) { - dir = filepath.Join(base.Cwd, dir) + absDir = filepath.Join(base.Cwd, dir) } - if bp, _ := cfg.BuildContext.ImportDir(dir, build.FindOnly); bp.ImportPath != "" && bp.ImportPath != "." { + if bp, _ := cfg.BuildContext.ImportDir(absDir, build.FindOnly); bp.ImportPath != "" && bp.ImportPath != "." { m.Pkgs[i] = bp.ImportPath + } else { + m.Pkgs[i] = dir } } - out = append(out, m) - continue - } - - if strings.Contains(a, "...") { - out = append(out, MatchPackages(a)) - continue + } else { + m.MatchPackages() } - out = append(out, &Match{Pattern: a, Literal: true, Pkgs: []string{a}}) + out = append(out, m) } return out } @@ -419,11 +507,6 @@ func CleanPatterns(patterns []string) []string { return out } -// IsMetaPackage checks if name is a reserved package name that expands to multiple packages. -func IsMetaPackage(name string) bool { - return name == "std" || name == "cmd" || name == "all" -} - // hasPathPrefix reports whether the path s begins with the // elements in prefix. func hasPathPrefix(s, prefix string) bool { diff --git a/libgo/go/cmd/go/internal/str/path.go b/libgo/go/cmd/go/internal/str/path.go index a4ffc5f1312..95d91a3332e 100644 --- a/libgo/go/cmd/go/internal/str/path.go +++ b/libgo/go/cmd/go/internal/str/path.go @@ -10,7 +10,7 @@ import ( "strings" ) -// HasPath reports whether the slash-separated path s +// HasPathPrefix reports whether the slash-separated path s // begins with the elements in prefix. func HasPathPrefix(s, prefix string) bool { if len(s) == len(prefix) { diff --git a/libgo/go/cmd/go/internal/test/flagdefs.go b/libgo/go/cmd/go/internal/test/flagdefs.go new file mode 100644 index 00000000000..8a0a07683b7 --- /dev/null +++ b/libgo/go/cmd/go/internal/test/flagdefs.go @@ -0,0 +1,34 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by genflags.go — DO NOT EDIT. + +package test + +// passFlagToTest contains the flags that should be forwarded to +// the test binary with the prefix "test.". +var passFlagToTest = map[string]bool{ + "bench": true, + "benchmem": true, + "benchtime": true, + "blockprofile": true, + "blockprofilerate": true, + "count": true, + "coverprofile": true, + "cpu": true, + "cpuprofile": true, + "failfast": true, + "list": true, + "memprofile": true, + "memprofilerate": true, + "mutexprofile": true, + "mutexprofilefraction": true, + "outputdir": true, + "parallel": true, + "run": true, + "short": true, + "timeout": true, + "trace": true, + "v": true, +} diff --git a/libgo/go/cmd/go/internal/test/flagdefs_test.go b/libgo/go/cmd/go/internal/test/flagdefs_test.go new file mode 100644 index 00000000000..7562415298c --- /dev/null +++ b/libgo/go/cmd/go/internal/test/flagdefs_test.go @@ -0,0 +1,34 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package test + +import ( + "flag" + "strings" + "testing" +) + +func TestPassFlagToTestIncludesAllTestFlags(t *testing.T) { + flag.VisitAll(func(f *flag.Flag) { + if !strings.HasPrefix(f.Name, "test.") { + return + } + name := strings.TrimPrefix(f.Name, "test.") + if name != "testlogfile" && !passFlagToTest[name] { + t.Errorf("passFlagToTest missing entry for %q (flag test.%s)", name, name) + t.Logf("(Run 'go generate cmd/go/internal/test' if it should be added.)") + } + }) + + for name := range passFlagToTest { + if flag.Lookup("test."+name) == nil { + t.Errorf("passFlagToTest contains %q, but flag -test.%s does not exist in test binary", name, name) + } + + if CmdTest.Flag.Lookup(name) == nil { + t.Errorf("passFlagToTest contains %q, but flag -%s does not exist in 'go test' subcommand", name, name) + } + } +} diff --git a/libgo/go/cmd/go/internal/test/genflags.go b/libgo/go/cmd/go/internal/test/genflags.go new file mode 100644 index 00000000000..512fa1671ef --- /dev/null +++ b/libgo/go/cmd/go/internal/test/genflags.go @@ -0,0 +1,90 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +package main + +import ( + "bytes" + "flag" + "log" + "os" + "os/exec" + "strings" + "testing" + "text/template" +) + +func main() { + if err := regenerate(); err != nil { + log.Fatal(err) + } +} + +func regenerate() error { + t := template.Must(template.New("fileTemplate").Parse(fileTemplate)) + buf := bytes.NewBuffer(nil) + if err := t.Execute(buf, testFlags()); err != nil { + return err + } + + f, err := os.Create("flagdefs.go") + if err != nil { + return err + } + + cmd := exec.Command("gofmt") + cmd.Stdin = buf + cmd.Stdout = f + cmd.Stderr = os.Stderr + cmdErr := cmd.Run() + + if err := f.Close(); err != nil { + return err + } + if cmdErr != nil { + os.Remove(f.Name()) + return cmdErr + } + + return nil +} + +func testFlags() []string { + testing.Init() + + var names []string + flag.VisitAll(func(f *flag.Flag) { + if !strings.HasPrefix(f.Name, "test.") { + return + } + name := strings.TrimPrefix(f.Name, "test.") + + if name == "testlogfile" { + // test.testlogfile is “for use only by cmd/go” + } else { + names = append(names, name) + } + }) + + return names +} + +const fileTemplate = `// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by genflags.go — DO NOT EDIT. + +package test + +// passFlagToTest contains the flags that should be forwarded to +// the test binary with the prefix "test.". +var passFlagToTest = map[string]bool { +{{- range .}} + "{{.}}": true, +{{- end }} +} +` diff --git a/libgo/go/cmd/go/internal/test/test.go b/libgo/go/cmd/go/internal/test/test.go index 4ad142ccd87..873a76aa380 100644 --- a/libgo/go/cmd/go/internal/test/test.go +++ b/libgo/go/cmd/go/internal/test/test.go @@ -73,10 +73,10 @@ As part of building a test binary, go test runs go vet on the package and its test source files to identify significant problems. If go vet finds any problems, go test reports those and does not run the test binary. Only a high-confidence subset of the default go vet checks are -used. That subset is: 'atomic', 'bool', 'buildtags', 'nilfunc', and -'printf'. You can see the documentation for these and other vet tests -via "go doc cmd/vet". To disable the running of go vet, use the --vet=off flag. +used. That subset is: 'atomic', 'bool', 'buildtags', 'errorsas', +'ifaceassert', 'nilfunc', 'printf', and 'stringintconv'. You can see +the documentation for these and other vet tests via "go doc cmd/vet". +To disable the running of go vet, use the -vet=off flag. All test output and summary lines are printed to the go command's standard output, even if the test printed them to its own standard @@ -466,37 +466,78 @@ See the documentation of the testing package for more information. } var ( - testC bool // -c flag - testCover bool // -cover flag - testCoverMode string // -covermode flag - testCoverPaths []string // -coverpkg flag - testCoverPkgs []*load.Package // -coverpkg flag - testCoverProfile string // -coverprofile flag - testOutputDir string // -outputdir flag - testO string // -o flag - testProfile string // profiling flag that limits test to one package - testNeedBinary bool // profile needs to keep binary around - testJSON bool // -json flag - testV bool // -v flag - testTimeout string // -timeout flag - testArgs []string - testBench bool - testList bool - testShowPass bool // show passing output - testVetList string // -vet flag - pkgArgs []string - pkgs []*load.Package - - testActualTimeout = 10 * time.Minute // actual timeout which is passed to tests - testKillTimeout = testActualTimeout + 1*time.Minute // backup alarm - testCacheExpire time.Time // ignore cached test results before this time + testBench string // -bench flag + testC bool // -c flag + testCover bool // -cover flag + testCoverMode string // -covermode flag + testCoverPaths []string // -coverpkg flag + testCoverPkgs []*load.Package // -coverpkg flag + testCoverProfile string // -coverprofile flag + testJSON bool // -json flag + testList string // -list flag + testO string // -o flag + testOutputDir = base.Cwd // -outputdir flag + testTimeout time.Duration // -timeout flag + testV bool // -v flag + testVet = vetFlag{flags: defaultVetFlags} // -vet flag ) -// testVetExplicit records whether testVetFlags were set by an explicit -vet. -var testVetExplicit = false +var ( + testArgs []string + pkgArgs []string + pkgs []*load.Package + + testHelp bool // -help option passed to test via -args + + testKillTimeout = 100 * 365 * 24 * time.Hour // backup alarm; defaults to about a century if no timeout is set + testCacheExpire time.Time // ignore cached test results before this time + + testBlockProfile, testCPUProfile, testMemProfile, testMutexProfile, testTrace string // profiling flag that limits test to one package +) + +// testProfile returns the name of an arbitrary single-package profiling flag +// that is set, if any. +func testProfile() string { + switch { + case testBlockProfile != "": + return "-blockprofile" + case testCPUProfile != "": + return "-cpuprofile" + case testMemProfile != "": + return "-memprofile" + case testMutexProfile != "": + return "-mutexprofile" + case testTrace != "": + return "-trace" + default: + return "" + } +} + +// testNeedBinary reports whether the test needs to keep the binary around. +func testNeedBinary() bool { + switch { + case testBlockProfile != "": + return true + case testCPUProfile != "": + return true + case testMemProfile != "": + return true + case testMutexProfile != "": + return true + case testO != "": + return true + default: + return false + } +} + +// testShowPass reports whether the output for a passing test should be shown. +func testShowPass() bool { + return testV || (testList != "") || testHelp +} -// testVetFlags is the list of flags to pass to vet when invoked automatically during go test. -var testVetFlags = []string{ +var defaultVetFlags = []string{ // TODO(rsc): Decide which tests are enabled by default. // See golang.org/issue/18085. // "-asmdecl", @@ -509,12 +550,14 @@ var testVetFlags = []string{ // "-copylocks", "-errorsas", // "-httpresponse", + "-ifaceassert", // "-lostcancel", // "-methods", "-nilfunc", "-printf", // "-rangeloops", // "-shift", + "-stringintconv", // "-structtags", // "-tests", // "-unreachable", @@ -522,22 +565,16 @@ var testVetFlags = []string{ // "-unusedresult", } -func testCmdUsage() { - fmt.Fprintf(os.Stderr, "usage: %s\n", CmdTest.UsageLine) - fmt.Fprintf(os.Stderr, "Run 'go help %s' and 'go help %s' for details.\n", CmdTest.LongName(), HelpTestflag.LongName()) - os.Exit(2) -} - func runTest(cmd *base.Command, args []string) { modload.LoadTests = true - pkgArgs, testArgs = testFlags(testCmdUsage, args) + pkgArgs, testArgs = testFlags(args) work.FindExecCmd() // initialize cached result work.BuildInit() - work.VetFlags = testVetFlags - work.VetExplicit = testVetExplicit + work.VetFlags = testVet.flags + work.VetExplicit = testVet.explicit pkgs = load.PackagesForBuild(pkgArgs) if len(pkgs) == 0 { @@ -550,38 +587,20 @@ func runTest(cmd *base.Command, args []string) { if testO != "" && len(pkgs) != 1 { base.Fatalf("cannot use -o flag with multiple packages") } - if testProfile != "" && len(pkgs) != 1 { - base.Fatalf("cannot use %s flag with multiple packages", testProfile) + if testProfile() != "" && len(pkgs) != 1 { + base.Fatalf("cannot use %s flag with multiple packages", testProfile()) } initCoverProfile() defer closeCoverProfile() - // If a test timeout was given and is parseable, set our kill timeout + // If a test timeout is finite, set our kill timeout // to that timeout plus one minute. This is a backup alarm in case // the test wedges with a goroutine spinning and its background // timer does not get a chance to fire. - if dt, err := time.ParseDuration(testTimeout); err == nil && dt > 0 { - testActualTimeout = dt - testKillTimeout = testActualTimeout + 1*time.Minute - } else if err == nil && dt == 0 { - // An explicit zero disables the test timeout. - // No timeout is passed to tests. - // Let it have one century (almost) before we kill it. - testActualTimeout = -1 - testKillTimeout = 100 * 365 * 24 * time.Hour - } - - // Pass timeout to tests if it exists. - // Prepend rather than appending so that it appears before positional arguments. - if testActualTimeout > 0 { - testArgs = append([]string{"-test.timeout=" + testActualTimeout.String()}, testArgs...) + if testTimeout > 0 { + testKillTimeout = testTimeout + 1*time.Minute } - // show passing test output (after buffering) with -v flag. - // must buffer because tests are running in parallel, and - // otherwise the output will get mixed. - testShowPass = testV || testList - // For 'go test -i -o x.test', we want to build x.test. Imply -c to make the logic easier. if cfg.BuildI && testO != "" { testC = true @@ -755,7 +774,7 @@ func runTest(cmd *base.Command, args []string) { } // Force benchmarks to run in serial. - if !testC && testBench { + if !testC && (testBench != "") { // The first run must wait for all builds. // Later runs must wait for the previous run's print. for i, run := range runs { @@ -839,7 +858,7 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin } pmain.Dir = testDir - pmain.Internal.OmitDebug = !testC && !testNeedBinary + pmain.Internal.OmitDebug = !testC && !testNeedBinary() if !cfg.BuildN { // writeTestmain writes _testmain.go, @@ -887,7 +906,7 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin } buildAction = a var installAction, cleanAction *work.Action - if testC || testNeedBinary { + if testC || testNeedBinary() { // -c or profiling flag: create action to copy binary to ./test.out. target := filepath.Join(base.Cwd, testBinary+cfg.ExeSuffix) if testO != "" { @@ -964,7 +983,7 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin } func addTestVet(b *work.Builder, p *load.Package, runAction, installAction *work.Action) { - if testVetList == "off" { + if testVet.off { return } @@ -1067,7 +1086,7 @@ func (c *runCache) builderRunTest(b *work.Builder, a *work.Action) error { } var buf bytes.Buffer - if len(pkgArgs) == 0 || testBench { + if len(pkgArgs) == 0 || (testBench != "") { // Stream test output (no buffering) when no package has // been given on the command line (implicit current directory) // or when benchmarking. @@ -1087,7 +1106,7 @@ func (c *runCache) builderRunTest(b *work.Builder, a *work.Action) error { // possible even when multiple tests are being run: the JSON output // events are attributed to specific package tests, so interlacing them // is OK. - if testShowPass && (len(pkgs) == 1 || cfg.BuildP == 1) || testJSON { + if testShowPass() && (len(pkgs) == 1 || cfg.BuildP == 1) || testJSON { // Write both to stdout and buf, for possible saving // to cache, and for looking for the "no tests to run" message. stdout = io.MultiWriter(stdout, &buf) @@ -1142,7 +1161,7 @@ func (c *runCache) builderRunTest(b *work.Builder, a *work.Action) error { cmd := exec.Command(args[0], args[1:]...) cmd.Dir = a.Package.Dir - cmd.Env = base.EnvForDir(cmd.Dir, cfg.OrigEnv[:len(cfg.OrigEnv):len(cfg.OrigEnv)]) + cmd.Env = base.AppendPWD(cfg.OrigEnv[:len(cfg.OrigEnv):len(cfg.OrigEnv)], cmd.Dir) cmd.Stdout = stdout cmd.Stderr = stdout @@ -1209,7 +1228,7 @@ func (c *runCache) builderRunTest(b *work.Builder, a *work.Action) error { if err == nil { norun := "" - if !testShowPass && !testJSON { + if !testShowPass() && !testJSON { buf.Reset() } if bytes.HasPrefix(out, noTestsToRun[1:]) || bytes.Contains(out, noTestsToRun) { @@ -1284,16 +1303,13 @@ func (c *runCache) tryCacheWithID(b *work.Builder, a *work.Action, id string) bo "-test.parallel", "-test.run", "-test.short", + "-test.timeout", "-test.v": // These are cacheable. // Note that this list is documented above, // so if you add to this list, update the docs too. cacheArgs = append(cacheArgs, arg) - case "-test.timeout": - // Special case: this is cacheable but ignored during the hash. - // Do not add to cacheArgs. - default: // nothing else is cacheable if cache.DebugTest { diff --git a/libgo/go/cmd/go/internal/test/testflag.go b/libgo/go/cmd/go/internal/test/testflag.go index e214b1532bd..1ff34f7445c 100644 --- a/libgo/go/cmd/go/internal/test/testflag.go +++ b/libgo/go/cmd/go/internal/test/testflag.go @@ -5,81 +5,197 @@ package test import ( + "errors" "flag" + "fmt" "os" + "path/filepath" "strings" + "time" "cmd/go/internal/base" "cmd/go/internal/cfg" "cmd/go/internal/cmdflag" - "cmd/go/internal/str" "cmd/go/internal/work" ) -const cmd = "test" +//go:generate go run ./genflags.go // The flag handling part of go test is large and distracting. -// We can't use the flag package because some of the flags from -// our command line are for us, and some are for 6.out, and +// We can't use (*flag.FlagSet).Parse because some of the flags from +// our command line are for us, and some are for the test binary, and // some are for both. -// testFlagDefn is the set of flags we process. -var testFlagDefn = []*cmdflag.Defn{ - // local. - {Name: "c", BoolVar: &testC}, - {Name: "i", BoolVar: &cfg.BuildI}, - {Name: "o"}, - {Name: "cover", BoolVar: &testCover}, - {Name: "covermode"}, - {Name: "coverpkg"}, - {Name: "exec"}, - {Name: "json", BoolVar: &testJSON}, - {Name: "vet"}, - - // Passed to 6.out, adding a "test." prefix to the name if necessary: -v becomes -test.v. - {Name: "bench", PassToTest: true}, - {Name: "benchmem", BoolVar: new(bool), PassToTest: true}, - {Name: "benchtime", PassToTest: true}, - {Name: "blockprofile", PassToTest: true}, - {Name: "blockprofilerate", PassToTest: true}, - {Name: "count", PassToTest: true}, - {Name: "coverprofile", PassToTest: true}, - {Name: "cpu", PassToTest: true}, - {Name: "cpuprofile", PassToTest: true}, - {Name: "failfast", BoolVar: new(bool), PassToTest: true}, - {Name: "list", PassToTest: true}, - {Name: "memprofile", PassToTest: true}, - {Name: "memprofilerate", PassToTest: true}, - {Name: "mutexprofile", PassToTest: true}, - {Name: "mutexprofilefraction", PassToTest: true}, - {Name: "outputdir", PassToTest: true}, - {Name: "parallel", PassToTest: true}, - {Name: "run", PassToTest: true}, - {Name: "short", BoolVar: new(bool), PassToTest: true}, - {Name: "timeout", PassToTest: true}, - {Name: "trace", PassToTest: true}, - {Name: "v", BoolVar: &testV, PassToTest: true}, +func init() { + work.AddBuildFlags(CmdTest, work.OmitVFlag) + + cf := CmdTest.Flag + cf.BoolVar(&testC, "c", false, "") + cf.BoolVar(&cfg.BuildI, "i", false, "") + cf.StringVar(&testO, "o", "", "") + + cf.BoolVar(&testCover, "cover", false, "") + cf.Var(coverFlag{(*coverModeFlag)(&testCoverMode)}, "covermode", "") + cf.Var(coverFlag{commaListFlag{&testCoverPaths}}, "coverpkg", "") + + cf.Var((*base.StringsFlag)(&work.ExecCmd), "exec", "") + cf.BoolVar(&testJSON, "json", false, "") + cf.Var(&testVet, "vet", "") + + // Register flags to be forwarded to the test binary. We retain variables for + // some of them so that cmd/go knows what to do with the test output, or knows + // to build the test in a way that supports the use of the flag. + + cf.StringVar(&testBench, "bench", "", "") + cf.Bool("benchmem", false, "") + cf.String("benchtime", "", "") + cf.StringVar(&testBlockProfile, "blockprofile", "", "") + cf.String("blockprofilerate", "", "") + cf.Int("count", 0, "") + cf.Var(coverFlag{stringFlag{&testCoverProfile}}, "coverprofile", "") + cf.String("cpu", "", "") + cf.StringVar(&testCPUProfile, "cpuprofile", "", "") + cf.Bool("failfast", false, "") + cf.StringVar(&testList, "list", "", "") + cf.StringVar(&testMemProfile, "memprofile", "", "") + cf.String("memprofilerate", "", "") + cf.StringVar(&testMutexProfile, "mutexprofile", "", "") + cf.String("mutexprofilefraction", "", "") + cf.Var(outputdirFlag{&testOutputDir}, "outputdir", "") + cf.Int("parallel", 0, "") + cf.String("run", "", "") + cf.Bool("short", false, "") + cf.DurationVar(&testTimeout, "timeout", 10*time.Minute, "") + cf.StringVar(&testTrace, "trace", "", "") + cf.BoolVar(&testV, "v", false, "") + + for name, _ := range passFlagToTest { + cf.Var(cf.Lookup(name).Value, "test."+name, "") + } } -// add build flags to testFlagDefn -func init() { - cmdflag.AddKnownFlags("test", testFlagDefn) - var cmd base.Command - work.AddBuildFlags(&cmd, work.DefaultBuildFlags) - cmd.Flag.VisitAll(func(f *flag.Flag) { - if f.Name == "v" { - // test overrides the build -v flag - return +// A coverFlag is a flag.Value that also implies -cover. +type coverFlag struct{ v flag.Value } + +func (f coverFlag) String() string { return f.v.String() } + +func (f coverFlag) Set(value string) error { + if err := f.v.Set(value); err != nil { + return err + } + testCover = true + return nil +} + +type coverModeFlag string + +func (f *coverModeFlag) String() string { return string(*f) } +func (f *coverModeFlag) Set(value string) error { + switch value { + case "", "set", "count", "atomic": + *f = coverModeFlag(value) + return nil + default: + return errors.New(`valid modes are "set", "count", or "atomic"`) + } +} + +// A commaListFlag is a flag.Value representing a comma-separated list. +type commaListFlag struct{ vals *[]string } + +func (f commaListFlag) String() string { return strings.Join(*f.vals, ",") } + +func (f commaListFlag) Set(value string) error { + if value == "" { + *f.vals = nil + } else { + *f.vals = strings.Split(value, ",") + } + return nil +} + +// A stringFlag is a flag.Value representing a single string. +type stringFlag struct{ val *string } + +func (f stringFlag) String() string { return *f.val } +func (f stringFlag) Set(value string) error { + *f.val = value + return nil +} + +// outputdirFlag implements the -outputdir flag. +// It interprets an empty value as the working directory of the 'go' command. +type outputdirFlag struct { + resolved *string +} + +func (f outputdirFlag) String() string { return *f.resolved } +func (f outputdirFlag) Set(value string) (err error) { + if value == "" { + // The empty string implies the working directory of the 'go' command. + *f.resolved = base.Cwd + } else { + *f.resolved, err = filepath.Abs(value) + } + return err +} + +// vetFlag implements the special parsing logic for the -vet flag: +// a comma-separated list, with a distinguished value "off" and +// a boolean tracking whether it was set explicitly. +type vetFlag struct { + explicit bool + off bool + flags []string // passed to vet when invoked automatically during 'go test' +} + +func (f *vetFlag) String() string { + if f.off { + return "off" + } + + var buf strings.Builder + for i, f := range f.flags { + if i > 0 { + buf.WriteByte(',') } - testFlagDefn = append(testFlagDefn, &cmdflag.Defn{ - Name: f.Name, - Value: f.Value, - }) - }) + buf.WriteString(f) + } + return buf.String() +} + +func (f *vetFlag) Set(value string) error { + if value == "" { + *f = vetFlag{flags: defaultVetFlags} + return nil + } + + if value == "off" { + *f = vetFlag{ + explicit: true, + off: true, + } + return nil + } + + if strings.Contains(value, "=") { + return fmt.Errorf("-vet argument cannot contain equal signs") + } + if strings.Contains(value, " ") { + return fmt.Errorf("-vet argument is comma-separated list, cannot contain spaces") + } + *f = vetFlag{explicit: true} + for _, arg := range strings.Split(value, ",") { + if arg == "" { + return fmt.Errorf("-vet argument contains empty list element") + } + f.flags = append(f.flags, "-"+arg) + } + return nil } // testFlags processes the command line, grabbing -x and -c, rewriting known flags -// to have "test" before them, and reading the command line for the 6.out. +// to have "test" before them, and reading the command line for the test binary. // Unfortunately for us, we need to do our own flag processing because go test // grabs some flags but otherwise its command line is just a holding place for // pkg.test's arguments. @@ -87,117 +203,154 @@ func init() { // to allow both // go test fmt -custom-flag-for-fmt-test // go test -x math -func testFlags(usage func(), args []string) (packageNames, passToTest []string) { - goflags := cmdflag.FindGOFLAGS(testFlagDefn) - args = str.StringList(goflags, args) - inPkg := false - var explicitArgs []string - for i := 0; i < len(args); i++ { - if !strings.HasPrefix(args[i], "-") { - if !inPkg && packageNames == nil { - // First package name we've seen. - inPkg = true - } - if inPkg { - packageNames = append(packageNames, args[i]) - continue +func testFlags(args []string) (packageNames, passToTest []string) { + base.SetFromGOFLAGS(&CmdTest.Flag) + addFromGOFLAGS := map[string]bool{} + CmdTest.Flag.Visit(func(f *flag.Flag) { + if short := strings.TrimPrefix(f.Name, "test."); passFlagToTest[short] { + addFromGOFLAGS[f.Name] = true + } + }) + + explicitArgs := make([]string, 0, len(args)) + inPkgList := false + for len(args) > 0 { + f, remainingArgs, err := cmdflag.ParseOne(&CmdTest.Flag, args) + + if errors.Is(err, flag.ErrHelp) { + exitWithUsage() + } + + if errors.Is(err, cmdflag.ErrFlagTerminator) { + // 'go list' allows package arguments to be named either before or after + // the terminator, but 'go test' has historically allowed them only + // before. Preserve that behavior and treat all remaining arguments — + // including the terminator itself! — as arguments to the test. + explicitArgs = append(explicitArgs, args...) + break + } + + if nf := (cmdflag.NonFlagError{}); errors.As(err, &nf) { + if !inPkgList && packageNames != nil { + // We already saw the package list previously, and this argument is not + // a flag, so it — and everything after it — must be a literal argument + // to the test binary. + explicitArgs = append(explicitArgs, args...) + break } + + inPkgList = true + packageNames = append(packageNames, nf.RawArg) + args = remainingArgs // Consume the package name. + continue } - if inPkg { - // Found an argument beginning with "-"; end of package list. - inPkg = false + if inPkgList { + // This argument is syntactically a flag, so if we were in the package + // list we're not anymore. + inPkgList = false } - f, value, extraWord := cmdflag.Parse(cmd, usage, testFlagDefn, args, i) - if f == nil { - // This is a flag we do not know; we must assume - // that any args we see after this might be flag - // arguments, not package names. - inPkg = false + if nd := (cmdflag.FlagNotDefinedError{}); errors.As(err, &nd) { + // This is a flag we do not know. We must assume that any args we see + // after this might be flag arguments, not package names, so make + // packageNames non-nil to indicate that the package list is complete. + // + // (Actually, we only strictly need to assume that if the flag is not of + // the form -x=value, but making this more precise would be a breaking + // change in the command line API.) if packageNames == nil { - // make non-nil: we have seen the empty package list packageNames = []string{} } - if args[i] == "-args" || args[i] == "--args" { + + if nd.RawArg == "-args" || nd.RawArg == "--args" { // -args or --args signals that everything that follows // should be passed to the test. - explicitArgs = args[i+1:] + explicitArgs = append(explicitArgs, remainingArgs...) break } - passToTest = append(passToTest, args[i]) + + explicitArgs = append(explicitArgs, nd.RawArg) + args = remainingArgs continue } - if i < len(goflags) { - f.Present = false // Not actually present on the command line. + + if err != nil { + fmt.Fprintln(os.Stderr, err) + exitWithUsage() } - if f.Value != nil { - if err := f.Value.Set(value); err != nil { - base.Fatalf("invalid flag argument for -%s: %v", f.Name, err) - } - } else { - // Test-only flags. - // Arguably should be handled by f.Value, but aren't. - switch f.Name { - // bool flags. - case "c", "i", "v", "cover", "json": - cmdflag.SetBool(cmd, f.BoolVar, value) - if f.Name == "json" && testJSON { - passToTest = append(passToTest, "-test.v=true") - } - case "o": - testO = value - testNeedBinary = true - case "exec": - xcmd, err := str.SplitQuotedFields(value) - if err != nil { - base.Fatalf("invalid flag argument for -%s: %v", f.Name, err) - } - work.ExecCmd = xcmd - case "bench": - // record that we saw the flag; don't care about the value - testBench = true - case "list": - testList = true - case "timeout": - testTimeout = value - case "blockprofile", "cpuprofile", "memprofile", "mutexprofile": - testProfile = "-" + f.Name - testNeedBinary = true - case "trace": - testProfile = "-trace" - case "coverpkg": - testCover = true - if value == "" { - testCoverPaths = nil - } else { - testCoverPaths = strings.Split(value, ",") - } - case "coverprofile": - testCover = true - testCoverProfile = value - case "covermode": - switch value { - case "set", "count", "atomic": - testCoverMode = value - default: - base.Fatalf("invalid flag argument for -covermode: %q", value) - } - testCover = true - case "outputdir": - testOutputDir = value - case "vet": - testVetList = value - } + + if short := strings.TrimPrefix(f.Name, "test."); passFlagToTest[short] { + explicitArgs = append(explicitArgs, fmt.Sprintf("-test.%s=%v", short, f.Value)) + + // This flag has been overridden explicitly, so don't forward its implicit + // value from GOFLAGS. + delete(addFromGOFLAGS, short) + delete(addFromGOFLAGS, "test."+short) } - if extraWord { - i++ + + args = remainingArgs + } + + var injectedFlags []string + if testJSON { + // If converting to JSON, we need the full output in order to pipe it to + // test2json. + injectedFlags = append(injectedFlags, "-test.v=true") + delete(addFromGOFLAGS, "v") + delete(addFromGOFLAGS, "test.v") + } + + // Inject flags from GOFLAGS before the explicit command-line arguments. + // (They must appear before the flag terminator or first non-flag argument.) + // Also determine whether flags with awkward defaults have already been set. + var timeoutSet, outputDirSet bool + CmdTest.Flag.Visit(func(f *flag.Flag) { + short := strings.TrimPrefix(f.Name, "test.") + if addFromGOFLAGS[f.Name] { + injectedFlags = append(injectedFlags, fmt.Sprintf("-test.%s=%v", short, f.Value)) + } + switch short { + case "timeout": + timeoutSet = true + case "outputdir": + outputDirSet = true } - if f.PassToTest { - passToTest = append(passToTest, "-test."+f.Name+"="+value) + }) + + // 'go test' has a default timeout, but the test binary itself does not. + // If the timeout wasn't set (and forwarded) explicitly, add the default + // timeout to the command line. + if testTimeout > 0 && !timeoutSet { + injectedFlags = append(injectedFlags, fmt.Sprintf("-test.timeout=%v", testTimeout)) + } + + // Similarly, the test binary defaults -test.outputdir to its own working + // directory, but 'go test' defaults it to the working directory of the 'go' + // command. Set it explicitly if it is needed due to some other flag that + // requests output. + if testProfile() != "" && !outputDirSet { + injectedFlags = append(injectedFlags, "-test.outputdir="+testOutputDir) + } + + // If the user is explicitly passing -help or -h, show output + // of the test binary so that the help output is displayed + // even though the test will exit with success. + // This loop is imperfect: it will do the wrong thing for a case + // like -args -test.outputdir -help. Such cases are probably rare, + // and getting this wrong doesn't do too much harm. +helpLoop: + for _, arg := range explicitArgs { + switch arg { + case "--": + break helpLoop + case "-h", "-help", "--help": + testHelp = true + break helpLoop } } + // Ensure that -race and -covermode are compatible. if testCoverMode == "" { testCoverMode = "set" if cfg.BuildRace { @@ -205,35 +358,18 @@ func testFlags(usage func(), args []string) (packageNames, passToTest []string) testCoverMode = "atomic" } } - - testVetExplicit = testVetList != "" - if testVetList != "" && testVetList != "off" { - if strings.Contains(testVetList, "=") { - base.Fatalf("-vet argument cannot contain equal signs") - } - if strings.Contains(testVetList, " ") { - base.Fatalf("-vet argument is comma-separated list, cannot contain spaces") - } - list := strings.Split(testVetList, ",") - for i, arg := range list { - list[i] = "-" + arg - } - testVetFlags = list - } - if cfg.BuildRace && testCoverMode != "atomic" { base.Fatalf(`-covermode must be "atomic", not %q, when -race is enabled`, testCoverMode) } - // Tell the test what directory we're running in, so it can write the profiles there. - if testProfile != "" && testOutputDir == "" { - dir, err := os.Getwd() - if err != nil { - base.Fatalf("error from os.Getwd: %s", err) - } - passToTest = append(passToTest, "-test.outputdir", dir) - } + // Forward any unparsed arguments (following --args) to the test binary. + return packageNames, append(injectedFlags, explicitArgs...) +} + +func exitWithUsage() { + fmt.Fprintf(os.Stderr, "usage: %s\n", CmdTest.UsageLine) + fmt.Fprintf(os.Stderr, "Run 'go help %s' and 'go help %s' for details.\n", CmdTest.LongName(), HelpTestflag.LongName()) - passToTest = append(passToTest, explicitArgs...) - return + base.SetExitStatus(2) + base.Exit() } diff --git a/libgo/go/cmd/go/internal/version/version.go b/libgo/go/cmd/go/internal/version/version.go index 857548c7ed8..ac2ae501552 100644 --- a/libgo/go/cmd/go/internal/version/version.go +++ b/libgo/go/cmd/go/internal/version/version.go @@ -53,6 +53,11 @@ var ( func runVersion(cmd *base.Command, args []string) { if len(args) == 0 { + if *versionM || *versionV { + fmt.Fprintf(os.Stderr, "go version: flags can only be used with arguments\n") + base.SetExitStatus(2) + return + } fmt.Printf("go version %s %s/%s\n", runtime.Version(), runtime.GOOS, runtime.GOARCH) return } @@ -61,6 +66,7 @@ func runVersion(cmd *base.Command, args []string) { info, err := os.Stat(arg) if err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) + base.SetExitStatus(1) continue } if info.IsDir() { diff --git a/libgo/go/cmd/go/internal/vet/vet.go b/libgo/go/cmd/go/internal/vet/vet.go index 4e09c0fb9c9..4ec58de7854 100644 --- a/libgo/go/cmd/go/internal/vet/vet.go +++ b/libgo/go/cmd/go/internal/vet/vet.go @@ -13,8 +13,12 @@ import ( "path/filepath" ) +// Break init loop. +func init() { + CmdVet.Run = runVet +} + var CmdVet = &base.Command{ - Run: runVet, CustomFlags: true, UsageLine: "go vet [-n] [-x] [-vettool prog] [build flags] [vet flags] [packages]", Short: "report likely mistakes in packages", @@ -47,7 +51,7 @@ See also: go fmt, go fix. func runVet(cmd *base.Command, args []string) { modload.LoadTests = true - vetFlags, pkgArgs := vetFlags(vetUsage, args) + vetFlags, pkgArgs := vetFlags(args) work.BuildInit() work.VetFlags = vetFlags diff --git a/libgo/go/cmd/go/internal/vet/vetflag.go b/libgo/go/cmd/go/internal/vet/vetflag.go index e3de48bbffa..ef995ef8353 100644 --- a/libgo/go/cmd/go/internal/vet/vetflag.go +++ b/libgo/go/cmd/go/internal/vet/vetflag.go @@ -7,6 +7,7 @@ package vet import ( "bytes" "encoding/json" + "errors" "flag" "fmt" "log" @@ -17,7 +18,6 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cmdflag" - "cmd/go/internal/str" "cmd/go/internal/work" ) @@ -39,37 +39,44 @@ import ( var vetTool string // -vettool func init() { + work.AddBuildFlags(CmdVet, work.DefaultBuildFlags) + CmdVet.Flag.StringVar(&vetTool, "vettool", "", "") +} + +func parseVettoolFlag(args []string) { // Extract -vettool by ad hoc flag processing: // its value is needed even before we can declare // the flags available during main flag processing. - for i, arg := range os.Args { + for i, arg := range args { if arg == "-vettool" || arg == "--vettool" { - if i+1 >= len(os.Args) { + if i+1 >= len(args) { log.Fatalf("%s requires a filename", arg) } - vetTool = os.Args[i+1] - break + vetTool = args[i+1] + return } else if strings.HasPrefix(arg, "-vettool=") || strings.HasPrefix(arg, "--vettool=") { vetTool = arg[strings.IndexByte(arg, '=')+1:] - break + return } } } // vetFlags processes the command line, splitting it at the first non-flag // into the list of flags and list of packages. -func vetFlags(usage func(), args []string) (passToVet, packageNames []string) { +func vetFlags(args []string) (passToVet, packageNames []string) { + parseVettoolFlag(args) + // Query the vet command for its flags. - tool := vetTool - if tool != "" { + var tool string + if vetTool == "" { + tool = base.Tool("vet") + } else { var err error - tool, err = filepath.Abs(tool) + tool, err = filepath.Abs(vetTool) if err != nil { log.Fatal(err) } - } else { - tool = base.Tool("vet") } out := new(bytes.Buffer) vetcmd := exec.Command(tool, "-flags") @@ -90,95 +97,85 @@ func vetFlags(usage func(), args []string) (passToVet, packageNames []string) { base.Exit() } - // Add vet's flags to vetflagDefn. + // Add vet's flags to CmdVet.Flag. // // Some flags, in particular -tags and -v, are known to vet but - // also defined as build flags. This works fine, so we don't - // define them here but use AddBuildFlags to init them. + // also defined as build flags. This works fine, so we omit duplicates here. // However some, like -x, are known to the build but not to vet. - var vetFlagDefn []*cmdflag.Defn + isVetFlag := make(map[string]bool, len(analysisFlags)) + cf := CmdVet.Flag for _, f := range analysisFlags { - switch f.Name { - case "tags", "v": - continue - } - defn := &cmdflag.Defn{ - Name: f.Name, - PassToTest: true, - } - if f.Bool { - defn.BoolVar = new(bool) + isVetFlag[f.Name] = true + if cf.Lookup(f.Name) == nil { + if f.Bool { + cf.Bool(f.Name, false, "") + } else { + cf.String(f.Name, "", "") + } } - vetFlagDefn = append(vetFlagDefn, defn) } - // Add build flags to vetFlagDefn. - var cmd base.Command - work.AddBuildFlags(&cmd, work.DefaultBuildFlags) - // This flag declaration is a placeholder: - // -vettool is actually parsed by the init function above. - cmd.Flag.StringVar(new(string), "vettool", "", "path to vet tool binary") - cmd.Flag.VisitAll(func(f *flag.Flag) { - vetFlagDefn = append(vetFlagDefn, &cmdflag.Defn{ - Name: f.Name, - Value: f.Value, - }) + // Record the set of vet tool flags set by GOFLAGS. We want to pass them to + // the vet tool, but only if they aren't overridden by an explicit argument. + base.SetFromGOFLAGS(&CmdVet.Flag) + addFromGOFLAGS := map[string]bool{} + CmdVet.Flag.Visit(func(f *flag.Flag) { + if isVetFlag[f.Name] { + addFromGOFLAGS[f.Name] = true + } }) - // Process args. - goflags := cmdflag.FindGOFLAGS(vetFlagDefn) - args = str.StringList(goflags, args) - for i := 0; i < len(args); i++ { - if !strings.HasPrefix(args[i], "-") { - return args[:i], args[i:] + explicitFlags := make([]string, 0, len(args)) + for len(args) > 0 { + f, remainingArgs, err := cmdflag.ParseOne(&CmdVet.Flag, args) + + if errors.Is(err, flag.ErrHelp) { + exitWithUsage() } - f, value, extraWord := cmdflag.Parse("vet", usage, vetFlagDefn, args, i) - if f == nil { - fmt.Fprintf(os.Stderr, "vet: flag %q not defined\n", args[i]) - fmt.Fprintf(os.Stderr, "Run \"go help vet\" for more information\n") - base.SetExitStatus(2) - base.Exit() + if errors.Is(err, cmdflag.ErrFlagTerminator) { + // All remaining args must be package names, but the flag terminator is + // not included. + packageNames = remainingArgs + break } - if i < len(goflags) { - f.Present = false // Not actually present on the command line. + + if nf := (cmdflag.NonFlagError{}); errors.As(err, &nf) { + // Everything from here on out — including the argument we just consumed — + // must be a package name. + packageNames = args + break } - if f.Value != nil { - if err := f.Value.Set(value); err != nil { - base.Fatalf("invalid flag argument for -%s: %v", f.Name, err) - } - keep := f.PassToTest - if !keep { - // A build flag, probably one we don't want to pass to vet. - // Can whitelist. - switch f.Name { - case "tags", "v": - keep = true - } - } - if !keep { - // Flags known to the build but not to vet, so must be dropped. - if extraWord { - args = append(args[:i], args[i+2:]...) - extraWord = false - } else { - args = append(args[:i], args[i+1:]...) - } - i-- - } + + if err != nil { + fmt.Fprintln(os.Stderr, err) + exitWithUsage() } - if extraWord { - i++ + + if isVetFlag[f.Name] { + // Forward the raw arguments rather than cleaned equivalents, just in + // case the vet tool parses them idiosyncratically. + explicitFlags = append(explicitFlags, args[:len(args)-len(remainingArgs)]...) + + // This flag has been overridden explicitly, so don't forward its implicit + // value from GOFLAGS. + delete(addFromGOFLAGS, f.Name) } - } - return args, nil -} -var vetUsage func() + args = remainingArgs + } -func init() { vetUsage = usage } // break initialization cycle + // Prepend arguments from GOFLAGS before other arguments. + CmdVet.Flag.Visit(func(f *flag.Flag) { + if addFromGOFLAGS[f.Name] { + passToVet = append(passToVet, fmt.Sprintf("-%s=%s", f.Name, f.Value)) + } + }) + passToVet = append(passToVet, explicitFlags...) + return passToVet, packageNames +} -func usage() { +func exitWithUsage() { fmt.Fprintf(os.Stderr, "usage: %s\n", CmdVet.UsageLine) fmt.Fprintf(os.Stderr, "Run 'go help %s' for details.\n", CmdVet.LongName()) diff --git a/libgo/go/cmd/go/internal/web/api.go b/libgo/go/cmd/go/internal/web/api.go index 209ed6861a1..570818843ba 100644 --- a/libgo/go/cmd/go/internal/web/api.go +++ b/libgo/go/cmd/go/internal/web/api.go @@ -89,7 +89,7 @@ func GetBytes(u *url.URL) ([]byte, error) { } b, err := ioutil.ReadAll(resp.Body) if err != nil { - return nil, fmt.Errorf("reading %s: %v", Redacted(u), err) + return nil, fmt.Errorf("reading %s: %v", u.Redacted(), err) } return b, nil } @@ -183,21 +183,6 @@ func Get(security SecurityMode, u *url.URL) (*Response, error) { return get(security, u) } -// Redacted returns a redacted string form of the URL, -// suitable for printing in error messages. -// The string form replaces any non-empty password -// in the original URL with "[redacted]". -func Redacted(u *url.URL) string { - if u.User != nil { - if _, ok := u.User.Password(); ok { - redacted := *u - redacted.User = url.UserPassword(u.User.Username(), "[redacted]") - u = &redacted - } - } - return u.String() -} - // OpenBrowser attempts to open the requested URL in a web browser. func OpenBrowser(url string) (opened bool) { return openBrowser(url) diff --git a/libgo/go/cmd/go/internal/web/http.go b/libgo/go/cmd/go/internal/web/http.go index 5e4319b00e9..e0509808d67 100644 --- a/libgo/go/cmd/go/internal/web/http.go +++ b/libgo/go/cmd/go/internal/web/http.go @@ -13,6 +13,7 @@ package web import ( "crypto/tls" + "errors" "fmt" "mime" "net/http" @@ -47,6 +48,13 @@ var securityPreservingHTTPClient = &http.Client{ lastHop := via[len(via)-1].URL return fmt.Errorf("redirected from secure URL %s to insecure URL %s", lastHop, req.URL) } + + // Go's http.DefaultClient allows 10 redirects before returning an error. + // The securityPreservingHTTPClient also uses this default policy to avoid + // Go command hangs. + if len(via) >= 10 { + return errors.New("stopped after 10 redirects") + } return nil }, } @@ -60,14 +68,14 @@ func get(security SecurityMode, url *urlpkg.URL) (*Response, error) { if os.Getenv("TESTGOPROXY404") == "1" && url.Host == "proxy.golang.org" { res := &Response{ - URL: Redacted(url), + URL: url.Redacted(), Status: "404 testing", StatusCode: 404, Header: make(map[string][]string), Body: http.NoBody, } if cfg.BuildX { - fmt.Fprintf(os.Stderr, "# get %s: %v (%.3fs)\n", Redacted(url), res.Status, time.Since(start).Seconds()) + fmt.Fprintf(os.Stderr, "# get %s: %v (%.3fs)\n", url.Redacted(), res.Status, time.Since(start).Seconds()) } return res, nil } @@ -78,7 +86,7 @@ func get(security SecurityMode, url *urlpkg.URL) (*Response, error) { // We print extra logging in -x mode instead, which traces what // commands are executed. if cfg.BuildX { - fmt.Fprintf(os.Stderr, "# get %s\n", Redacted(url)) + fmt.Fprintf(os.Stderr, "# get %s\n", url.Redacted()) } req, err := http.NewRequest("GET", url.String(), nil) @@ -111,7 +119,7 @@ func get(security SecurityMode, url *urlpkg.URL) (*Response, error) { fetched, res, err = fetch(secure) if err != nil { if cfg.BuildX { - fmt.Fprintf(os.Stderr, "# get %s: %v\n", Redacted(secure), err) + fmt.Fprintf(os.Stderr, "# get %s: %v\n", secure.Redacted(), err) } if security != Insecure || url.Scheme == "https" { // HTTPS failed, and we can't fall back to plain HTTP. @@ -126,9 +134,9 @@ func get(security SecurityMode, url *urlpkg.URL) (*Response, error) { case "http": if security == SecureOnly { if cfg.BuildX { - fmt.Fprintf(os.Stderr, "# get %s: insecure\n", Redacted(url)) + fmt.Fprintf(os.Stderr, "# get %s: insecure\n", url.Redacted()) } - return nil, fmt.Errorf("insecure URL: %s", Redacted(url)) + return nil, fmt.Errorf("insecure URL: %s", url.Redacted()) } case "": if security != Insecure { @@ -136,9 +144,9 @@ func get(security SecurityMode, url *urlpkg.URL) (*Response, error) { } default: if cfg.BuildX { - fmt.Fprintf(os.Stderr, "# get %s: unsupported\n", Redacted(url)) + fmt.Fprintf(os.Stderr, "# get %s: unsupported\n", url.Redacted()) } - return nil, fmt.Errorf("unsupported scheme: %s", Redacted(url)) + return nil, fmt.Errorf("unsupported scheme: %s", url.Redacted()) } insecure := new(urlpkg.URL) @@ -146,15 +154,15 @@ func get(security SecurityMode, url *urlpkg.URL) (*Response, error) { insecure.Scheme = "http" if insecure.User != nil && security != Insecure { if cfg.BuildX { - fmt.Fprintf(os.Stderr, "# get %s: insecure credentials\n", Redacted(insecure)) + fmt.Fprintf(os.Stderr, "# get %s: insecure credentials\n", insecure.Redacted()) } - return nil, fmt.Errorf("refusing to pass credentials to insecure URL: %s", Redacted(insecure)) + return nil, fmt.Errorf("refusing to pass credentials to insecure URL: %s", insecure.Redacted()) } fetched, res, err = fetch(insecure) if err != nil { if cfg.BuildX { - fmt.Fprintf(os.Stderr, "# get %s: %v\n", Redacted(insecure), err) + fmt.Fprintf(os.Stderr, "# get %s: %v\n", insecure.Redacted(), err) } // HTTP failed, and we already tried HTTPS if applicable. // Report the error from the HTTP attempt. @@ -165,11 +173,11 @@ func get(security SecurityMode, url *urlpkg.URL) (*Response, error) { // Note: accepting a non-200 OK here, so people can serve a // meta import in their http 404 page. if cfg.BuildX { - fmt.Fprintf(os.Stderr, "# get %s: %v (%.3fs)\n", Redacted(fetched), res.Status, time.Since(start).Seconds()) + fmt.Fprintf(os.Stderr, "# get %s: %v (%.3fs)\n", fetched.Redacted(), res.Status, time.Since(start).Seconds()) } r := &Response{ - URL: Redacted(fetched), + URL: fetched.Redacted(), Status: res.Status, StatusCode: res.StatusCode, Header: map[string][]string(res.Header), @@ -201,7 +209,7 @@ func getFile(u *urlpkg.URL) (*Response, error) { if os.IsNotExist(err) { return &Response{ - URL: Redacted(u), + URL: u.Redacted(), Status: http.StatusText(http.StatusNotFound), StatusCode: http.StatusNotFound, Body: http.NoBody, @@ -211,7 +219,7 @@ func getFile(u *urlpkg.URL) (*Response, error) { if os.IsPermission(err) { return &Response{ - URL: Redacted(u), + URL: u.Redacted(), Status: http.StatusText(http.StatusForbidden), StatusCode: http.StatusForbidden, Body: http.NoBody, @@ -224,7 +232,7 @@ func getFile(u *urlpkg.URL) (*Response, error) { } return &Response{ - URL: Redacted(u), + URL: u.Redacted(), Status: http.StatusText(http.StatusOK), StatusCode: http.StatusOK, Body: f, diff --git a/libgo/go/cmd/go/internal/work/action.go b/libgo/go/cmd/go/internal/work/action.go index db422fd9935..b87292811fd 100644 --- a/libgo/go/cmd/go/internal/work/action.go +++ b/libgo/go/cmd/go/internal/work/action.go @@ -42,7 +42,7 @@ type Builder struct { IsCmdList bool // running as part of go list; set p.Stale and additional fields below NeedError bool // list needs p.Error NeedExport bool // list needs p.Export - NeedCompiledGoFiles bool // list needs p.CompiledGoFIles + NeedCompiledGoFiles bool // list needs p.CompiledGoFiles objdirSeq int // counter for NewObjdir pkgSeq int diff --git a/libgo/go/cmd/go/internal/work/build.go b/libgo/go/cmd/go/internal/work/build.go index e3b25c937c3..7146c9ce00e 100644 --- a/libgo/go/cmd/go/internal/work/build.go +++ b/libgo/go/cmd/go/internal/work/build.go @@ -232,6 +232,7 @@ const ( DefaultBuildFlags BuildFlagMask = 0 OmitModFlag BuildFlagMask = 1 << iota OmitModCommonFlags + OmitVFlag ) // AddBuildFlags adds the flags common to the build, clean, get, @@ -240,7 +241,9 @@ func AddBuildFlags(cmd *base.Command, mask BuildFlagMask) { cmd.Flag.BoolVar(&cfg.BuildA, "a", false, "") cmd.Flag.BoolVar(&cfg.BuildN, "n", false, "") cmd.Flag.IntVar(&cfg.BuildP, "p", cfg.BuildP, "") - cmd.Flag.BoolVar(&cfg.BuildV, "v", false, "") + if mask&OmitVFlag == 0 { + cmd.Flag.BoolVar(&cfg.BuildV, "v", false, "") + } cmd.Flag.BoolVar(&cfg.BuildX, "x", false, "") cmd.Flag.Var(&load.BuildAsmflags, "asmflags", "") diff --git a/libgo/go/cmd/go/internal/work/build_test.go b/libgo/go/cmd/go/internal/work/build_test.go index b60f4e27c04..c33de2635dc 100644 --- a/libgo/go/cmd/go/internal/work/build_test.go +++ b/libgo/go/cmd/go/internal/work/build_test.go @@ -222,7 +222,7 @@ func pkgImportPath(pkgpath string) *load.Package { func TestRespectSetgidDir(t *testing.T) { switch runtime.GOOS { case "darwin": - if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" { + if runtime.GOARCH == "arm64" { t.Skip("can't set SetGID bit with chmod on iOS") } case "windows", "plan9": diff --git a/libgo/go/cmd/go/internal/work/buildid.go b/libgo/go/cmd/go/internal/work/buildid.go index 7558a3091aa..6613b6fe3f2 100644 --- a/libgo/go/cmd/go/internal/work/buildid.go +++ b/libgo/go/cmd/go/internal/work/buildid.go @@ -185,7 +185,7 @@ func (b *Builder) toolID(name string) string { cmdline := str.StringList(cfg.BuildToolexec, path, "-V=full") cmd := exec.Command(cmdline[0], cmdline[1:]...) - cmd.Env = base.EnvForDir(cmd.Dir, os.Environ()) + cmd.Env = base.AppendPWD(os.Environ(), cmd.Dir) var stdout, stderr bytes.Buffer cmd.Stdout = &stdout cmd.Stderr = &stderr @@ -244,7 +244,7 @@ func (b *Builder) gccgoToolID(name, language string) (string, error) { // compile an empty file on standard input. cmdline := str.StringList(cfg.BuildToolexec, name, "-###", "-x", language, "-c", "-") cmd := exec.Command(cmdline[0], cmdline[1:]...) - cmd.Env = base.EnvForDir(cmd.Dir, os.Environ()) + cmd.Env = base.AppendPWD(os.Environ(), cmd.Dir) // Force untranslated output so that we see the string "version". cmd.Env = append(cmd.Env, "LC_ALL=C") out, err := cmd.CombinedOutput() diff --git a/libgo/go/cmd/go/internal/work/exec.go b/libgo/go/cmd/go/internal/work/exec.go index 764291b0584..d610410a72c 100644 --- a/libgo/go/cmd/go/internal/work/exec.go +++ b/libgo/go/cmd/go/internal/work/exec.go @@ -8,11 +8,6 @@ package work import ( "bytes" - "cmd/go/internal/base" - "cmd/go/internal/cache" - "cmd/go/internal/cfg" - "cmd/go/internal/load" - "cmd/go/internal/str" "encoding/json" "errors" "fmt" @@ -30,6 +25,12 @@ import ( "strings" "sync" "time" + + "cmd/go/internal/base" + "cmd/go/internal/cache" + "cmd/go/internal/cfg" + "cmd/go/internal/load" + "cmd/go/internal/str" ) // actionList returns the list of actions in the dag rooted at root @@ -490,6 +491,10 @@ func (b *Builder) build(a *Action) (err error) { return nil } + if err := allowInstall(a); err != nil { + return err + } + // make target directory dir, _ := filepath.Split(a.Target) if dir != "" { @@ -1194,6 +1199,10 @@ func (b *Builder) link(a *Action) (err error) { return err } + if err := allowInstall(a); err != nil { + return err + } + // make target directory dir, _ := filepath.Split(a.Target) if dir != "" { @@ -1368,6 +1377,10 @@ func (b *Builder) getPkgConfigFlags(p *load.Package) (cflags, ldflags []string, } func (b *Builder) installShlibname(a *Action) error { + if err := allowInstall(a); err != nil { + return err + } + // TODO: BuildN a1 := a.Deps[0] err := ioutil.WriteFile(a.Target, []byte(filepath.Base(a1.Target)+"\n"), 0666) @@ -1418,6 +1431,10 @@ func (b *Builder) linkShared(a *Action) (err error) { } defer b.flushOutput(a) + if err := allowInstall(a); err != nil { + return err + } + if err := b.Mkdir(a.Objdir); err != nil { return err } @@ -1483,8 +1500,12 @@ func BuildInstallFunc(b *Builder, a *Action) (err error) { // advertise it by touching the mtimes (usually the libraries are up // to date). if !a.buggyInstall && !b.IsCmdList { - now := time.Now() - os.Chtimes(a.Target, now, now) + if cfg.BuildN { + b.Showcmd("", "touch %s", a.Target) + } else if err := allowInstall(a); err == nil { + now := time.Now() + os.Chtimes(a.Target, now, now) + } } return nil } @@ -1495,6 +1516,9 @@ func BuildInstallFunc(b *Builder, a *Action) (err error) { a.built = a1.built return nil } + if err := allowInstall(a); err != nil { + return err + } if err := b.Mkdir(a.Objdir); err != nil { return err @@ -1524,6 +1548,13 @@ func BuildInstallFunc(b *Builder, a *Action) (err error) { return b.moveOrCopyFile(a.Target, a1.built, perm, false) } +// allowInstall returns a non-nil error if this invocation of the go command is +// allowed to install a.Target. +// +// (The build of cmd/go running under its own test is forbidden from installing +// to its original GOROOT.) +var allowInstall = func(*Action) error { return nil } + // cleanup removes a's object dir to keep the amount of // on-disk garbage down in a large build. On an operating system // with aggressive buffering, cleaning incrementally like @@ -1687,6 +1718,10 @@ func (b *Builder) installHeader(a *Action) error { return nil } + if err := allowInstall(a); err != nil { + return err + } + dir, _ := filepath.Split(a.Target) if dir != "" { if err := b.Mkdir(dir); err != nil { @@ -1927,7 +1962,7 @@ func (b *Builder) runOut(a *Action, dir string, env []string, cmdargs ...interfa cleanup := passLongArgsInResponseFiles(cmd) defer cleanup() cmd.Dir = dir - cmd.Env = base.EnvForDir(cmd.Dir, os.Environ()) + cmd.Env = base.AppendPWD(os.Environ(), cmd.Dir) cmd.Env = append(cmd.Env, env...) start := time.Now() err := cmd.Run() @@ -2134,9 +2169,41 @@ func (b *Builder) gfortran(a *Action, p *load.Package, workdir, out string, flag func (b *Builder) ccompile(a *Action, p *load.Package, outfile string, flags []string, file string, compiler []string) error { file = mkAbs(p.Dir, file) desc := p.ImportPath - if !filepath.IsAbs(outfile) { - outfile = filepath.Join(p.Dir, outfile) + outfile = mkAbs(p.Dir, outfile) + + // Elide source directory paths if -trimpath or GOROOT_FINAL is set. + // This is needed for source files (e.g., a .c file in a package directory). + // TODO(golang.org/issue/36072): cgo also generates files with #line + // directives pointing to the source directory. It should not generate those + // when -trimpath is enabled. + if b.gccSupportsFlag(compiler, "-fdebug-prefix-map=a=b") { + if cfg.BuildTrimpath { + // Keep in sync with Action.trimpath. + // The trimmed paths are a little different, but we need to trim in the + // same situations. + var from, toPath string + if m := p.Module; m != nil { + from = m.Dir + toPath = m.Path + "@" + m.Version + } else { + from = p.Dir + toPath = p.ImportPath + } + // -fdebug-prefix-map requires an absolute "to" path (or it joins the path + // with the working directory). Pick something that makes sense for the + // target platform. + var to string + if cfg.BuildContext.GOOS == "windows" { + to = filepath.Join(`\\_\_`, toPath) + } else { + to = filepath.Join("/_", toPath) + } + flags = append(flags[:len(flags):len(flags)], "-fdebug-prefix-map="+from+"="+to) + } else if p.Goroot && cfg.GOROOT_FINAL != cfg.GOROOT { + flags = append(flags[:len(flags):len(flags)], "-fdebug-prefix-map="+cfg.GOROOT+"="+cfg.GOROOT_FINAL) + } } + output, err := b.runOut(a, filepath.Dir(file), b.cCompilerEnv(), compiler, flags, "-o", outfile, "-c", filepath.Base(file)) if len(output) > 0 { // On FreeBSD 11, when we pass -g to clang 3.8 it @@ -2375,13 +2442,25 @@ func (b *Builder) gccSupportsFlag(compiler []string, flag string) bool { if b.flagCache == nil { b.flagCache = make(map[[2]string]bool) } + + tmp := os.DevNull + if runtime.GOOS == "windows" { + f, err := ioutil.TempFile(b.WorkDir, "") + if err != nil { + return false + } + f.Close() + tmp = f.Name() + defer os.Remove(tmp) + } + // We used to write an empty C file, but that gets complicated with // go build -n. We tried using a file that does not exist, but that // fails on systems with GCC version 4.2.1; that is the last GPLv2 // version of GCC, so some systems have frozen on it. // Now we pass an empty file on stdin, which should work at least for // GCC and clang. - cmdArgs := str.StringList(compiler, flag, "-c", "-x", "c", "-", "-o", os.DevNull) + cmdArgs := str.StringList(compiler, flag, "-c", "-x", "c", "-", "-o", tmp) if cfg.BuildN || cfg.BuildX { b.Showcmd(b.WorkDir, "%s || true", joinUnambiguously(cmdArgs)) if cfg.BuildN { @@ -2390,7 +2469,7 @@ func (b *Builder) gccSupportsFlag(compiler []string, flag string) bool { } cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...) cmd.Dir = b.WorkDir - cmd.Env = base.EnvForDir(cmd.Dir, os.Environ()) + cmd.Env = base.AppendPWD(os.Environ(), cmd.Dir) cmd.Env = append(cmd.Env, "LC_ALL=C") out, _ := cmd.CombinedOutput() // GCC says "unrecognized command line option". @@ -2946,13 +3025,13 @@ func mkAbsFiles(dir string, files []string) []string { return abs } -// passLongArgsInResponseFiles modifies cmd on Windows such that, for +// passLongArgsInResponseFiles modifies cmd such that, for // certain programs, long arguments are passed in "response files", a // file on disk with the arguments, with one arg per line. An actual // argument starting with '@' means that the rest of the argument is // a filename of arguments to expand. // -// See Issue 18468. +// See issues 18468 (Windows) and 37768 (Darwin). func passLongArgsInResponseFiles(cmd *exec.Cmd) (cleanup func()) { cleanup = func() {} // no cleanup by default @@ -2990,11 +3069,6 @@ func passLongArgsInResponseFiles(cmd *exec.Cmd) (cleanup func()) { } func useResponseFile(path string, argLen int) bool { - // Unless we're on Windows, don't use response files. - if runtime.GOOS != "windows" { - return false - } - // Unless the program uses objabi.Flagparse, which understands // response files, don't use response files. // TODO: do we need more commands? asm? cgo? For now, no. @@ -3007,6 +3081,8 @@ func useResponseFile(path string, argLen int) bool { // Windows has a limit of 32 KB arguments. To be conservative and not // worry about whether that includes spaces or not, just use 30 KB. + // Darwin's limit is less clear. The OS claims 256KB, but we've seen + // failures with arglen as small as 50KB. if argLen > (30 << 10) { return true } diff --git a/libgo/go/cmd/go/internal/work/gc.go b/libgo/go/cmd/go/internal/work/gc.go index 7d17c0c01ed..f1d08e02686 100644 --- a/libgo/go/cmd/go/internal/work/gc.go +++ b/libgo/go/cmd/go/internal/work/gc.go @@ -37,6 +37,17 @@ func (gcToolchain) linker() string { return base.Tool("link") } +func pkgPath(a *Action) string { + p := a.Package + ppath := p.ImportPath + if cfg.BuildBuildmode == "plugin" { + ppath = pluginPath(a) + } else if p.Name == "main" && !p.Internal.ForceLibrary { + ppath = "main" + } + return ppath +} + func (gcToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, output []byte, err error) { p := a.Package objdir := a.Objdir @@ -47,12 +58,7 @@ func (gcToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, s ofile = objdir + out } - pkgpath := p.ImportPath - if cfg.BuildBuildmode == "plugin" { - pkgpath = pluginPath(a) - } else if p.Name == "main" && !p.Internal.ForceLibrary { - pkgpath = "main" - } + pkgpath := pkgPath(a) gcargs := []string{"-p", pkgpath} if p.Module != nil && p.Module.GoVersion != "" && allowedVersion(p.Module.GoVersion) { gcargs = append(gcargs, "-lang=go"+p.Module.GoVersion) @@ -162,7 +168,7 @@ func gcBackendConcurrency(gcflags []string) int { CheckFlags: for _, flag := range gcflags { // Concurrent compilation is presumed incompatible with any gcflags, - // except for a small whitelist of commonly used flags. + // except for known commonly used flags. // If the user knows better, they can manually add their own -c to the gcflags. switch flag { case "-N", "-l", "-S", "-B", "-C", "-I": @@ -217,6 +223,10 @@ CheckFlags: // trimpath returns the -trimpath argument to use // when compiling the action. func (a *Action) trimpath() string { + // Keep in sync with Builder.ccompile + // The trimmed paths are a little different, but we need to trim in the + // same situations. + // Strip the object directory entirely. objdir := a.Objdir if len(objdir) > 1 && objdir[len(objdir)-1] == filepath.Separator { @@ -240,7 +250,8 @@ func (a *Action) trimpath() string { func asmArgs(a *Action, p *load.Package) []interface{} { // Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files. inc := filepath.Join(cfg.GOROOT, "pkg", "include") - args := []interface{}{cfg.BuildToolexec, base.Tool("asm"), "-trimpath", a.trimpath(), "-I", a.Objdir, "-I", inc, "-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch, forcedAsmflags, p.Internal.Asmflags} + pkgpath := pkgPath(a) + args := []interface{}{cfg.BuildToolexec, base.Tool("asm"), "-p", pkgpath, "-trimpath", a.trimpath(), "-I", a.Objdir, "-I", inc, "-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch, forcedAsmflags, p.Internal.Asmflags} if p.ImportPath == "runtime" && cfg.Goarch == "386" { for _, arg := range forcedAsmflags { if arg == "-dynlink" { diff --git a/libgo/go/cmd/go/internal/work/init.go b/libgo/go/cmd/go/internal/work/init.go index 9091f986368..dad3b10111d 100644 --- a/libgo/go/cmd/go/internal/work/init.go +++ b/libgo/go/cmd/go/internal/work/init.go @@ -10,11 +10,13 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cfg" "cmd/go/internal/load" + "cmd/internal/objabi" "cmd/internal/sys" "flag" "fmt" "os" "path/filepath" + "runtime" "strings" ) @@ -34,6 +36,20 @@ func BuildInit() { } cfg.BuildPkgdir = p } + + // For each experiment that has been enabled in the toolchain, define a + // build tag with the same name but prefixed by "goexperiment." which can be + // used for compiling alternative files for the experiment. This allows + // changes for the experiment, like extra struct fields in the runtime, + // without affecting the base non-experiment code at all. [2:] strips the + // leading "X:" from objabi.Expstring(). + exp := objabi.Expstring()[2:] + if exp != "none" { + experiments := strings.Split(exp, ",") + for _, expt := range experiments { + cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, "goexperiment."+expt) + } + } } func instrumentInit() { @@ -69,7 +85,12 @@ func instrumentInit() { modeFlag := "-" + mode if !cfg.BuildContext.CgoEnabled { - fmt.Fprintf(os.Stderr, "go %s: %s requires cgo; enable cgo by setting CGO_ENABLED=1\n", flag.Args()[0], modeFlag) + if runtime.GOOS != cfg.Goos || runtime.GOARCH != cfg.Goarch { + fmt.Fprintf(os.Stderr, "go %s: %s requires cgo\n", flag.Args()[0], modeFlag) + } else { + fmt.Fprintf(os.Stderr, "go %s: %s requires cgo; enable cgo by setting CGO_ENABLED=1\n", flag.Args()[0], modeFlag) + } + base.SetExitStatus(2) base.Exit() } @@ -102,7 +123,7 @@ func buildModeInit() { switch cfg.Goos { case "darwin": switch cfg.Goarch { - case "arm", "arm64": + case "arm64": codegenArg = "-shared" } @@ -134,9 +155,11 @@ func buildModeInit() { case "android": codegenArg = "-shared" ldBuildmode = "pie" + case "windows": + ldBuildmode = "pie" case "darwin": switch cfg.Goarch { - case "arm", "arm64": + case "arm64": codegenArg = "-shared" } fallthrough @@ -161,8 +184,12 @@ func buildModeInit() { } if gccgo { codegenArg = "-fPIE" - } else if cfg.Goos != "aix" { - codegenArg = "-shared" + } else { + switch cfg.Goos { + case "aix", "windows": + default: + codegenArg = "-shared" + } } ldBuildmode = "pie" case "shared": diff --git a/libgo/go/cmd/go/internal/work/security.go b/libgo/go/cmd/go/internal/work/security.go index 0ce1664c16f..3ee68ac1b41 100644 --- a/libgo/go/cmd/go/internal/work/security.go +++ b/libgo/go/cmd/go/internal/work/security.go @@ -184,7 +184,9 @@ var validLinkerFlags = []*lazyregexp.Regexp{ re(`-Wl,--enable-new-dtags`), re(`-Wl,--end-group`), re(`-Wl,--(no-)?export-dynamic`), + re(`-Wl,-E`), re(`-Wl,-framework,[^,@\-][^,]+`), + re(`-Wl,--hash-style=(sysv|gnu|both)`), re(`-Wl,-headerpad_max_install_names`), re(`-Wl,--no-undefined`), re(`-Wl,-R([^@\-][^,@]*$)`), @@ -200,6 +202,7 @@ var validLinkerFlags = []*lazyregexp.Regexp{ re(`-Wl,-undefined[=,]([^,@\-][^,]+)`), re(`-Wl,-?-unresolved-symbols=[^,]+`), re(`-Wl,--(no-)?warn-([^,]+)`), + re(`-Wl,-?-wrap[=,][^,@\-][^,]*`), re(`-Wl,-z,(no)?execstack`), re(`-Wl,-z,relro`), diff --git a/libgo/go/cmd/go/internal/work/security_test.go b/libgo/go/cmd/go/internal/work/security_test.go index 6b85c40b13b..11e74f29c6a 100644 --- a/libgo/go/cmd/go/internal/work/security_test.go +++ b/libgo/go/cmd/go/internal/work/security_test.go @@ -131,6 +131,7 @@ var goodLinkerFlags = [][]string{ {"-mtune=happybirthday"}, {"-pic"}, {"-pthread"}, + {"-Wl,--hash-style=both"}, {"-Wl,-rpath,foo"}, {"-Wl,-rpath,$ORIGIN/foo"}, {"-Wl,-R", "/foo"}, @@ -208,6 +209,7 @@ var badLinkerFlags = [][]string{ {"-Wl,-framework", "-Wl,@Home"}, {"-Wl,-framework", "@Home"}, {"-Wl,-framework,Chocolate,@Home"}, + {"-Wl,--hash-style=foo"}, {"-x", "--c"}, {"-x", "@obj"}, {"-Wl,-rpath,@foo"}, diff --git a/libgo/go/cmd/go/internal/work/testgo.go b/libgo/go/cmd/go/internal/work/testgo.go index 3e623c66210..931f49a0691 100644 --- a/libgo/go/cmd/go/internal/work/testgo.go +++ b/libgo/go/cmd/go/internal/work/testgo.go @@ -8,10 +8,41 @@ package work -import "os" +import ( + "cmd/go/internal/cfg" + "cmd/go/internal/search" + "fmt" + "os" + "path/filepath" + "runtime" +) func init() { if v := os.Getenv("TESTGO_VERSION"); v != "" { runtimeVersion = v } + + if testGOROOT := os.Getenv("TESTGO_GOROOT"); testGOROOT != "" { + // Disallow installs to the GOROOT from which testgo was built. + // Installs to other GOROOTs — such as one set explicitly within a test — are ok. + allowInstall = func(a *Action) error { + if cfg.BuildN { + return nil + } + + rel := search.InDir(a.Target, testGOROOT) + if rel == "" { + return nil + } + + callerPos := "" + if _, file, line, ok := runtime.Caller(1); ok { + if shortFile := search.InDir(file, filepath.Join(testGOROOT, "src")); shortFile != "" { + file = shortFile + } + callerPos = fmt.Sprintf("%s:%d: ", file, line) + } + return fmt.Errorf("%stestgo must not write to GOROOT (installing to %s)", callerPos, filepath.Join("GOROOT", rel)) + } + } } diff --git a/libgo/go/cmd/go/main.go b/libgo/go/cmd/go/main.go index bb442b5f8e4..11913d6f063 100644 --- a/libgo/go/cmd/go/main.go +++ b/libgo/go/cmd/go/main.go @@ -59,6 +59,7 @@ func init() { version.CmdVersion, vet.CmdVet, + help.HelpBuildConstraint, help.HelpBuildmode, help.HelpC, help.HelpCache, @@ -185,7 +186,7 @@ BigCmdLoop: if cmd.CustomFlags { args = args[1:] } else { - base.SetFromGOFLAGS(cmd.Flag) + base.SetFromGOFLAGS(&cmd.Flag) cmd.Flag.Parse(args[1:]) args = cmd.Flag.Args() } diff --git a/libgo/go/cmd/go/note_test.go b/libgo/go/cmd/go/note_test.go index e94e82bd5bd..b2d3179a1e3 100644 --- a/libgo/go/cmd/go/note_test.go +++ b/libgo/go/cmd/go/note_test.go @@ -20,6 +20,8 @@ func TestNoteReading(t *testing.T) { // both in internal and external linking mode. tg := testgo(t) defer tg.cleanup() + tg.parallel() + tg.tempFile("hello.go", `package main; func main() { print("hello, world\n") }`) const buildID = "TestNoteReading-Build-ID" tg.run("build", "-ldflags", "-buildid="+buildID, "-o", tg.path("hello.exe"), tg.path("hello.go")) @@ -53,7 +55,7 @@ func TestNoteReading(t *testing.T) { // we've had trouble reading the notes generated by gold. err := tg.doRun([]string{"build", "-ldflags", "-buildid=" + buildID + " -linkmode=external -extldflags=-fuse-ld=gold", "-o", tg.path("hello3.exe"), tg.path("hello.go")}) if err != nil { - if tg.grepCountBoth("(invalid linker|gold|cannot find 'ld')") > 0 { + if tg.grepCountBoth("(invalid linker|gold|cannot find [‘']ld[’'])") > 0 { // It's not an error if gold isn't there. gcc claims it "cannot find 'ld'" if // ld.gold is missing, see issue #22340. t.Log("skipping gold test") diff --git a/libgo/go/cmd/go/proxy_test.go b/libgo/go/cmd/go/proxy_test.go index 8214488a59a..2a4d2935b38 100644 --- a/libgo/go/cmd/go/proxy_test.go +++ b/libgo/go/cmd/go/proxy_test.go @@ -174,6 +174,25 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) { return } + // Request for $GOPROXY/redirect//... goes to redirects. + if strings.HasPrefix(path, "redirect/") { + path = path[len("redirect/"):] + if j := strings.Index(path, "/"); j >= 0 { + count, err := strconv.Atoi(path[:j]) + if err != nil { + return + } + + // The last redirect. + if count <= 1 { + http.Redirect(w, r, fmt.Sprintf("/mod/%s", path[j+1:]), 302) + return + } + http.Redirect(w, r, fmt.Sprintf("/mod/redirect/%d/%s", count-1, path[j+1:]), 302) + return + } + } + // Request for $GOPROXY/sumdb//supported // is checking whether it's OK to access sumdb via the proxy. if path == "sumdb/"+testSumDBName+"/supported" { diff --git a/libgo/go/cmd/go/script_test.go b/libgo/go/cmd/go/script_test.go index ec498bbcd76..2e8f18a8972 100644 --- a/libgo/go/cmd/go/script_test.go +++ b/libgo/go/cmd/go/script_test.go @@ -10,6 +10,7 @@ package main_test import ( "bytes" "context" + "errors" "fmt" "go/build" "internal/testenv" @@ -30,6 +31,7 @@ import ( "cmd/go/internal/robustio" "cmd/go/internal/txtar" "cmd/go/internal/work" + "cmd/internal/objabi" "cmd/internal/sys" ) @@ -76,15 +78,26 @@ type testScript struct { stderr string // standard error from last 'go' command; for 'stderr' command stopped bool // test wants to stop early start time.Time // time phase started - background []backgroundCmd // backgrounded 'exec' and 'go' commands + background []*backgroundCmd // backgrounded 'exec' and 'go' commands } type backgroundCmd struct { - cmd *exec.Cmd - wait <-chan struct{} - neg bool // if true, cmd should fail + want simpleStatus + args []string + cancel context.CancelFunc + done <-chan struct{} + err error + stdout, stderr strings.Builder } +type simpleStatus string + +const ( + success simpleStatus = "" + failure simpleStatus = "!" + successOrFailure simpleStatus = "?" +) + var extraEnvKeys = []string{ "SYSTEMROOT", // must be preserved on Windows to find DLLs; golang.org/issue/25210 "WINDIR", // must be preserved on Windows to be able to run PowerShell command; golang.org/issue/30711 @@ -109,12 +122,16 @@ func (ts *testScript) setup() { "CCACHE_DISABLE=1", // ccache breaks with non-existent HOME "GOARCH=" + runtime.GOARCH, "GOCACHE=" + testGOCACHE, + "GODEBUG=" + os.Getenv("GODEBUG"), "GOEXE=" + cfg.ExeSuffix, + "GOEXPSTRING=" + objabi.Expstring()[2:], "GOOS=" + runtime.GOOS, "GOPATH=" + filepath.Join(ts.workdir, "gopath"), "GOPROXY=" + proxyURL, "GOPRIVATE=", "GOROOT=" + testGOROOT, + "GOROOT_FINAL=" + os.Getenv("GOROOT_FINAL"), // causes spurious rebuilds and breaks the "stale" built-in if not propagated + "TESTGO_GOROOT=" + testGOROOT, "GOSUMDB=" + testSumDBVerifierKey, "GONOPROXY=", "GONOSUMDB=", @@ -181,10 +198,10 @@ func (ts *testScript) run() { // before we print PASS. If we return early (e.g., due to a test failure), // don't print anything about the processes that were still running. for _, bg := range ts.background { - interruptProcess(bg.cmd.Process) + bg.cancel() } for _, bg := range ts.background { - <-bg.wait + <-bg.done } ts.background = nil @@ -205,7 +222,7 @@ func (ts *testScript) run() { // With -v or -testwork, start log with full environment. if *testWork || testing.Verbose() { // Display environment. - ts.cmdEnv(false, nil) + ts.cmdEnv(success, nil) fmt.Fprintf(&ts.log, "\n") ts.mark = ts.log.Len() } @@ -245,7 +262,7 @@ Script: // Parse input line. Ignore blanks entirely. parsed := ts.parse(line) if parsed.name == "" { - if parsed.neg || len(parsed.conds) > 0 { + if parsed.want != "" || len(parsed.conds) > 0 { ts.fatalf("missing command") } continue @@ -324,7 +341,7 @@ Script: if cmd == nil { ts.fatalf("unknown command %q", parsed.name) } - cmd(ts, parsed.neg, parsed.args) + cmd(ts, parsed.want, parsed.args) // Command can ask script to stop early. if ts.stopped { @@ -335,9 +352,9 @@ Script: } for _, bg := range ts.background { - interruptProcess(bg.cmd.Process) + bg.cancel() } - ts.cmdWait(false, nil) + ts.cmdWait(success, nil) // Final phase ended. rewind() @@ -352,7 +369,7 @@ Script: // // NOTE: If you make changes here, update testdata/script/README too! // -var scriptCmds = map[string]func(*testScript, bool, []string){ +var scriptCmds = map[string]func(*testScript, simpleStatus, []string){ "addcrlf": (*testScript).cmdAddcrlf, "cc": (*testScript).cmdCc, "cd": (*testScript).cmdCd, @@ -385,7 +402,7 @@ var regexpCmd = map[string]bool{ } // addcrlf adds CRLF line endings to the named files. -func (ts *testScript) cmdAddcrlf(neg bool, args []string) { +func (ts *testScript) cmdAddcrlf(want simpleStatus, args []string) { if len(args) == 0 { ts.fatalf("usage: addcrlf file...") } @@ -399,21 +416,21 @@ func (ts *testScript) cmdAddcrlf(neg bool, args []string) { } // cc runs the C compiler along with platform specific options. -func (ts *testScript) cmdCc(neg bool, args []string) { +func (ts *testScript) cmdCc(want simpleStatus, args []string) { if len(args) < 1 || (len(args) == 1 && args[0] == "&") { ts.fatalf("usage: cc args... [&]") } var b work.Builder b.Init() - ts.cmdExec(neg, append(b.GccCmd(".", ""), args...)) + ts.cmdExec(want, append(b.GccCmd(".", ""), args...)) robustio.RemoveAll(b.WorkDir) } // cd changes to a different directory. -func (ts *testScript) cmdCd(neg bool, args []string) { - if neg { - ts.fatalf("unsupported: ! cd") +func (ts *testScript) cmdCd(want simpleStatus, args []string) { + if want != success { + ts.fatalf("unsupported: %v cd", want) } if len(args) != 1 { ts.fatalf("usage: cd dir") @@ -437,9 +454,9 @@ func (ts *testScript) cmdCd(neg bool, args []string) { } // chmod changes permissions for a file or directory. -func (ts *testScript) cmdChmod(neg bool, args []string) { - if neg { - ts.fatalf("unsupported: ! chmod") +func (ts *testScript) cmdChmod(want simpleStatus, args []string) { + if want != success { + ts.fatalf("unsupported: %v chmod", want) } if len(args) < 2 { ts.fatalf("usage: chmod perm paths...") @@ -459,10 +476,10 @@ func (ts *testScript) cmdChmod(neg bool, args []string) { } // cmp compares two files. -func (ts *testScript) cmdCmp(neg bool, args []string) { - if neg { +func (ts *testScript) cmdCmp(want simpleStatus, args []string) { + if want != success { // It would be strange to say "this file can have any content except this precise byte sequence". - ts.fatalf("unsupported: ! cmp") + ts.fatalf("unsupported: %v cmp", want) } quiet := false if len(args) > 0 && args[0] == "-q" { @@ -476,9 +493,9 @@ func (ts *testScript) cmdCmp(neg bool, args []string) { } // cmpenv compares two files with environment variable substitution. -func (ts *testScript) cmdCmpenv(neg bool, args []string) { - if neg { - ts.fatalf("unsupported: ! cmpenv") +func (ts *testScript) cmdCmpenv(want simpleStatus, args []string) { + if want != success { + ts.fatalf("unsupported: %v cmpenv", want) } quiet := false if len(args) > 0 && args[0] == "-q" { @@ -524,7 +541,7 @@ func (ts *testScript) doCmdCmp(args []string, env, quiet bool) { } // cp copies files, maybe eventually directories. -func (ts *testScript) cmdCp(neg bool, args []string) { +func (ts *testScript) cmdCp(want simpleStatus, args []string) { if len(args) < 2 { ts.fatalf("usage: cp src... dst") } @@ -564,20 +581,21 @@ func (ts *testScript) cmdCp(neg bool, args []string) { targ = filepath.Join(dst, filepath.Base(src)) } err := ioutil.WriteFile(targ, data, mode) - if neg { + switch want { + case failure: if err == nil { ts.fatalf("unexpected command success") } - } else { + case success: ts.check(err) } } } // env displays or adds to the environment. -func (ts *testScript) cmdEnv(neg bool, args []string) { - if neg { - ts.fatalf("unsupported: ! env") +func (ts *testScript) cmdEnv(want simpleStatus, args []string) { + if want != success { + ts.fatalf("unsupported: %v env", want) } conv := func(s string) string { return s } @@ -615,86 +633,96 @@ func (ts *testScript) cmdEnv(neg bool, args []string) { } // exec runs the given command. -func (ts *testScript) cmdExec(neg bool, args []string) { +func (ts *testScript) cmdExec(want simpleStatus, args []string) { if len(args) < 1 || (len(args) == 1 && args[0] == "&") { ts.fatalf("usage: exec program [args...] [&]") } - var err error + background := false if len(args) > 0 && args[len(args)-1] == "&" { - var cmd *exec.Cmd - cmd, err = ts.execBackground(args[0], args[1:len(args)-1]...) - if err == nil { - wait := make(chan struct{}) - go func() { - ctxWait(testCtx, cmd) - close(wait) - }() - ts.background = append(ts.background, backgroundCmd{cmd, wait, neg}) - } - ts.stdout, ts.stderr = "", "" - } else { - ts.stdout, ts.stderr, err = ts.exec(args[0], args[1:]...) - if ts.stdout != "" { - fmt.Fprintf(&ts.log, "[stdout]\n%s", ts.stdout) - } - if ts.stderr != "" { - fmt.Fprintf(&ts.log, "[stderr]\n%s", ts.stderr) - } - if err == nil && neg { - ts.fatalf("unexpected command success") - } + background = true + args = args[:len(args)-1] } + bg, err := ts.startBackground(want, args[0], args[1:]...) if err != nil { - fmt.Fprintf(&ts.log, "[%v]\n", err) - if testCtx.Err() != nil { - ts.fatalf("test timed out while running command") - } else if !neg { - ts.fatalf("unexpected command failure") - } + ts.fatalf("unexpected error starting command: %v", err) + } + if background { + ts.stdout, ts.stderr = "", "" + ts.background = append(ts.background, bg) + return + } + + <-bg.done + ts.stdout = bg.stdout.String() + ts.stderr = bg.stderr.String() + if ts.stdout != "" { + fmt.Fprintf(&ts.log, "[stdout]\n%s", ts.stdout) } + if ts.stderr != "" { + fmt.Fprintf(&ts.log, "[stderr]\n%s", ts.stderr) + } + if bg.err != nil { + fmt.Fprintf(&ts.log, "[%v]\n", bg.err) + } + ts.checkCmd(bg) } // exists checks that the list of files exists. -func (ts *testScript) cmdExists(neg bool, args []string) { - var readonly bool - if len(args) > 0 && args[0] == "-readonly" { - readonly = true - args = args[1:] +func (ts *testScript) cmdExists(want simpleStatus, args []string) { + if want == successOrFailure { + ts.fatalf("unsupported: %v exists", want) + } + var readonly, exec bool +loop: + for len(args) > 0 { + switch args[0] { + case "-readonly": + readonly = true + args = args[1:] + case "-exec": + exec = true + args = args[1:] + default: + break loop + } } if len(args) == 0 { - ts.fatalf("usage: exists [-readonly] file...") + ts.fatalf("usage: exists [-readonly] [-exec] file...") } for _, file := range args { file = ts.mkabs(file) info, err := os.Stat(file) - if err == nil && neg { + if err == nil && want == failure { what := "file" if info.IsDir() { what = "directory" } ts.fatalf("%s %s unexpectedly exists", what, file) } - if err != nil && !neg { + if err != nil && want == success { ts.fatalf("%s does not exist", file) } - if err == nil && !neg && readonly && info.Mode()&0222 != 0 { + if err == nil && want == success && readonly && info.Mode()&0222 != 0 { ts.fatalf("%s exists but is writable", file) } + if err == nil && want == success && exec && runtime.GOOS != "windows" && info.Mode()&0111 == 0 { + ts.fatalf("%s exists but is not executable", file) + } } } // go runs the go command. -func (ts *testScript) cmdGo(neg bool, args []string) { - ts.cmdExec(neg, append([]string{testGo}, args...)) +func (ts *testScript) cmdGo(want simpleStatus, args []string) { + ts.cmdExec(want, append([]string{testGo}, args...)) } // mkdir creates directories. -func (ts *testScript) cmdMkdir(neg bool, args []string) { - if neg { - ts.fatalf("unsupported: ! mkdir") +func (ts *testScript) cmdMkdir(want simpleStatus, args []string) { + if want != success { + ts.fatalf("unsupported: %v mkdir", want) } if len(args) < 1 { ts.fatalf("usage: mkdir dir...") @@ -705,9 +733,9 @@ func (ts *testScript) cmdMkdir(neg bool, args []string) { } // rm removes files or directories. -func (ts *testScript) cmdRm(neg bool, args []string) { - if neg { - ts.fatalf("unsupported: ! rm") +func (ts *testScript) cmdRm(want simpleStatus, args []string) { + if want != success { + ts.fatalf("unsupported: %v rm", want) } if len(args) < 1 { ts.fatalf("usage: rm file...") @@ -720,20 +748,20 @@ func (ts *testScript) cmdRm(neg bool, args []string) { } // skip marks the test skipped. -func (ts *testScript) cmdSkip(neg bool, args []string) { +func (ts *testScript) cmdSkip(want simpleStatus, args []string) { if len(args) > 1 { ts.fatalf("usage: skip [msg]") } - if neg { - ts.fatalf("unsupported: ! skip") + if want != success { + ts.fatalf("unsupported: %v skip", want) } // Before we mark the test as skipped, shut down any background processes and // make sure they have returned the correct status. for _, bg := range ts.background { - interruptProcess(bg.cmd.Process) + bg.cancel() } - ts.cmdWait(false, nil) + ts.cmdWait(success, nil) if len(args) == 1 { ts.t.Skip(args[0]) @@ -742,15 +770,18 @@ func (ts *testScript) cmdSkip(neg bool, args []string) { } // stale checks that the named build targets are stale. -func (ts *testScript) cmdStale(neg bool, args []string) { +func (ts *testScript) cmdStale(want simpleStatus, args []string) { if len(args) == 0 { ts.fatalf("usage: stale target...") } - tmpl := "{{if .Error}}{{.ImportPath}}: {{.Error.Err}}{else}}" - if neg { + tmpl := "{{if .Error}}{{.ImportPath}}: {{.Error.Err}}{{else}}" + switch want { + case failure: tmpl += "{{if .Stale}}{{.ImportPath}} is unexpectedly stale{{end}}" - } else { + case success: tmpl += "{{if not .Stale}}{{.ImportPath}} is unexpectedly NOT stale{{end}}" + default: + ts.fatalf("unsupported: %v stale", want) } tmpl += "{{end}}" goArgs := append([]string{"list", "-e", "-f=" + tmpl}, args...) @@ -764,26 +795,30 @@ func (ts *testScript) cmdStale(neg bool, args []string) { } // stdout checks that the last go command standard output matches a regexp. -func (ts *testScript) cmdStdout(neg bool, args []string) { - scriptMatch(ts, neg, args, ts.stdout, "stdout") +func (ts *testScript) cmdStdout(want simpleStatus, args []string) { + scriptMatch(ts, want, args, ts.stdout, "stdout") } // stderr checks that the last go command standard output matches a regexp. -func (ts *testScript) cmdStderr(neg bool, args []string) { - scriptMatch(ts, neg, args, ts.stderr, "stderr") +func (ts *testScript) cmdStderr(want simpleStatus, args []string) { + scriptMatch(ts, want, args, ts.stderr, "stderr") } // grep checks that file content matches a regexp. // Like stdout/stderr and unlike Unix grep, it accepts Go regexp syntax. -func (ts *testScript) cmdGrep(neg bool, args []string) { - scriptMatch(ts, neg, args, "", "grep") +func (ts *testScript) cmdGrep(want simpleStatus, args []string) { + scriptMatch(ts, want, args, "", "grep") } // scriptMatch implements both stdout and stderr. -func scriptMatch(ts *testScript, neg bool, args []string, text, name string) { +func scriptMatch(ts *testScript, want simpleStatus, args []string, text, name string) { + if want == successOrFailure { + ts.fatalf("unsupported: %v %s", want, name) + } + n := 0 if len(args) >= 1 && strings.HasPrefix(args[0], "-count=") { - if neg { + if want == failure { ts.fatalf("cannot use -count= with negated match") } var err error @@ -803,12 +838,12 @@ func scriptMatch(ts *testScript, neg bool, args []string, text, name string) { } extraUsage := "" - want := 1 + wantArgs := 1 if name == "grep" { extraUsage = " file" - want = 2 + wantArgs = 2 } - if len(args) != want { + if len(args) != wantArgs { ts.fatalf("usage: %s [-count=N] 'pattern'%s", name, extraUsage) } @@ -829,14 +864,16 @@ func scriptMatch(ts *testScript, neg bool, args []string, text, name string) { // Matching against workdir would be misleading. text = strings.ReplaceAll(text, ts.workdir, "$WORK") - if neg { + switch want { + case failure: if re.MatchString(text) { if isGrep && !quiet { fmt.Fprintf(&ts.log, "[%s]\n%s\n", name, text) } ts.fatalf("unexpected match for %#q found in %s: %s", pattern, name, re.FindString(text)) } - } else { + + case success: if !re.MatchString(text) { if isGrep && !quiet { fmt.Fprintf(&ts.log, "[%s]\n%s\n", name, text) @@ -856,9 +893,9 @@ func scriptMatch(ts *testScript, neg bool, args []string, text, name string) { } // stop stops execution of the test (marking it passed). -func (ts *testScript) cmdStop(neg bool, args []string) { - if neg { - ts.fatalf("unsupported: ! stop") +func (ts *testScript) cmdStop(want simpleStatus, args []string) { + if want != success { + ts.fatalf("unsupported: %v stop", want) } if len(args) > 1 { ts.fatalf("usage: stop [msg]") @@ -872,9 +909,9 @@ func (ts *testScript) cmdStop(neg bool, args []string) { } // symlink creates a symbolic link. -func (ts *testScript) cmdSymlink(neg bool, args []string) { - if neg { - ts.fatalf("unsupported: ! symlink") +func (ts *testScript) cmdSymlink(want simpleStatus, args []string) { + if want != success { + ts.fatalf("unsupported: %v symlink", want) } if len(args) != 3 || args[1] != "->" { ts.fatalf("usage: symlink file -> target") @@ -885,9 +922,9 @@ func (ts *testScript) cmdSymlink(neg bool, args []string) { } // wait waits for background commands to exit, setting stderr and stdout to their result. -func (ts *testScript) cmdWait(neg bool, args []string) { - if neg { - ts.fatalf("unsupported: ! wait") +func (ts *testScript) cmdWait(want simpleStatus, args []string) { + if want != success { + ts.fatalf("unsupported: %v wait", want) } if len(args) > 0 { ts.fatalf("usage: wait") @@ -895,34 +932,24 @@ func (ts *testScript) cmdWait(neg bool, args []string) { var stdouts, stderrs []string for _, bg := range ts.background { - <-bg.wait + <-bg.done - args := append([]string{filepath.Base(bg.cmd.Args[0])}, bg.cmd.Args[1:]...) - fmt.Fprintf(&ts.log, "[background] %s: %v\n", strings.Join(args, " "), bg.cmd.ProcessState) + args := append([]string{filepath.Base(bg.args[0])}, bg.args[1:]...) + fmt.Fprintf(&ts.log, "[background] %s: %v\n", strings.Join(args, " "), bg.err) - cmdStdout := bg.cmd.Stdout.(*strings.Builder).String() + cmdStdout := bg.stdout.String() if cmdStdout != "" { fmt.Fprintf(&ts.log, "[stdout]\n%s", cmdStdout) stdouts = append(stdouts, cmdStdout) } - cmdStderr := bg.cmd.Stderr.(*strings.Builder).String() + cmdStderr := bg.stderr.String() if cmdStderr != "" { fmt.Fprintf(&ts.log, "[stderr]\n%s", cmdStderr) stderrs = append(stderrs, cmdStderr) } - if bg.cmd.ProcessState.Success() { - if bg.neg { - ts.fatalf("unexpected command success") - } - } else { - if testCtx.Err() != nil { - ts.fatalf("test timed out while running command") - } else if !bg.neg { - ts.fatalf("unexpected command failure") - } - } + ts.checkCmd(bg) } ts.stdout = strings.Join(stdouts, "") @@ -950,58 +977,176 @@ func (ts *testScript) check(err error) { } } +func (ts *testScript) checkCmd(bg *backgroundCmd) { + select { + case <-bg.done: + default: + panic("checkCmd called when not done") + } + + if bg.err == nil { + if bg.want == failure { + ts.fatalf("unexpected command success") + } + return + } + + if errors.Is(bg.err, context.DeadlineExceeded) { + ts.fatalf("test timed out while running command") + } + + if errors.Is(bg.err, context.Canceled) { + // The process was still running at the end of the test. + // The test must not depend on its exit status. + if bg.want != successOrFailure { + ts.fatalf("unexpected background command remaining at test end") + } + return + } + + if bg.want == success { + ts.fatalf("unexpected command failure") + } +} + // exec runs the given command line (an actual subprocess, not simulated) // in ts.cd with environment ts.env and then returns collected standard output and standard error. func (ts *testScript) exec(command string, args ...string) (stdout, stderr string, err error) { - cmd := exec.Command(command, args...) - cmd.Dir = ts.cd - cmd.Env = append(ts.env, "PWD="+ts.cd) - var stdoutBuf, stderrBuf strings.Builder - cmd.Stdout = &stdoutBuf - cmd.Stderr = &stderrBuf - if err = cmd.Start(); err == nil { - err = ctxWait(testCtx, cmd) + bg, err := ts.startBackground(success, command, args...) + if err != nil { + return "", "", err } - return stdoutBuf.String(), stderrBuf.String(), err + <-bg.done + return bg.stdout.String(), bg.stderr.String(), bg.err } -// execBackground starts the given command line (an actual subprocess, not simulated) +// startBackground starts the given command line (an actual subprocess, not simulated) // in ts.cd with environment ts.env. -func (ts *testScript) execBackground(command string, args ...string) (*exec.Cmd, error) { +func (ts *testScript) startBackground(want simpleStatus, command string, args ...string) (*backgroundCmd, error) { + done := make(chan struct{}) + bg := &backgroundCmd{ + want: want, + args: append([]string{command}, args...), + done: done, + cancel: func() {}, + } + + ctx := context.Background() + gracePeriod := 100 * time.Millisecond + if deadline, ok := ts.t.Deadline(); ok { + timeout := time.Until(deadline) + // If time allows, increase the termination grace period to 5% of the + // remaining time. + if gp := timeout / 20; gp > gracePeriod { + gracePeriod = gp + } + + // Send the first termination signal with two grace periods remaining. + // If it still hasn't finished after the first period has elapsed, + // we'll escalate to os.Kill with a second period remaining until the + // test deadline.. + timeout -= 2 * gracePeriod + + if timeout <= 0 { + // The test has less than the grace period remaining. There is no point in + // even starting the command, because it will be terminated immediately. + // Save the expense of starting it in the first place. + bg.err = context.DeadlineExceeded + close(done) + return bg, nil + } + + ctx, bg.cancel = context.WithTimeout(ctx, timeout) + } + cmd := exec.Command(command, args...) cmd.Dir = ts.cd cmd.Env = append(ts.env, "PWD="+ts.cd) - var stdoutBuf, stderrBuf strings.Builder - cmd.Stdout = &stdoutBuf - cmd.Stderr = &stderrBuf - return cmd, cmd.Start() -} - -// ctxWait is like cmd.Wait, but terminates cmd with os.Interrupt if ctx becomes done. -// -// This differs from exec.CommandContext in that it prefers os.Interrupt over os.Kill. -// (See https://golang.org/issue/21135.) -func ctxWait(ctx context.Context, cmd *exec.Cmd) error { - errc := make(chan error, 1) - go func() { errc <- cmd.Wait() }() - - select { - case err := <-errc: - return err - case <-ctx.Done(): - interruptProcess(cmd.Process) - return <-errc + cmd.Stdout = &bg.stdout + cmd.Stderr = &bg.stderr + if err := cmd.Start(); err != nil { + bg.cancel() + return nil, err } + + go func() { + bg.err = waitOrStop(ctx, cmd, stopSignal(), gracePeriod) + close(done) + }() + return bg, nil } -// interruptProcess sends os.Interrupt to p if supported, or os.Kill otherwise. -func interruptProcess(p *os.Process) { - if err := p.Signal(os.Interrupt); err != nil { +// stopSignal returns the appropriate signal to use to request that a process +// stop execution. +func stopSignal() os.Signal { + if runtime.GOOS == "windows" { // Per https://golang.org/pkg/os/#Signal, “Interrupt is not implemented on // Windows; using it with os.Process.Signal will return an error.” // Fall back to Kill instead. - p.Kill() + return os.Kill } + return os.Interrupt +} + +// waitOrStop waits for the already-started command cmd by calling its Wait method. +// +// If cmd does not return before ctx is done, waitOrStop sends it the given interrupt signal. +// If killDelay is positive, waitOrStop waits that additional period for Wait to return before sending os.Kill. +// +// This function is copied from the one added to x/playground/internal in +// http://golang.org/cl/228438. +func waitOrStop(ctx context.Context, cmd *exec.Cmd, interrupt os.Signal, killDelay time.Duration) error { + if cmd.Process == nil { + panic("waitOrStop called with a nil cmd.Process — missing Start call?") + } + if interrupt == nil { + panic("waitOrStop requires a non-nil interrupt signal") + } + + errc := make(chan error) + go func() { + select { + case errc <- nil: + return + case <-ctx.Done(): + } + + err := cmd.Process.Signal(interrupt) + if err == nil { + err = ctx.Err() // Report ctx.Err() as the reason we interrupted. + } else if err.Error() == "os: process already finished" { + errc <- nil + return + } + + if killDelay > 0 { + timer := time.NewTimer(killDelay) + select { + // Report ctx.Err() as the reason we interrupted the process... + case errc <- ctx.Err(): + timer.Stop() + return + // ...but after killDelay has elapsed, fall back to a stronger signal. + case <-timer.C: + } + + // Wait still hasn't returned. + // Kill the process harder to make sure that it exits. + // + // Ignore any error: if cmd.Process has already terminated, we still + // want to send ctx.Err() (or the error from the Interrupt call) + // to properly attribute the signal that may have terminated it. + _ = cmd.Process.Kill() + } + + errc <- err + }() + + waitErr := cmd.Wait() + if interruptErr := <-errc; interruptErr != nil { + return interruptErr + } + return waitErr } // expand applies environment variable expansion to the string s. @@ -1044,7 +1189,7 @@ type condition struct { // A command is a complete command parsed from a script. type command struct { - neg bool // if true, expect the command to fail + want simpleStatus conds []condition // all must be satisfied name string // the name of the command; must be non-empty args []string // shell-expanded arguments following name @@ -1079,11 +1224,13 @@ func (ts *testScript) parse(line string) command { // Command prefix ! means negate the expectations about this command: // go command should fail, match should not be found, etc. - if arg == "!" { - if cmd.neg { - ts.fatalf("duplicated '!' token") + // Prefix ? means allow either success or failure. + switch want := simpleStatus(arg); want { + case failure, successOrFailure: + if cmd.want != "" { + ts.fatalf("duplicated '!' or '?' token") } - cmd.neg = true + cmd.want = want return } @@ -1234,6 +1381,8 @@ var diffTests = []struct { } func TestDiff(t *testing.T) { + t.Parallel() + for _, tt := range diffTests { // Turn spaces into \n. text1 := strings.ReplaceAll(tt.text1, " ", "\n") diff --git a/libgo/go/cmd/go/testdata/example1_test.go b/libgo/go/cmd/go/testdata/example1_test.go deleted file mode 100644 index 87e6c0acfaa..00000000000 --- a/libgo/go/cmd/go/testdata/example1_test.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Make sure that go test runs Example_Z before Example_A, preserving source order. - -package p - -import "fmt" - -var n int - -func Example_Z() { - n++ - fmt.Println(n) - // Output: 1 -} - -func Example_A() { - n++ - fmt.Println(n) - // Output: 2 -} diff --git a/libgo/go/cmd/go/testdata/example2_test.go b/libgo/go/cmd/go/testdata/example2_test.go deleted file mode 100644 index 5d134260051..00000000000 --- a/libgo/go/cmd/go/testdata/example2_test.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Make sure that go test runs Example_Y before Example_B, preserving source order. - -package p - -import "fmt" - -func Example_Y() { - n++ - fmt.Println(n) - // Output: 3 -} - -func Example_B() { - n++ - fmt.Println(n) - // Output: 4 -} diff --git a/libgo/go/cmd/go/testdata/generate/test1.go b/libgo/go/cmd/go/testdata/generate/test1.go deleted file mode 100644 index 168cfb74fbf..00000000000 --- a/libgo/go/cmd/go/testdata/generate/test1.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Simple test for go generate. - -// We include a build tag that go generate should ignore. - -// +build ignore - -//go:generate echo Success - -package p diff --git a/libgo/go/cmd/go/testdata/generate/test2.go b/libgo/go/cmd/go/testdata/generate/test2.go deleted file mode 100644 index 829244a1663..00000000000 --- a/libgo/go/cmd/go/testdata/generate/test2.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Test that go generate handles command aliases. - -//go:generate -command run echo Now is the time -//go:generate run for all good men - -package p diff --git a/libgo/go/cmd/go/testdata/generate/test3.go b/libgo/go/cmd/go/testdata/generate/test3.go deleted file mode 100644 index e950da591a7..00000000000 --- a/libgo/go/cmd/go/testdata/generate/test3.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Test go generate variable substitution. - -//go:generate echo $GOARCH $GOFILE:$GOLINE ${GOPACKAGE}abc xyz$GOPACKAGE/$GOFILE/123 - -package p diff --git a/libgo/go/cmd/go/testdata/generate/test4.go b/libgo/go/cmd/go/testdata/generate/test4.go deleted file mode 100644 index 6dae0486eb4..00000000000 --- a/libgo/go/cmd/go/testdata/generate/test4.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Test -run flag - -//go:generate echo oh yes my man -//go:generate echo no, no, a thousand times no - -package p diff --git a/libgo/go/cmd/go/testdata/mod/example.com_printversion_v0.1.0.txt b/libgo/go/cmd/go/testdata/mod/example.com_printversion_v0.1.0.txt index bae8b13d470..606322ac862 100644 --- a/libgo/go/cmd/go/testdata/mod/example.com_printversion_v0.1.0.txt +++ b/libgo/go/cmd/go/testdata/mod/example.com_printversion_v0.1.0.txt @@ -21,7 +21,13 @@ func main() { info, _ := debug.ReadBuildInfo() fmt.Fprintf(os.Stdout, "path is %s\n", info.Path) fmt.Fprintf(os.Stdout, "main is %s %s\n", info.Main.Path, info.Main.Version) + if r := info.Main.Replace; r != nil { + fmt.Fprintf(os.Stdout, "\t(replaced by %s %s)\n", r.Path, r.Version) + } for _, m := range info.Deps { fmt.Fprintf(os.Stdout, "using %s %s\n", m.Path, m.Version) + if r := m.Replace; r != nil { + fmt.Fprintf(os.Stdout, "\t(replaced by %s %s)\n", r.Path, r.Version) + } } } diff --git a/libgo/go/cmd/go/testdata/mod/example.com_printversion_v1.0.0.txt b/libgo/go/cmd/go/testdata/mod/example.com_printversion_v1.0.0.txt index 246741821af..b9b71e95382 100644 --- a/libgo/go/cmd/go/testdata/mod/example.com_printversion_v1.0.0.txt +++ b/libgo/go/cmd/go/testdata/mod/example.com_printversion_v1.0.0.txt @@ -29,7 +29,13 @@ func main() { info, _ := debug.ReadBuildInfo() fmt.Fprintf(os.Stdout, "path is %s\n", info.Path) fmt.Fprintf(os.Stdout, "main is %s %s\n", info.Main.Path, info.Main.Version) + if r := info.Main.Replace; r != nil { + fmt.Fprintf(os.Stdout, "\t(replaced by %s %s)\n", r.Path, r.Version) + } for _, m := range info.Deps { fmt.Fprintf(os.Stdout, "using %s %s\n", m.Path, m.Version) + if r := m.Replace; r != nil { + fmt.Fprintf(os.Stdout, "\t(replaced by %s %s)\n", r.Path, r.Version) + } } } diff --git a/libgo/go/cmd/go/testdata/norunexample/example_test.go b/libgo/go/cmd/go/testdata/norunexample/example_test.go deleted file mode 100644 index e158305a6c8..00000000000 --- a/libgo/go/cmd/go/testdata/norunexample/example_test.go +++ /dev/null @@ -1,11 +0,0 @@ -package pkg_test - -import "os" - -func init() { - os.Stdout.Write([]byte("File with non-runnable example was built.\n")) -} - -func Example_test() { - // This test will not be run, it has no "Output:" comment. -} diff --git a/libgo/go/cmd/go/testdata/norunexample/test_test.go b/libgo/go/cmd/go/testdata/norunexample/test_test.go deleted file mode 100644 index d2e919838fb..00000000000 --- a/libgo/go/cmd/go/testdata/norunexample/test_test.go +++ /dev/null @@ -1,10 +0,0 @@ -package pkg - -import ( - "os" - "testing" -) - -func TestBuilt(t *testing.T) { - os.Stdout.Write([]byte("A normal test was executed.\n")) -} diff --git a/libgo/go/cmd/go/testdata/print_goroot.go b/libgo/go/cmd/go/testdata/print_goroot.go deleted file mode 100644 index 91fbf7d8ec3..00000000000 --- a/libgo/go/cmd/go/testdata/print_goroot.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "fmt" - "runtime" -) - -func main() { - fmt.Println(runtime.GOROOT()) -} diff --git a/libgo/go/cmd/go/testdata/rundir/sub/sub.go b/libgo/go/cmd/go/testdata/rundir/sub/sub.go deleted file mode 100644 index 06ab7d0f9a3..00000000000 --- a/libgo/go/cmd/go/testdata/rundir/sub/sub.go +++ /dev/null @@ -1 +0,0 @@ -package main diff --git a/libgo/go/cmd/go/testdata/rundir/x.go b/libgo/go/cmd/go/testdata/rundir/x.go deleted file mode 100644 index 06ab7d0f9a3..00000000000 --- a/libgo/go/cmd/go/testdata/rundir/x.go +++ /dev/null @@ -1 +0,0 @@ -package main diff --git a/libgo/go/cmd/go/testdata/script/README b/libgo/go/cmd/go/testdata/script/README index 7dba6b394c9..76d66517183 100644 --- a/libgo/go/cmd/go/testdata/script/README +++ b/libgo/go/cmd/go/testdata/script/README @@ -29,13 +29,17 @@ Scripts also have access to these other environment variables: GOARCH= GOCACHE= GOEXE= + GOEXPSTRING= GOOS= GOPATH=$WORK/gopath GOPROXY= GOROOT= + GOROOT_FINAL= + TESTGO_GOROOT= HOME=/no-home PATH= TMPDIR=$WORK/tmp + GODEBUG= devnull= goversion= := @@ -65,6 +69,10 @@ The command prefix ! indicates that the command on the rest of the line (typically go or a matching predicate) must fail, not succeed. Only certain commands support this prefix. They are indicated below by [!] in the synopsis. +The command prefix ? indicates that the command on the rest of the line +may or may not succeed, but the test should continue regardless. +Commands that support this prefix are indicated by [?]. + The command prefix [cond] indicates that the command on the rest of the line should only run when the condition is satisfied. The available conditions are: @@ -88,7 +96,7 @@ are satisfied. The commands are: -- [!] cc args... [&] +- [! | ?] cc args... [&] Run the C compiler, the platform specific flags (i.e. `go env GOGCCFLAGS`) will be added automatically before args. @@ -110,7 +118,7 @@ The commands are: Like cmp, but environment variables are substituted in the file contents before the comparison. For example, $GOOS is replaced by the target GOOS. -- [!] cp src... dst +- [! | ?] cp src... dst Copy the listed files to the target file or existing directory. src can include "stdout" or "stderr" to use the standard output or standard error from the most recent exec or go command. @@ -122,7 +130,7 @@ The commands are: The -r flag causes the values to be escaped using regexp.QuoteMeta before being recorded. -- [!] exec program [args...] [&] +- [! | ?] exec program [args...] [&] Run the given executable program with the arguments. It must (or must not) succeed. Note that 'exec' does not terminate the script (unlike in Unix shells). @@ -131,14 +139,16 @@ The commands are: output and standard error of the previous command is cleared, but the output of the background process is buffered — and checking of its exit status is delayed — until the next call to 'wait', 'skip', or 'stop' or the end of the - test. At the end of the test, any remaining background processes are - terminated using os.Interrupt (if supported) or os.Kill. + test. If any background processes remain at the end of the test, they + are terminated using os.Interrupt (if supported) or os.Kill and the test + must not depend upon their exit status. -- [!] exists [-readonly] file... +- [!] exists [-readonly] [-exec] file... Each of the listed files or directories must (or must not) exist. If -readonly is given, the files or directories must be unwritable. + If -exec is given, the files or directories must be executable. -- [!] go args... [&] +- [! | ?] go args... [&] Run the (test copy of the) go command with the given arguments. It must (or must not) succeed. diff --git a/libgo/go/cmd/go/testdata/script/build_gcflags.txt b/libgo/go/cmd/go/testdata/script/build_gcflags.txt index e0accb10d50..b47237410d1 100644 --- a/libgo/go/cmd/go/testdata/script/build_gcflags.txt +++ b/libgo/go/cmd/go/testdata/script/build_gcflags.txt @@ -7,7 +7,8 @@ env GO111MODULE=off [!linux] skip # test only works if c-archive implies -shared [short] skip -go build -x -buildmode=c-archive -gcflags=all=-shared=false ./override.go +env GOCACHE=$WORK/gocache # Looking for compile commands, so need a clean cache. +go build -x -n -buildmode=c-archive -gcflags=all=-shared=false ./override.go stderr '^.*/compile (.* )?-shared (.* )?-shared=false' -- override.go -- diff --git a/libgo/go/cmd/go/testdata/script/build_trimpath.txt b/libgo/go/cmd/go/testdata/script/build_trimpath.txt index cfab80743ea..ad78bcf2b27 100644 --- a/libgo/go/cmd/go/testdata/script/build_trimpath.txt +++ b/libgo/go/cmd/go/testdata/script/build_trimpath.txt @@ -1,5 +1,9 @@ [short] skip +# If GOROOT_FINAL is set, 'go build -trimpath' bakes that into the resulting +# binary instead of GOROOT. Explicitly unset it here. +env GOROOT_FINAL= + # Set up two identical directories that can be used as GOPATH. env GO111MODULE=on mkdir $WORK/a/src/paths $WORK/b/src/paths diff --git a/libgo/go/cmd/go/testdata/script/cmd_import_error.txt b/libgo/go/cmd/go/testdata/script/cmd_import_error.txt index 685c606a413..dea76f4d4bf 100644 --- a/libgo/go/cmd/go/testdata/script/cmd_import_error.txt +++ b/libgo/go/cmd/go/testdata/script/cmd_import_error.txt @@ -5,7 +5,7 @@ env GO111MODULE=on # a clear error in module mode. ! go list cmd/unknown -stderr '^can''t load package: package cmd/unknown is not in GOROOT \('$GOROOT'[/\\]src[/\\]cmd[/\\]unknown\)$' +stderr '^package cmd/unknown is not in GOROOT \('$GOROOT'[/\\]src[/\\]cmd[/\\]unknown\)$' go list -f '{{range .DepsErrors}}{{.Err}}{{end}}' x.go stdout '^package cmd/unknown is not in GOROOT \('$GOROOT'[/\\]src[/\\]cmd[/\\]unknown\)$' diff --git a/libgo/go/cmd/go/testdata/script/gcflags_patterns.txt b/libgo/go/cmd/go/testdata/script/gcflags_patterns.txt index dce8e39715d..5374493a439 100644 --- a/libgo/go/cmd/go/testdata/script/gcflags_patterns.txt +++ b/libgo/go/cmd/go/testdata/script/gcflags_patterns.txt @@ -3,6 +3,8 @@ env GO111MODULE=off [!gc] skip 'using -gcflags and -ldflags' [short] skip +env GOCACHE=$WORK/gocache # Looking for compile commands, so need a clean cache. + # -gcflags=-e applies to named packages, not dependencies go build -n -v -gcflags=-e z1 z2 stderr 'compile.* -e.* -p z1' diff --git a/libgo/go/cmd/go/testdata/script/install_cross_gobin.txt b/libgo/go/cmd/go/testdata/script/install_cross_gobin.txt index 14cf7222620..8d38d7bcb8a 100644 --- a/libgo/go/cmd/go/testdata/script/install_cross_gobin.txt +++ b/libgo/go/cmd/go/testdata/script/install_cross_gobin.txt @@ -1,5 +1,5 @@ env GO111MODULE=off -[!short] skip # rebuilds std for alternate architecture +[short] skip # rebuilds std for alternate architecture [gccgo] skip cd mycmd @@ -17,10 +17,9 @@ env GOBIN=$WORK/bin ! go install mycmd ! exists $GOBIN/linux_$GOARCH -# installing standard command should still work -# (should also be mtime update only if cmd/pack is up-to-date). -! stale cmd/pack -[!short] go install cmd/pack +# The install directory for a cross-compiled standard command should include GOARCH. +go list -f '{{.Target}}' cmd/pack +stdout ${GOROOT}[/\\]pkg[/\\]tool[/\\]${GOOS}_${GOARCH}[/\\]pack$ -- mycmd/x.go -- package main diff --git a/libgo/go/cmd/go/testdata/script/link_syso_issue33139.txt b/libgo/go/cmd/go/testdata/script/link_syso_issue33139.txt index 03169bf5e9f..46b0ef4200e 100644 --- a/libgo/go/cmd/go/testdata/script/link_syso_issue33139.txt +++ b/libgo/go/cmd/go/testdata/script/link_syso_issue33139.txt @@ -12,10 +12,6 @@ # See: https://github.com/golang/go/issues/36739 [linux] [riscv64] skip -# External linking is not supported on darwin/386 (10.14+). -# See: https://github.com/golang/go/issues/31751 -[darwin] [386] skip - cc -c -o syso/objTestImpl.syso syso/src/objTestImpl.c go build -ldflags='-linkmode=external' ./cmd/main.go diff --git a/libgo/go/cmd/go/testdata/script/list_ambiguous_path.txt b/libgo/go/cmd/go/testdata/script/list_ambiguous_path.txt index bdb7ffb077a..82dde453802 100644 --- a/libgo/go/cmd/go/testdata/script/list_ambiguous_path.txt +++ b/libgo/go/cmd/go/testdata/script/list_ambiguous_path.txt @@ -17,10 +17,10 @@ stdout '^command-line-arguments$' # A single typo-ed pattern for a Go file. This should # treat the wrong pattern as if it were a package. ! go list ./foo.go/b.go -stderr 'package ./foo.go/b.go: cannot find package "."' +stderr '^stat .*[/\\]foo\.go[/\\]b\.go: directory not found$' # Multiple patterns for Go files with a typo. This should -# treat the wrong pattern as if it were a non-existint file. +# treat the wrong pattern as if it were a nonexistent file. ! go list ./foo.go/a.go ./foo.go/b.go [plan9] stderr 'stat ./foo.go/b.go: ''./foo.go/b.go'' does not exist' [windows] stderr './foo.go/b.go: The system cannot find the file specified' diff --git a/libgo/go/cmd/go/testdata/script/list_importmap.txt b/libgo/go/cmd/go/testdata/script/list_importmap.txt index 52ee6028f5b..f424b9814c6 100644 --- a/libgo/go/cmd/go/testdata/script/list_importmap.txt +++ b/libgo/go/cmd/go/testdata/script/list_importmap.txt @@ -16,7 +16,7 @@ go list -deps -test -f '{{.ImportPath}} MAP: {{.ImportMap}}{{"\n"}}{{.ImportPath stdout '^flag \[fmt\.test\] MAP: map\[fmt:fmt \[fmt\.test\]\]' stdout '^fmt\.test MAP: map\[(.* )?testing:testing \[fmt\.test\]' ! stdout '^fmt\.test MAP: map\[(.* )?os:' -stdout '^fmt\.test IMPORT: \[fmt \[fmt\.test\] fmt_test \[fmt\.test\] os testing \[fmt\.test\] testing/internal/testdeps \[fmt\.test\]\]' +stdout '^fmt\.test IMPORT: \[fmt \[fmt\.test\] fmt_test \[fmt\.test\] os reflect testing \[fmt\.test\] testing/internal/testdeps \[fmt\.test\]\]' -- a/b/b.go -- diff --git a/libgo/go/cmd/go/testdata/script/list_parse_err.txt b/libgo/go/cmd/go/testdata/script/list_parse_err.txt index 5aacaa88fae..3c5345801a2 100644 --- a/libgo/go/cmd/go/testdata/script/list_parse_err.txt +++ b/libgo/go/cmd/go/testdata/script/list_parse_err.txt @@ -1,17 +1,45 @@ -# 'go list' should report imports, even if some files have parse errors +# 'go list' without -e should fail and print errors on stderr. +! go list ./p +stderr '^p[/\\]b.go:2:2: expected ''package'', found ''EOF''$' +! go list -f '{{range .Imports}}{{.}} {{end}}' ./p +stderr '^p[/\\]b.go:2:2: expected ''package'', found ''EOF''$' +! go list -test ./t +stderr '^can''t load test package: t[/\\]t_test.go:8:1: expected declaration, found ʕ' +! go list -test -f '{{range .Imports}}{{.}} {{end}}' ./t +stderr '^can''t load test package: t[/\\]t_test.go:8:1: expected declaration, found ʕ' + +# 'go list -e' should report imports, even if some files have parse errors # before the import block. -go list -e -f '{{range .Imports}}{{.}} {{end}}' +go list -e -f '{{range .Imports}}{{.}} {{end}}' ./p stdout '^fmt ' +# 'go list' should report the position of the error if there's only one. +go list -e -f '{{.Error.Pos}} => {{.Error.Err}}' ./p +stdout 'b.go:[0-9:]+ => expected ''package'', found ''EOF''' + +# 'go test' should report the position of the error if there's only one. +go list -e -test -f '{{if .Error}}{{.Error.Pos}} => {{.Error.Err}}{{end}}' ./t +stdout 't_test.go:[0-9:]+ => expected declaration, found ʕ' + -- go.mod -- module m go 1.13 --- a.go -- +-- p/a.go -- package a import "fmt" --- b.go -- +-- p/b.go -- // no package statement + +-- t/t_test.go -- +package t + +import "testing" + +func Test(t *testing.T) {} + +// scan error +ʕ◔ϖ◔ʔ diff --git a/libgo/go/cmd/go/testdata/script/list_test_imports.txt b/libgo/go/cmd/go/testdata/script/list_test_imports.txt index b2a6bc45f9e..0342eba8623 100644 --- a/libgo/go/cmd/go/testdata/script/list_test_imports.txt +++ b/libgo/go/cmd/go/testdata/script/list_test_imports.txt @@ -16,6 +16,6 @@ package b_test; import _ "a" -- imports.txt -- a: b b: -b.test: b [b.test], b_test [b.test], os, testing, testing/internal/testdeps +b.test: b [b.test], b_test [b.test], os, reflect, testing, testing/internal/testdeps b [b.test]: b_test [b.test]: a [b.test] diff --git a/libgo/go/cmd/go/testdata/script/list_test_non_go_files.txt b/libgo/go/cmd/go/testdata/script/list_test_non_go_files.txt index 16b98f4a375..6b2b6336a6c 100644 --- a/libgo/go/cmd/go/testdata/script/list_test_non_go_files.txt +++ b/libgo/go/cmd/go/testdata/script/list_test_non_go_files.txt @@ -5,7 +5,7 @@ go list -e -test -json -- c.c x.go stdout '"Err": "named files must be .go files: c.c"' ! go list -test -json -- c.c x.go -stderr 'can''t load package: named files must be .go files: c.c' +stderr '^named files must be \.go files: c\.c$' -- x.go -- package main diff --git a/libgo/go/cmd/go/testdata/script/mod_ambiguous_import.txt b/libgo/go/cmd/go/testdata/script/mod_ambiguous_import.txt index 61e632a29cc..feaf5d273d6 100644 --- a/libgo/go/cmd/go/testdata/script/mod_ambiguous_import.txt +++ b/libgo/go/cmd/go/testdata/script/mod_ambiguous_import.txt @@ -11,12 +11,11 @@ go build ./importy # An import provided by both the main module and the vendor directory # should be flagged as an error only when -mod=vendor is set. -# TODO: This error message is a bit redundant. mkdir vendor/example.com/m/importy cp $WORK/importy/importy.go vendor/example.com/m/importy/importy.go go build example.com/m/importy ! go build -mod=vendor example.com/m/importy -stderr '^can.t load package: package example.com/m/importy: ambiguous import: found package example.com/m/importy in multiple directories:\n\t'$WORK'[/\\]importy\n\t'$WORK'[/\\]vendor[/\\]example.com[/\\]m[/\\]importy$' +stderr '^ambiguous import: found package example.com/m/importy in multiple directories:\n\t'$WORK'[/\\]importy\n\t'$WORK'[/\\]vendor[/\\]example.com[/\\]m[/\\]importy$' -- $WORK/go.mod -- module example.com/m diff --git a/libgo/go/cmd/go/testdata/script/mod_convert_dep.txt b/libgo/go/cmd/go/testdata/script/mod_convert_dep.txt index 267c90eb3ce..ad22aca5be8 100644 --- a/libgo/go/cmd/go/testdata/script/mod_convert_dep.txt +++ b/libgo/go/cmd/go/testdata/script/mod_convert_dep.txt @@ -20,7 +20,6 @@ cd $WORK/gopkgdir/x ! go list . stderr 'cannot find main module' ! stderr 'Gopkg.lock' -! stderr 'go mod init' -- $WORK/test/Gopkg.lock -- -- $WORK/test/x/x.go -- diff --git a/libgo/go/cmd/go/testdata/script/mod_convert_git.txt b/libgo/go/cmd/go/testdata/script/mod_convert_git.txt index ece505a7ba2..6ff1eb51cb0 100644 --- a/libgo/go/cmd/go/testdata/script/mod_convert_git.txt +++ b/libgo/go/cmd/go/testdata/script/mod_convert_git.txt @@ -18,6 +18,23 @@ cd $GOROOT ! go list . ! stderr 'go mod init' +# We should also not suggest creating a go.mod file in $GOROOT if its own +# .git/config has been stripped away and we find one in a parent directory. +# (https://golang.org/issue/34191) +env GOROOT=$WORK/parent/goroot +cd $GOROOT +! go list . +! stderr 'go mod init' + +cd $GOROOT/doc +! go list . +! stderr 'go mod init' + -- $WORK/test/.git/config -- -- $WORK/test/x/x.go -- package x // import "m/x" +-- $WORK/parent/.git/config -- +-- $WORK/parent/goroot/README -- +This directory isn't really a GOROOT, but let's pretend that it is. +-- $WORK/parent/goroot/doc/README -- +This is a subdirectory of our fake GOROOT. diff --git a/libgo/go/cmd/go/testdata/script/mod_dot.txt b/libgo/go/cmd/go/testdata/script/mod_dot.txt index c90074d0a6b..c220e99cedd 100644 --- a/libgo/go/cmd/go/testdata/script/mod_dot.txt +++ b/libgo/go/cmd/go/testdata/script/mod_dot.txt @@ -8,12 +8,12 @@ cd dir stderr 'go get \.: path .* is not a package in module rooted at .*[/\\]dir$' ! go list ! stderr 'cannot find module providing package' -stderr '^can.t load package: package \.: no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir$' +stderr '^no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir$' cd subdir ! go list ! stderr 'cannot find module providing package' -stderr '^can.t load package: package \.: no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]subdir$' +stderr '^no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]subdir$' cd .. # golang.org/issue/30590: if a package is found in the filesystem @@ -22,7 +22,74 @@ cd .. # to find a module providing the package. ! go list ./othermodule ! stderr 'cannot find module providing package' -stderr 'go: directory othermodule is outside main module' +stderr '^main module \(example\.com\) does not contain package example.com/othermodule$' + +# golang.org/issue/27122: 'go build' of a nonexistent directory should produce +# a helpful "no Go files" error message, not a generic "unknown import path". +! go list ./subdir +stderr '^no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]subdir$' + +# golang.org/issue/29280: 'go list -e' for a nonexistent directory should +# report a nonexistent package with an error. +go list -e -json ./subdir +stdout '"Incomplete": true' + +# golang.org/issue/28155: 'go list ./testdata' should not synthesize underscores. +go list ./testdata +stdout '^example.com/testdata' + +# golang.org/issue/32921: vendor directories should only be accepted as directories +# if the directory would actually be used to load the package. +! go list ./vendor/nonexist +stderr '^no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]vendor[/\\]nonexist$' + +! go list ./vendor/pkg +stderr '^without -mod=vendor, directory '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]vendor[/\\]pkg has no package path$' + +! go list -mod=vendor ./vendor/nonexist +stderr '^no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]vendor[/\\]nonexist$' + +! go list -mod=vendor ./vendor/unlisted +stderr '^directory '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]vendor[/\\]unlisted is not a package listed in vendor/modules.txt$' + +go list -mod=vendor ./vendor/pkg +stdout '^pkg$' + +# Packages within GOROOT should resolve as in any other module, +# except that -mod=vendor is implied by default. +[!gccgo] cd $GOROOT/src +[!gccgo] ! go list . +[!gccgo] stderr '^no Go files in '$GOROOT'[/\\]src$' + +[!gccgo] ! go list ./builtin +[!gccgo] stderr '^"builtin" is a pseudo-package, not an importable package$' + +[!gccgo] ! go list ./debug +[!gccgo] ! stderr 'cannot find module providing package' +[!gccgo] stderr '^no Go files in '$GOROOT'[/\\]src[/\\]debug$' + +[!gccgo] ! go list ./golang.org/x/tools/cmd/goimports +[!gccgo] ! stderr 'cannot find module providing package' +[!gccgo] stderr '^stat '$GOROOT'[/\\]src[/\\]golang.org[/\\]x[/\\]tools[/\\]cmd[/\\]goimports: directory not found' + +[!gccgo] go list ./vendor/golang.org/x/net/http2/hpack +[!gccgo] stdout '^golang.org/x/net/http2/hpack$' + +# golang.org/issue/30756: packages in other GOROOTs should not get the special +# prefixless treatment of GOROOT itself. +cd $WORK/othergoroot/src +! go list . +stderr '^no Go files in '$WORK'[/\\]othergoroot[/\\]src$' + +go list ./builtin +stdout '^std/builtin$' # Only the "std" in actual $GOROOT is special, and only its "builtin" is special. + +! go list ./bytes +! stderr 'cannot find module providing package' +stderr '^no Go files in '$WORK'[/\\]othergoroot[/\\]src[/\\]bytes$' + +! go list ./vendor/golang.org/x/net/http2/hpack +stderr '^without -mod=vendor, directory '$WORK'[/\\]othergoroot[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack has no package path$' -- dir/go.mod -- module example.com @@ -34,3 +101,27 @@ module example.com/othermodule go 1.13 -- dir/othermodule/om.go -- package othermodule +-- dir/testdata/td.go -- +package testdata +-- dir/vendor/modules.txt -- +# pkg v0.0.0 +pkg +-- dir/vendor/nonexist/README -- +There are no Go source files here either. +-- dir/vendor/pkg/pkg.go -- +package pkg +-- dir/vendor/unlisted/unlisted.go -- +package unlisted +-- emptyroot/go.mod -- +module example.com/emptyroot +-- emptyroot/pkg/pkg.go -- +package pkg +-- $WORK/othergoroot/src/go.mod -- +module std +go 1.13 +-- $WORK/othergoroot/src/builtin/builtin.go -- +package builtin +-- $WORK/othergoroot/src/bytes/README -- +There are no Go source files in this directory. +-- $WORK/othergoroot/src/vendor/golang.org/x/net/http2/hpack -- +package hpack diff --git a/libgo/go/cmd/go/testdata/script/mod_empty_err.txt b/libgo/go/cmd/go/testdata/script/mod_empty_err.txt index 729f848156d..982e6b2e518 100644 --- a/libgo/go/cmd/go/testdata/script/mod_empty_err.txt +++ b/libgo/go/cmd/go/testdata/script/mod_empty_err.txt @@ -4,16 +4,16 @@ env GO111MODULE=on cd $WORK go list -e -f {{.Error}} . -stdout 'package \.: no Go files in \$WORK' +stdout 'no Go files in \$WORK' go list -e -f {{.Error}} ./empty -stdout 'package \./empty: no Go files in \$WORK[/\\]empty' +stdout 'no Go files in \$WORK[/\\]empty' go list -e -f {{.Error}} ./exclude -stdout 'package \./exclude: build constraints exclude all Go files in \$WORK[/\\]exclude' +stdout 'build constraints exclude all Go files in \$WORK[/\\]exclude' go list -e -f {{.Error}} ./missing -stdout 'package \./missing: cannot find package "." in:\s*\$WORK[/\\]missing' +stdout 'stat '$WORK'[/\\]missing: directory not found' # use 'go build -n' because 'go list' reports no error. ! go build -n ./testonly diff --git a/libgo/go/cmd/go/testdata/script/mod_fs_patterns.txt b/libgo/go/cmd/go/testdata/script/mod_fs_patterns.txt index 4911fbb6138..a20fefd6d39 100644 --- a/libgo/go/cmd/go/testdata/script/mod_fs_patterns.txt +++ b/libgo/go/cmd/go/testdata/script/mod_fs_patterns.txt @@ -33,11 +33,11 @@ stderr 'import lookup disabled' ! go build -mod=readonly ./nonexist ! stderr 'import lookup disabled' -stderr '^can.t load package: package ./nonexist: cannot find package "." in:\n\t'$WORK'[/\\]gopath[/\\]src[/\\]x[/\\]nonexist$' +stderr '^stat '$GOPATH'[/\\]src[/\\]x[/\\]nonexist: directory not found' ! go build -mod=readonly ./go.mod ! stderr 'import lookup disabled' -stderr 'can.t load package: package ./go.mod: cannot find package' +stderr 'main module \(m\) does not contain package m/go.mod' # File system paths and patterns should allow the '@' character. diff --git a/libgo/go/cmd/go/testdata/script/mod_get_commit.txt b/libgo/go/cmd/go/testdata/script/mod_get_commit.txt index a906babbd5f..d108242c70e 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_commit.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_commit.txt @@ -14,6 +14,9 @@ go get -d golang.org/x/text@14c0d48 # dropping -d, we should see a build. [short] skip + +env GOCACHE=$WORK/gocache # Looking for compile commands, so need a clean cache. + go get -x golang.org/x/text/language@14c0d48 stderr 'compile|cp|gccgo .*language\.a$' diff --git a/libgo/go/cmd/go/testdata/script/mod_get_main.txt b/libgo/go/cmd/go/testdata/script/mod_get_main.txt index 403abcd28ba..408a5b51c84 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_main.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_main.txt @@ -1,9 +1,18 @@ env GO111MODULE=on -[short] skip +cp go.mod.orig go.mod + +# relative and absolute paths must be within the main module. +! go get -d .. +stderr '^go get \.\.: path '$WORK'[/\\]gopath is not a package in module rooted at '$WORK'[/\\]gopath[/\\]src$' +! go get -d $WORK +stderr '^go get '$WORK': path '$WORK' is not a package in module rooted at '$WORK'[/\\]gopath[/\\]src$' +! go get -d ../... +stderr '^go get: pattern \.\./\.\.\.: directory prefix \.\. outside available modules$' +! go get -d $WORK/... +stderr '^go get: pattern '$WORK'[/\\]\.\.\.: directory prefix \.\.[/\\]\.\. outside available modules$' # @patch and @latest within the main module refer to the current version. # The main module won't be upgraded, but missing dependencies will be added. -cp go.mod.orig go.mod go get -d rsc.io/x grep 'rsc.io/quote v1.5.2' go.mod go get -d rsc.io/x@upgrade @@ -18,7 +27,7 @@ cp go.mod.orig go.mod stderr '^go get rsc.io/x@latest: can.t request explicit version of path in main module$' # The main module cannot be updated to a specific version. -! go get rsc.io/x@v0.1.0 +! go get -d rsc.io/x@v0.1.0 stderr '^go get rsc.io/x@v0.1.0: can.t request explicit version of path in main module$' ! go get -d rsc.io/x@v0.1.0 stderr '^go get rsc.io/x@v0.1.0: can.t request explicit version of path in main module$' diff --git a/libgo/go/cmd/go/testdata/script/mod_get_tags.txt b/libgo/go/cmd/go/testdata/script/mod_get_tags.txt index 603c76983f7..e9869e3f023 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_tags.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_tags.txt @@ -14,7 +14,8 @@ stdout 'rsc.io/quote v1.5.2' [short] skip # Packages that are only imported in excluded files should not be built. -go get -x . +env GOCACHE=$WORK/gocache # Looking for compile commands, so need a clean cache. +go get -n -x . stderr 'compile.* -p m ' ! stderr 'compile.* -p example.com/version ' ! stderr 'compile.* -p rsc.io/quote ' diff --git a/libgo/go/cmd/go/testdata/script/mod_gonoproxy.txt b/libgo/go/cmd/go/testdata/script/mod_gonoproxy.txt index 2bd94cdee04..a9e0ca40108 100644 --- a/libgo/go/cmd/go/testdata/script/mod_gonoproxy.txt +++ b/libgo/go/cmd/go/testdata/script/mod_gonoproxy.txt @@ -10,7 +10,7 @@ env GOSUMDB=$sumdb' '$proxy/sumdb-wrong ! go get rsc.io/quote stderr 'SECURITY ERROR' -# but GONOSUMDB bypasses sumdb, for rsc.io/quote, rsc.io/sampler, golang.org/x/text +# GONOSUMDB bypasses sumdb, for rsc.io/quote, rsc.io/sampler, golang.org/x/text env GONOSUMDB='*/quote,*/*mple*,golang.org/x' go get rsc.io/quote rm go.sum @@ -18,7 +18,18 @@ env GOPRIVATE='*/quote,*/*mple*,golang.org/x' env GONOPROXY=none # that is, proxy all despite GOPRIVATE go get rsc.io/quote -# and GONOPROXY bypasses proxy +# When GOPROXY is not empty but contains no entries, an error should be reported. +env GOPROXY=',' +! go get golang.org/x/text +stderr '^go get golang.org/x/text: GOPROXY list is not the empty string, but contains no entries$' + +# When GOPROXY=off, fetching modules not matched by GONOPROXY fails. +env GONOPROXY=*/fortune +env GOPROXY=off +! go get golang.org/x/text +stderr '^go get golang.org/x/text: module lookup disabled by GOPROXY=off$' + +# GONOPROXY bypasses proxy [!net] skip [!exec:git] skip env GOPRIVATE=none diff --git a/libgo/go/cmd/go/testdata/script/mod_goroot_errors.txt b/libgo/go/cmd/go/testdata/script/mod_goroot_errors.txt index 2e08ae03aa3..e340f187ff7 100644 --- a/libgo/go/cmd/go/testdata/script/mod_goroot_errors.txt +++ b/libgo/go/cmd/go/testdata/script/mod_goroot_errors.txt @@ -13,12 +13,12 @@ env GO111MODULE=on ! go build -mod=readonly nonexist ! stderr 'import lookup disabled' ! stderr 'missing dot' -stderr '^can''t load package: package nonexist is not in GOROOT \('$GOROOT'[/\\]src[/\\]nonexist\)$' +stderr '^package nonexist is not in GOROOT \('$GOROOT'[/\\]src[/\\]nonexist\)$' ! go build nonexist ! stderr 'import lookup disabled' ! stderr 'missing dot' -stderr '^can''t load package: package nonexist is not in GOROOT \('$GOROOT'[/\\]src[/\\]nonexist\)$' +stderr '^package nonexist is not in GOROOT \('$GOROOT'[/\\]src[/\\]nonexist\)$' # Building a nonexistent std package indirectly should also fail usefully. diff --git a/libgo/go/cmd/go/testdata/script/mod_invalid_version.txt b/libgo/go/cmd/go/testdata/script/mod_invalid_version.txt index 76e0b43a735..7e1bc9ea4f9 100644 --- a/libgo/go/cmd/go/testdata/script/mod_invalid_version.txt +++ b/libgo/go/cmd/go/testdata/script/mod_invalid_version.txt @@ -76,17 +76,17 @@ cp go.mod.orig go.mod go mod edit -require golang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c cd outside ! go list -m golang.org/x/text -stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(2017-09-15T03:28:32Z\)' +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(expected 20170915032832\)' cd .. ! go list -m golang.org/x/text -stderr 'golang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(2017-09-15T03:28:32Z\)' +stderr 'golang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(expected 20170915032832\)' # A 'replace' directive in the main module can replace an invalid timestamp # with a valid one. go mod edit -replace golang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c=golang.org/x/text@14c0d48ead0c cd outside ! go list -m golang.org/x/text -stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(2017-09-15T03:28:32Z\)' +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(expected 20170915032832\)' cd .. go list -m golang.org/x/text stdout 'golang.org/x/text v0.1.1-0.20190915032832-14c0d48ead0c => golang.org/x/text v0.1.1-0.20170915032832-14c0d48ead0c' diff --git a/libgo/go/cmd/go/testdata/script/mod_list_dir.txt b/libgo/go/cmd/go/testdata/script/mod_list_dir.txt index f6994c1e666..6653435a06e 100644 --- a/libgo/go/cmd/go/testdata/script/mod_list_dir.txt +++ b/libgo/go/cmd/go/testdata/script/mod_list_dir.txt @@ -11,11 +11,7 @@ go list -f '{{.ImportPath}}' $GOROOT/src/math stdout ^math$ go list -f '{{.ImportPath}}' . stdout ^x$ -! go list -f '{{.ImportPath}}' $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 -stderr '^can.t load package: package '$WORK'[/\\]gopath[/\\]pkg[/\\]mod[/\\]rsc.io[/\\]quote@v1.5.2: can only use path@version syntax with .go get.' -go list -e -f '{{with .Error}}{{.}}{{end}}' $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 -stdout '^package '$WORK'[/\\]gopath[/\\]pkg[/\\]mod[/\\]rsc.io[/\\]quote@v1.5.2: can only use path@version syntax with .go get.' go mod download rsc.io/quote@v1.5.2 go list -f '{{.ImportPath}}' $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 stdout '^rsc.io/quote$' diff --git a/libgo/go/cmd/go/testdata/script/mod_list_replace_dir.txt b/libgo/go/cmd/go/testdata/script/mod_list_replace_dir.txt index d43bbe7f2bc..cad7fe25280 100644 --- a/libgo/go/cmd/go/testdata/script/mod_list_replace_dir.txt +++ b/libgo/go/cmd/go/testdata/script/mod_list_replace_dir.txt @@ -3,10 +3,10 @@ # Verifies golang.org/issue/29548 env GO111MODULE=on -go mod download +go mod download rsc.io/quote@v1.5.1 rsc.io/quote@v1.5.2 ! go list $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 -stderr 'can only use path@version syntax with .go get.' +stderr '^directory ..[/\\]pkg[/\\]mod[/\\]rsc.io[/\\]quote@v1.5.2 outside available modules$' go list $GOPATH/pkg/mod/rsc.io/quote@v1.5.1 stdout 'rsc.io/quote' diff --git a/libgo/go/cmd/go/testdata/script/mod_list_std.txt b/libgo/go/cmd/go/testdata/script/mod_list_std.txt index 8552aebf42c..76a3b00d1c9 100644 --- a/libgo/go/cmd/go/testdata/script/mod_list_std.txt +++ b/libgo/go/cmd/go/testdata/script/mod_list_std.txt @@ -14,6 +14,16 @@ go list cmd/... stdout ^cmd/compile ! stdout ^cmd/vendor/golang\.org/x/arch/x86/x86asm +# GOROOT/src/... should list the packages in std as if it were a module +# dependency: omitting vendored dependencies and stopping at the 'cmd' module +# boundary. + +go list $GOROOT/src/... +stdout ^bytes$ +! stdout ^builtin$ +! stdout ^cmd/ +! stdout ^vendor/ + # Within the std module, listing ./... should omit the 'std' prefix: # the package paths should be the same via ./... or the 'std' meta-pattern. diff --git a/libgo/go/cmd/go/testdata/script/mod_proxy_list.txt b/libgo/go/cmd/go/testdata/script/mod_proxy_list.txt index a48622814a2..849cf2c4764 100644 --- a/libgo/go/cmd/go/testdata/script/mod_proxy_list.txt +++ b/libgo/go/cmd/go/testdata/script/mod_proxy_list.txt @@ -10,17 +10,25 @@ stderr '404 Not Found' env GOPROXY=$proxy/404,$proxy/410,$proxy go get rsc.io/quote@v1.1.0 -# get should not walk past other 4xx errors. +# get should not walk past other 4xx errors if proxies are separated with ','. env GOPROXY=$proxy/403,$proxy ! go get rsc.io/quote@v1.2.0 stderr 'reading.*/403/rsc.io/.*: 403 Forbidden' -# get should not walk past non-4xx errors. +# get should not walk past non-4xx errors if proxies are separated with ','. env GOPROXY=$proxy/500,$proxy ! go get rsc.io/quote@v1.3.0 stderr 'reading.*/500/rsc.io/.*: 500 Internal Server Error' -# get should return the final 404/410 if that's all we have. +# get should walk past other 4xx errors if proxies are separated with '|'. +env GOPROXY=$proxy/403|https://0.0.0.0|$proxy +go get rsc.io/quote@v1.2.0 + +# get should walk past non-4xx errors if proxies are separated with '|'. +env GOPROXY=$proxy/500|https://0.0.0.0|$proxy +go get rsc.io/quote@v1.3.0 + +# get should return the final error if that's all we have. env GOPROXY=$proxy/404,$proxy/410 ! go get rsc.io/quote@v1.4.0 stderr 'reading.*/410/rsc.io/.*: 410 Gone' diff --git a/libgo/go/cmd/go/testdata/script/mod_readonly.txt b/libgo/go/cmd/go/testdata/script/mod_readonly.txt index 751f6e645e1..ac581264f1f 100644 --- a/libgo/go/cmd/go/testdata/script/mod_readonly.txt +++ b/libgo/go/cmd/go/testdata/script/mod_readonly.txt @@ -6,7 +6,7 @@ env GOFLAGS=-mod=readonly go mod edit -fmt cp go.mod go.mod.empty ! go list all -stderr '^can''t load package: x.go:2:8: cannot find module providing package rsc\.io/quote: import lookup disabled by -mod=readonly' +stderr '^x.go:2:8: cannot find module providing package rsc\.io/quote: import lookup disabled by -mod=readonly' ! stderr '\(\)' # If we don't have a reason for -mod=readonly, don't log an empty one. cmp go.mod go.mod.empty @@ -14,7 +14,7 @@ cmp go.mod go.mod.empty chmod 0400 go.mod env GOFLAGS= ! go list all -stderr '^can''t load package: x.go:2:8: cannot find module providing package rsc\.io/quote: import lookup disabled by -mod=readonly\n\t\(go.mod file is read-only\.\)$' +stderr '^x.go:2:8: cannot find module providing package rsc\.io/quote: import lookup disabled by -mod=readonly\n\t\(go.mod file is read-only\.\)$' chmod 0600 go.mod env GOFLAGS=-mod=readonly diff --git a/libgo/go/cmd/go/testdata/script/mod_replace_import.txt b/libgo/go/cmd/go/testdata/script/mod_replace_import.txt index fd5b04a4987..54b1a124485 100644 --- a/libgo/go/cmd/go/testdata/script/mod_replace_import.txt +++ b/libgo/go/cmd/go/testdata/script/mod_replace_import.txt @@ -27,9 +27,8 @@ stdout 'example.com/v v1.12.0 => ./v12' # module does not contain a package. cd fail ! go list all -stdout 'localhost.fail' -stderr '^can''t load package: m.go:4:2: module w@latest found \(v0.0.0-00010101000000-000000000000, replaced by ../w\), but does not contain package w$' -stderr '^can''t load package: m.go:5:2: nonexist@v0.1.0: replacement directory ../nonexist does not exist$' +stderr '^m.go:4:2: module w@latest found \(v0.0.0-00010101000000-000000000000, replaced by ../w\), but does not contain package w$' +stderr '^m.go:5:2: nonexist@v0.1.0: replacement directory ../nonexist does not exist$' -- go.mod -- module example.com/m diff --git a/libgo/go/cmd/go/testdata/script/mod_retention.txt b/libgo/go/cmd/go/testdata/script/mod_retention.txt index bff4142ad83..1d83e6c07e8 100644 --- a/libgo/go/cmd/go/testdata/script/mod_retention.txt +++ b/libgo/go/cmd/go/testdata/script/mod_retention.txt @@ -64,7 +64,7 @@ cmp go.mod go.mod.tidy # However, that should not remove other redundant requirements. cp go.mod.nogo go.mod go list all -cmp go.mod go.mod.redundant +cmpenv go.mod go.mod.currentgo -- go.mod.tidy -- @@ -133,3 +133,13 @@ require ( rsc.io/sampler v1.3.0 // indirect rsc.io/testonly v1.0.0 // indirect ) +-- go.mod.currentgo -- +module m + +go $goversion + +require ( + rsc.io/quote v1.5.2 + rsc.io/sampler v1.3.0 // indirect + rsc.io/testonly v1.0.0 // indirect +) diff --git a/libgo/go/cmd/go/testdata/script/mod_sumdb_proxy.txt b/libgo/go/cmd/go/testdata/script/mod_sumdb_proxy.txt index 28166913fd5..7bbc3f9e196 100644 --- a/libgo/go/cmd/go/testdata/script/mod_sumdb_proxy.txt +++ b/libgo/go/cmd/go/testdata/script/mod_sumdb_proxy.txt @@ -46,5 +46,22 @@ stderr '503 Service Unavailable' rm $GOPATH/pkg/mod/cache/download/sumdb rm go.sum +# the error from the last attempted proxy should be returned. +cp go.mod.orig go.mod +env GOSUMDB=$sumdb +env GOPROXY=$proxy/sumdb-404,$proxy/sumdb-503 +! go get -d rsc.io/fortune@v1.0.0 +stderr '503 Service Unavailable' +rm $GOPATH/pkg/mod/cache/download/sumdb +rm go.sum + +# if proxies are separated with '|', fallback is allowed on any error. +cp go.mod.orig go.mod +env GOSUMDB=$sumdb +env GOPROXY=$proxy/sumdb-503|https://0.0.0.0|$proxy +go get -d rsc.io/fortune@v1.0.0 +rm $GOPATH/pkg/mod/cache/download/sumdb +rm go.sum + -- go.mod.orig -- module m diff --git a/libgo/go/cmd/go/testdata/script/noncanonical_import.txt b/libgo/go/cmd/go/testdata/script/noncanonical_import.txt index 7fdc0718ef1..018cb01ca66 100644 --- a/libgo/go/cmd/go/testdata/script/noncanonical_import.txt +++ b/libgo/go/cmd/go/testdata/script/noncanonical_import.txt @@ -1,9 +1,7 @@ env GO111MODULE=off ! go build canonical/d -stderr 'package canonical/d' -stderr 'imports canonical/b' -stderr 'imports canonical/a/: non-canonical' +stderr '^canonical[/\\]b[/\\]b.go:3:8: non-canonical import path "canonical/a/": should be "canonical/a"$' -- canonical/a/a.go -- package a diff --git a/libgo/go/cmd/go/testdata/script/script_wait.txt b/libgo/go/cmd/go/testdata/script/script_wait.txt index 3cd4ded9dd1..acaccfe043a 100644 --- a/libgo/go/cmd/go/testdata/script/script_wait.txt +++ b/libgo/go/cmd/go/testdata/script/script_wait.txt @@ -19,6 +19,7 @@ wait stdout 'foo\nbar' # The end of the test should interrupt or kill any remaining background -# programs. -[!exec:sleep] skip -! exec sleep 86400 & +# programs, but that should not cause the test to fail if it does not +# care about the exit status of those programs. +[!exec:sleep] stop +? exec sleep 86400 & diff --git a/libgo/go/cmd/go/testdata/script/test_cache_inputs.txt b/libgo/go/cmd/go/testdata/script/test_cache_inputs.txt index 46faca0f422..57602e91dc1 100644 --- a/libgo/go/cmd/go/testdata/script/test_cache_inputs.txt +++ b/libgo/go/cmd/go/testdata/script/test_cache_inputs.txt @@ -29,6 +29,23 @@ go test testcache -run=TestLookupEnv go test testcache -run=TestLookupEnv stdout '\(cached\)' +# Changes in arguments forwarded to the test should invalidate cached test +# results. +go test testcache -run=TestOSArgs -v hello +! stdout '\(cached\)' +stdout 'hello' +go test testcache -run=TestOSArgs -v goodbye +! stdout '\(cached\)' +stdout 'goodbye' + +# golang.org/issue/36134: that includes the `-timeout` argument. +go test testcache -run=TestOSArgs -timeout=20m -v +! stdout '\(cached\)' +stdout '-test\.timeout[= ]20m' +go test testcache -run=TestOSArgs -timeout=5s -v +! stdout '\(cached\)' +stdout '-test\.timeout[= ]5s' + # If the test stats a file, changes to the file should invalidate the cache. go test testcache -run=FileSize go test testcache -run=FileSize @@ -207,6 +224,10 @@ func TestExternalFile(t *testing.T) { t.Fatal(err) } } + +func TestOSArgs(t *testing.T) { + t.Log(os.Args) +} -- mkold.go -- package main diff --git a/libgo/go/cmd/go/testdata/script/version.txt b/libgo/go/cmd/go/testdata/script/version.txt index 42526247f1e..0123ac6d53f 100644 --- a/libgo/go/cmd/go/testdata/script/version.txt +++ b/libgo/go/cmd/go/testdata/script/version.txt @@ -1,4 +1,16 @@ +# Without arguments, we just print Go's own version. +go version +stdout '^go version' + +# Flags without files, or paths to misisng files, should error. +! go version missing.exe +! go version -m +stderr 'with arguments' +! go version -v +stderr 'with arguments' + env GO111MODULE=on +# Skip the builds below if we are running in short mode. [short] skip # Check that 'go version' and 'go version -m' work on a binary built in module mode. @@ -10,9 +22,7 @@ stdout '^\tpath\trsc.io/fortune' stdout '^\tmod\trsc.io/fortune\tv1.0.0' # Repeat the test with -buildmode=pie. -# TODO(golang.org/issue/27144): don't skip after -buildmode=pie is implemented -# on Windows. -[windows] skip # -buildmode=pie not supported +[!buildmode:pie] stop go build -buildmode=pie -o external.exe rsc.io/fortune go version external.exe stdout '^external.exe: .+' @@ -20,5 +30,16 @@ go version -m external.exe stdout '^\tpath\trsc.io/fortune' stdout '^\tmod\trsc.io/fortune\tv1.0.0' +# Also test PIE with internal linking. +# currently only supported on linux/amd64, linux/arm64 and windows/amd64. +[!linux] [!windows] stop +[!amd64] [!arm64] stop +go build -buildmode=pie -ldflags=-linkmode=internal -o internal.exe rsc.io/fortune +go version internal.exe +stdout '^internal.exe: .+' +go version -m internal.exe +stdout '^\tpath\trsc.io/fortune' +stdout '^\tmod\trsc.io/fortune\tv1.0.0' + -- go.mod -- module m diff --git a/libgo/go/cmd/go/testdata/script/vet_flags.txt b/libgo/go/cmd/go/testdata/script/vet_flags.txt index 2d790c1ac99..b55dada4dc6 100644 --- a/libgo/go/cmd/go/testdata/script/vet_flags.txt +++ b/libgo/go/cmd/go/testdata/script/vet_flags.txt @@ -3,8 +3,8 @@ env GO111MODULE=on # gccgo doesn't support vet on the standard library [gccgo] skip -# Regression test for issue 35837: "go vet - " -# did not apply the requested analyzer. +# Issue 35837: "go vet - " should use the requested +# analyzers, not the default analyzers for 'go test'. go vet -n -unreachable=false encoding/binary stderr '-unreachable=false' ! stderr '-unsafeptr=false' @@ -20,20 +20,54 @@ go vet -n -unsafeptr encoding/binary stderr '-unsafeptr' ! stderr '-unsafeptr=false' +# A flag terminator should be allowed before the package list. +go vet -n -- . + [short] stop + +# Analyzer flags should be included from GOFLAGS, and should override +# the defaults. +go vet . +env GOFLAGS='-tags=buggy' +! go vet . +stderr 'possible formatting directive' + +# Enabling one analyzer in GOFLAGS should disable the rest implicitly... +env GOFLAGS='-tags=buggy -unsafeptr' +go vet . + +# ...but enabling one on the command line should not disable the analyzers +# enabled via GOFLAGS. +env GOFLAGS='-tags=buggy -printf' +! go vet -unsafeptr +stderr 'possible formatting directive' + +# Analyzer flags don't exist unless we're running 'go vet', +# and we shouldn't run the vet tool to discover them otherwise. +# (Maybe someday we'll hard-code the analyzer flags for the default vet +# tool to make this work, but not right now.) +env GOFLAGS='-unsafeptr' +! go list . +stderr 'go: parsing \$GOFLAGS: unknown flag -unsafeptr' +env GOFLAGS= + env GOCACHE=$WORK/gocache -env GOTMPDIR=$WORK/tmp -go env GOTMPDIR -stdout '/tmp' -# "go test" on a user package should by default enable an explicit whitelist of analyzers. +# "go test" on a user package should by default enable an explicit list of analyzers. go test -x -run=none . stderr '[/\\]vet'$GOEXE'["]? .* -errorsas .* ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' -# "go test" on a standard package should by default disable an explicit blacklist. +# An explicitly-empty -vet argument should imply the default analyzers. +go test -x -vet= -run=none . +stderr '[/\\]vet'$GOEXE'["]? .* -errorsas .* ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' + +# "go test" on a standard package should by default disable an explicit list. go test -x -run=none encoding/binary stderr '[/\\]vet'$GOEXE'["]? -unsafeptr=false ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' +go test -x -vet= -run=none encoding/binary +stderr '[/\\]vet'$GOEXE'["]? -unsafeptr=false ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' + # Both should allow users to override via the -vet flag. go test -x -vet=unreachable -run=none . stderr '[/\\]vet'$GOEXE'["]? -unreachable ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' @@ -46,3 +80,13 @@ module example.com/x package x -- x_test.go -- package x +-- x_tagged.go -- +// +build buggy + +package x + +import "fmt" + +func init() { + fmt.Sprint("%s") // oops! +} diff --git a/libgo/go/cmd/go/testdata/shadow/root1/src/foo/foo.go b/libgo/go/cmd/go/testdata/shadow/root1/src/foo/foo.go deleted file mode 100644 index f52652b1ba7..00000000000 --- a/libgo/go/cmd/go/testdata/shadow/root1/src/foo/foo.go +++ /dev/null @@ -1 +0,0 @@ -package foo diff --git a/libgo/go/cmd/go/testdata/shadow/root1/src/math/math.go b/libgo/go/cmd/go/testdata/shadow/root1/src/math/math.go deleted file mode 100644 index c91c24e967c..00000000000 --- a/libgo/go/cmd/go/testdata/shadow/root1/src/math/math.go +++ /dev/null @@ -1 +0,0 @@ -package math diff --git a/libgo/go/cmd/go/testdata/shadow/root2/src/foo/foo.go b/libgo/go/cmd/go/testdata/shadow/root2/src/foo/foo.go deleted file mode 100644 index f52652b1ba7..00000000000 --- a/libgo/go/cmd/go/testdata/shadow/root2/src/foo/foo.go +++ /dev/null @@ -1 +0,0 @@ -package foo diff --git a/libgo/go/cmd/go/testdata/src/cgotest/m.go b/libgo/go/cmd/go/testdata/src/cgotest/m.go deleted file mode 100644 index 4d68307cf0d..00000000000 --- a/libgo/go/cmd/go/testdata/src/cgotest/m.go +++ /dev/null @@ -1,5 +0,0 @@ -package cgotest - -import "C" - -var _ C.int diff --git a/libgo/go/cmd/go/testdata/src/coverasm/p.go b/libgo/go/cmd/go/testdata/src/coverasm/p.go deleted file mode 100644 index ab0c300d723..00000000000 --- a/libgo/go/cmd/go/testdata/src/coverasm/p.go +++ /dev/null @@ -1,7 +0,0 @@ -package p - -func f() - -func g() { - println("g") -} diff --git a/libgo/go/cmd/go/testdata/src/coverasm/p.s b/libgo/go/cmd/go/testdata/src/coverasm/p.s deleted file mode 100644 index 5e728f9946d..00000000000 --- a/libgo/go/cmd/go/testdata/src/coverasm/p.s +++ /dev/null @@ -1,2 +0,0 @@ -// empty asm file, -// so go test doesn't complain about declaration of f in p.go. diff --git a/libgo/go/cmd/go/testdata/src/coverasm/p_test.go b/libgo/go/cmd/go/testdata/src/coverasm/p_test.go deleted file mode 100644 index 3cb3bd5664b..00000000000 --- a/libgo/go/cmd/go/testdata/src/coverasm/p_test.go +++ /dev/null @@ -1,7 +0,0 @@ -package p - -import "testing" - -func Test(t *testing.T) { - g() -} diff --git a/libgo/go/cmd/go/testdata/src/coverbad/p.go b/libgo/go/cmd/go/testdata/src/coverbad/p.go deleted file mode 100644 index 16504a401eb..00000000000 --- a/libgo/go/cmd/go/testdata/src/coverbad/p.go +++ /dev/null @@ -1,5 +0,0 @@ -package p - -func f() { - g() -} diff --git a/libgo/go/cmd/go/testdata/src/coverbad/p1.go b/libgo/go/cmd/go/testdata/src/coverbad/p1.go deleted file mode 100644 index 2d25c8e1908..00000000000 --- a/libgo/go/cmd/go/testdata/src/coverbad/p1.go +++ /dev/null @@ -1,7 +0,0 @@ -package p - -import "C" - -func h() { - j() -} diff --git a/libgo/go/cmd/go/testdata/src/coverbad/p_test.go b/libgo/go/cmd/go/testdata/src/coverbad/p_test.go deleted file mode 100644 index 3a876d6296c..00000000000 --- a/libgo/go/cmd/go/testdata/src/coverbad/p_test.go +++ /dev/null @@ -1,5 +0,0 @@ -package p - -import "testing" - -func Test(t *testing.T) {} diff --git a/libgo/go/cmd/go/testdata/src/coverdep/p.go b/libgo/go/cmd/go/testdata/src/coverdep/p.go deleted file mode 100644 index 6baf6d5f0c7..00000000000 --- a/libgo/go/cmd/go/testdata/src/coverdep/p.go +++ /dev/null @@ -1,6 +0,0 @@ -package p - -import _ "coverdep/p1" - -func F() { -} diff --git a/libgo/go/cmd/go/testdata/src/coverdep/p1/p1.go b/libgo/go/cmd/go/testdata/src/coverdep/p1/p1.go deleted file mode 100644 index 8ae793d55d7..00000000000 --- a/libgo/go/cmd/go/testdata/src/coverdep/p1/p1.go +++ /dev/null @@ -1,3 +0,0 @@ -package p1 - -import _ "errors" diff --git a/libgo/go/cmd/go/testdata/src/coverdep/p_test.go b/libgo/go/cmd/go/testdata/src/coverdep/p_test.go deleted file mode 100644 index 11a14343ea9..00000000000 --- a/libgo/go/cmd/go/testdata/src/coverdep/p_test.go +++ /dev/null @@ -1,7 +0,0 @@ -package p - -import "testing" - -func Test(t *testing.T) { - F() -} diff --git a/libgo/go/cmd/go/testdata/src/coverdep2/p1/p.go b/libgo/go/cmd/go/testdata/src/coverdep2/p1/p.go deleted file mode 100644 index fd315272ea2..00000000000 --- a/libgo/go/cmd/go/testdata/src/coverdep2/p1/p.go +++ /dev/null @@ -1,3 +0,0 @@ -package p1 - -func F() int { return 1 } diff --git a/libgo/go/cmd/go/testdata/src/coverdep2/p1/p_test.go b/libgo/go/cmd/go/testdata/src/coverdep2/p1/p_test.go deleted file mode 100644 index c40256885c1..00000000000 --- a/libgo/go/cmd/go/testdata/src/coverdep2/p1/p_test.go +++ /dev/null @@ -1,10 +0,0 @@ -package p1_test - -import ( - "coverdep2/p2" - "testing" -) - -func Test(t *testing.T) { - p2.F() -} diff --git a/libgo/go/cmd/go/testdata/src/coverdep2/p2/p2.go b/libgo/go/cmd/go/testdata/src/coverdep2/p2/p2.go deleted file mode 100644 index 33561bbb582..00000000000 --- a/libgo/go/cmd/go/testdata/src/coverdep2/p2/p2.go +++ /dev/null @@ -1,7 +0,0 @@ -package p2 - -import "coverdep2/p1" - -func F() { - p1.F() -} diff --git a/libgo/go/cmd/go/testdata/src/coverdot1/p.go b/libgo/go/cmd/go/testdata/src/coverdot1/p.go deleted file mode 100644 index cda364f9292..00000000000 --- a/libgo/go/cmd/go/testdata/src/coverdot1/p.go +++ /dev/null @@ -1,3 +0,0 @@ -package coverdot1 - -func F() {} diff --git a/libgo/go/cmd/go/testdata/src/coverdot2/p.go b/libgo/go/cmd/go/testdata/src/coverdot2/p.go deleted file mode 100644 index 80f79aec838..00000000000 --- a/libgo/go/cmd/go/testdata/src/coverdot2/p.go +++ /dev/null @@ -1,5 +0,0 @@ -package coverdot2 - -import . "coverdot1" - -func G() { F() } diff --git a/libgo/go/cmd/go/testdata/src/coverdot2/p_test.go b/libgo/go/cmd/go/testdata/src/coverdot2/p_test.go deleted file mode 100644 index da66e3e7af2..00000000000 --- a/libgo/go/cmd/go/testdata/src/coverdot2/p_test.go +++ /dev/null @@ -1,7 +0,0 @@ -package coverdot2 - -import "testing" - -func TestG(t *testing.T) { - G() -} diff --git a/libgo/go/cmd/go/testdata/src/empty/pkg/pkg.go b/libgo/go/cmd/go/testdata/src/empty/pkg/pkg.go deleted file mode 100644 index c89cd18d0fe..00000000000 --- a/libgo/go/cmd/go/testdata/src/empty/pkg/pkg.go +++ /dev/null @@ -1 +0,0 @@ -package p diff --git a/libgo/go/cmd/go/testdata/src/empty/pkgtest/pkg.go b/libgo/go/cmd/go/testdata/src/empty/pkgtest/pkg.go deleted file mode 100644 index c89cd18d0fe..00000000000 --- a/libgo/go/cmd/go/testdata/src/empty/pkgtest/pkg.go +++ /dev/null @@ -1 +0,0 @@ -package p diff --git a/libgo/go/cmd/go/testdata/src/empty/pkgtest/test_test.go b/libgo/go/cmd/go/testdata/src/empty/pkgtest/test_test.go deleted file mode 100644 index c89cd18d0fe..00000000000 --- a/libgo/go/cmd/go/testdata/src/empty/pkgtest/test_test.go +++ /dev/null @@ -1 +0,0 @@ -package p diff --git a/libgo/go/cmd/go/testdata/src/empty/pkgtestxtest/pkg.go b/libgo/go/cmd/go/testdata/src/empty/pkgtestxtest/pkg.go deleted file mode 100644 index c89cd18d0fe..00000000000 --- a/libgo/go/cmd/go/testdata/src/empty/pkgtestxtest/pkg.go +++ /dev/null @@ -1 +0,0 @@ -package p diff --git a/libgo/go/cmd/go/testdata/src/empty/pkgtestxtest/test_test.go b/libgo/go/cmd/go/testdata/src/empty/pkgtestxtest/test_test.go deleted file mode 100644 index c89cd18d0fe..00000000000 --- a/libgo/go/cmd/go/testdata/src/empty/pkgtestxtest/test_test.go +++ /dev/null @@ -1 +0,0 @@ -package p diff --git a/libgo/go/cmd/go/testdata/src/empty/pkgtestxtest/xtest_test.go b/libgo/go/cmd/go/testdata/src/empty/pkgtestxtest/xtest_test.go deleted file mode 100644 index 9b64e8e1a26..00000000000 --- a/libgo/go/cmd/go/testdata/src/empty/pkgtestxtest/xtest_test.go +++ /dev/null @@ -1 +0,0 @@ -package p_test diff --git a/libgo/go/cmd/go/testdata/src/empty/pkgxtest/pkg.go b/libgo/go/cmd/go/testdata/src/empty/pkgxtest/pkg.go deleted file mode 100644 index c89cd18d0fe..00000000000 --- a/libgo/go/cmd/go/testdata/src/empty/pkgxtest/pkg.go +++ /dev/null @@ -1 +0,0 @@ -package p diff --git a/libgo/go/cmd/go/testdata/src/empty/pkgxtest/xtest_test.go b/libgo/go/cmd/go/testdata/src/empty/pkgxtest/xtest_test.go deleted file mode 100644 index 9b64e8e1a26..00000000000 --- a/libgo/go/cmd/go/testdata/src/empty/pkgxtest/xtest_test.go +++ /dev/null @@ -1 +0,0 @@ -package p_test diff --git a/libgo/go/cmd/go/testdata/src/empty/test/test_test.go b/libgo/go/cmd/go/testdata/src/empty/test/test_test.go deleted file mode 100644 index c89cd18d0fe..00000000000 --- a/libgo/go/cmd/go/testdata/src/empty/test/test_test.go +++ /dev/null @@ -1 +0,0 @@ -package p diff --git a/libgo/go/cmd/go/testdata/src/empty/testxtest/test_test.go b/libgo/go/cmd/go/testdata/src/empty/testxtest/test_test.go deleted file mode 100644 index c89cd18d0fe..00000000000 --- a/libgo/go/cmd/go/testdata/src/empty/testxtest/test_test.go +++ /dev/null @@ -1 +0,0 @@ -package p diff --git a/libgo/go/cmd/go/testdata/src/empty/testxtest/xtest_test.go b/libgo/go/cmd/go/testdata/src/empty/testxtest/xtest_test.go deleted file mode 100644 index 9b64e8e1a26..00000000000 --- a/libgo/go/cmd/go/testdata/src/empty/testxtest/xtest_test.go +++ /dev/null @@ -1 +0,0 @@ -package p_test diff --git a/libgo/go/cmd/go/testdata/src/empty/xtest/xtest_test.go b/libgo/go/cmd/go/testdata/src/empty/xtest/xtest_test.go deleted file mode 100644 index 9b64e8e1a26..00000000000 --- a/libgo/go/cmd/go/testdata/src/empty/xtest/xtest_test.go +++ /dev/null @@ -1 +0,0 @@ -package p_test diff --git a/libgo/go/cmd/go/testdata/src/exclude/empty/x.txt b/libgo/go/cmd/go/testdata/src/exclude/empty/x.txt deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/libgo/go/cmd/go/testdata/src/exclude/ignore/_x.go b/libgo/go/cmd/go/testdata/src/exclude/ignore/_x.go deleted file mode 100644 index 823aafd0712..00000000000 --- a/libgo/go/cmd/go/testdata/src/exclude/ignore/_x.go +++ /dev/null @@ -1 +0,0 @@ -package x diff --git a/libgo/go/cmd/go/testdata/src/exclude/x.go b/libgo/go/cmd/go/testdata/src/exclude/x.go deleted file mode 100644 index 9affd21e8c1..00000000000 --- a/libgo/go/cmd/go/testdata/src/exclude/x.go +++ /dev/null @@ -1,3 +0,0 @@ -// +build linux,!linux - -package x diff --git a/libgo/go/cmd/go/testdata/src/exclude/x_linux.go b/libgo/go/cmd/go/testdata/src/exclude/x_linux.go deleted file mode 100644 index 41ef6e5d7b1..00000000000 --- a/libgo/go/cmd/go/testdata/src/exclude/x_linux.go +++ /dev/null @@ -1,3 +0,0 @@ -// +build windows - -package x diff --git a/libgo/go/cmd/go/testdata/src/failfast_test.go b/libgo/go/cmd/go/testdata/src/failfast_test.go deleted file mode 100644 index 6e64d73fdf9..00000000000 --- a/libgo/go/cmd/go/testdata/src/failfast_test.go +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package failfast - -import "testing" - -func TestA(t *testing.T) { - // Edge-case testing, mixing unparallel tests too - t.Logf("LOG: %s", t.Name()) -} - -func TestFailingA(t *testing.T) { - t.Errorf("FAIL - %s", t.Name()) -} - -func TestB(t *testing.T) { - // Edge-case testing, mixing unparallel tests too - t.Logf("LOG: %s", t.Name()) -} - -func TestParallelFailingA(t *testing.T) { - t.Parallel() - t.Errorf("FAIL - %s", t.Name()) -} - -func TestParallelFailingB(t *testing.T) { - t.Parallel() - t.Errorf("FAIL - %s", t.Name()) -} - -func TestParallelFailingSubtestsA(t *testing.T) { - t.Parallel() - t.Run("TestFailingSubtestsA1", func(t *testing.T) { - t.Errorf("FAIL - %s", t.Name()) - }) - t.Run("TestFailingSubtestsA2", func(t *testing.T) { - t.Errorf("FAIL - %s", t.Name()) - }) -} - -func TestFailingSubtestsA(t *testing.T) { - t.Run("TestFailingSubtestsA1", func(t *testing.T) { - t.Errorf("FAIL - %s", t.Name()) - }) - t.Run("TestFailingSubtestsA2", func(t *testing.T) { - t.Errorf("FAIL - %s", t.Name()) - }) -} - -func TestFailingB(t *testing.T) { - t.Errorf("FAIL - %s", t.Name()) -} - -func TestFatalC(t *testing.T) { - t.Fatalf("FAIL - %s", t.Name()) -} - -func TestFatalD(t *testing.T) { - t.Fatalf("FAIL - %s", t.Name()) -} diff --git a/libgo/go/cmd/go/testdata/src/hello/hello.go b/libgo/go/cmd/go/testdata/src/hello/hello.go deleted file mode 100644 index 73d83e646f9..00000000000 --- a/libgo/go/cmd/go/testdata/src/hello/hello.go +++ /dev/null @@ -1,5 +0,0 @@ -package main - -func main() { - println("hello, world") -} diff --git a/libgo/go/cmd/go/testdata/src/my.pkg/main/main.go b/libgo/go/cmd/go/testdata/src/my.pkg/main/main.go deleted file mode 100644 index c3e8de1276d..00000000000 --- a/libgo/go/cmd/go/testdata/src/my.pkg/main/main.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import "my.pkg" - -func main() { - println(pkg.Text) -} diff --git a/libgo/go/cmd/go/testdata/src/my.pkg/pkg.go b/libgo/go/cmd/go/testdata/src/my.pkg/pkg.go deleted file mode 100644 index 17702a680bb..00000000000 --- a/libgo/go/cmd/go/testdata/src/my.pkg/pkg.go +++ /dev/null @@ -1,3 +0,0 @@ -package pkg - -var Text = "unset" diff --git a/libgo/go/cmd/go/testdata/src/skipper/skip_test.go b/libgo/go/cmd/go/testdata/src/skipper/skip_test.go deleted file mode 100644 index 58e6dc505b7..00000000000 --- a/libgo/go/cmd/go/testdata/src/skipper/skip_test.go +++ /dev/null @@ -1,7 +0,0 @@ -package skipper - -import "testing" - -func Test(t *testing.T) { - t.Skip("skipping") -} diff --git a/libgo/go/cmd/go/testdata/src/testlist/bench_test.go b/libgo/go/cmd/go/testdata/src/testlist/bench_test.go deleted file mode 100644 index 22f147b6339..00000000000 --- a/libgo/go/cmd/go/testdata/src/testlist/bench_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package testlist - -import ( - "fmt" - "testing" -) - -func BenchmarkSimplefunc(b *testing.B) { - b.StopTimer() - b.StartTimer() - for i := 0; i < b.N; i++ { - _ = fmt.Sprint("Test for bench") - } -} diff --git a/libgo/go/cmd/go/testdata/src/testlist/example_test.go b/libgo/go/cmd/go/testdata/src/testlist/example_test.go deleted file mode 100644 index 0298dfde81e..00000000000 --- a/libgo/go/cmd/go/testdata/src/testlist/example_test.go +++ /dev/null @@ -1,21 +0,0 @@ -package testlist - -import ( - "fmt" -) - -func ExampleSimple() { - fmt.Println("Test with Output.") - - // Output: Test with Output. -} - -func ExampleWithEmptyOutput() { - fmt.Println("") - - // Output: -} - -func ExampleNoOutput() { - _ = fmt.Sprint("Test with no output") -} diff --git a/libgo/go/cmd/go/testdata/src/testlist/test_test.go b/libgo/go/cmd/go/testdata/src/testlist/test_test.go deleted file mode 100644 index bdc09f27c5b..00000000000 --- a/libgo/go/cmd/go/testdata/src/testlist/test_test.go +++ /dev/null @@ -1,10 +0,0 @@ -package testlist - -import ( - "fmt" - "testing" -) - -func TestSimple(t *testing.T) { - _ = fmt.Sprint("Test simple") -} diff --git a/libgo/go/cmd/go/testdata/src/vend/bad.go b/libgo/go/cmd/go/testdata/src/vend/bad.go deleted file mode 100644 index 57cc595220c..00000000000 --- a/libgo/go/cmd/go/testdata/src/vend/bad.go +++ /dev/null @@ -1,3 +0,0 @@ -package vend - -import _ "r" diff --git a/libgo/go/cmd/go/testdata/src/vend/dir1/dir1.go b/libgo/go/cmd/go/testdata/src/vend/dir1/dir1.go deleted file mode 100644 index b719eadc091..00000000000 --- a/libgo/go/cmd/go/testdata/src/vend/dir1/dir1.go +++ /dev/null @@ -1 +0,0 @@ -package dir1 diff --git a/libgo/go/cmd/go/testdata/src/vend/good.go b/libgo/go/cmd/go/testdata/src/vend/good.go deleted file mode 100644 index 952ada3108d..00000000000 --- a/libgo/go/cmd/go/testdata/src/vend/good.go +++ /dev/null @@ -1,3 +0,0 @@ -package vend - -import _ "p" diff --git a/libgo/go/cmd/go/testdata/src/vend/hello/hello.go b/libgo/go/cmd/go/testdata/src/vend/hello/hello.go deleted file mode 100644 index 41dc03e0ce4..00000000000 --- a/libgo/go/cmd/go/testdata/src/vend/hello/hello.go +++ /dev/null @@ -1,10 +0,0 @@ -package main - -import ( - "fmt" - "strings" // really ../vendor/strings -) - -func main() { - fmt.Printf("%s\n", strings.Msg) -} diff --git a/libgo/go/cmd/go/testdata/src/vend/hello/hello_test.go b/libgo/go/cmd/go/testdata/src/vend/hello/hello_test.go deleted file mode 100644 index 7190f599d68..00000000000 --- a/libgo/go/cmd/go/testdata/src/vend/hello/hello_test.go +++ /dev/null @@ -1,12 +0,0 @@ -package main - -import ( - "strings" // really ../vendor/strings - "testing" -) - -func TestMsgInternal(t *testing.T) { - if strings.Msg != "hello, world" { - t.Fatalf("unexpected msg: %v", strings.Msg) - } -} diff --git a/libgo/go/cmd/go/testdata/src/vend/hello/hellox_test.go b/libgo/go/cmd/go/testdata/src/vend/hello/hellox_test.go deleted file mode 100644 index 3f2165bd38a..00000000000 --- a/libgo/go/cmd/go/testdata/src/vend/hello/hellox_test.go +++ /dev/null @@ -1,12 +0,0 @@ -package main_test - -import ( - "strings" // really ../vendor/strings - "testing" -) - -func TestMsgExternal(t *testing.T) { - if strings.Msg != "hello, world" { - t.Fatalf("unexpected msg: %v", strings.Msg) - } -} diff --git a/libgo/go/cmd/go/testdata/src/vend/subdir/bad.go b/libgo/go/cmd/go/testdata/src/vend/subdir/bad.go deleted file mode 100644 index d0ddaacfea5..00000000000 --- a/libgo/go/cmd/go/testdata/src/vend/subdir/bad.go +++ /dev/null @@ -1,3 +0,0 @@ -package subdir - -import _ "r" diff --git a/libgo/go/cmd/go/testdata/src/vend/subdir/good.go b/libgo/go/cmd/go/testdata/src/vend/subdir/good.go deleted file mode 100644 index edd04543a2b..00000000000 --- a/libgo/go/cmd/go/testdata/src/vend/subdir/good.go +++ /dev/null @@ -1,3 +0,0 @@ -package subdir - -import _ "p" diff --git a/libgo/go/cmd/go/testdata/src/vend/vendor/p/p.go b/libgo/go/cmd/go/testdata/src/vend/vendor/p/p.go deleted file mode 100644 index c89cd18d0fe..00000000000 --- a/libgo/go/cmd/go/testdata/src/vend/vendor/p/p.go +++ /dev/null @@ -1 +0,0 @@ -package p diff --git a/libgo/go/cmd/go/testdata/src/vend/vendor/q/q.go b/libgo/go/cmd/go/testdata/src/vend/vendor/q/q.go deleted file mode 100644 index 946e6d99109..00000000000 --- a/libgo/go/cmd/go/testdata/src/vend/vendor/q/q.go +++ /dev/null @@ -1 +0,0 @@ -package q diff --git a/libgo/go/cmd/go/testdata/src/vend/vendor/strings/msg.go b/libgo/go/cmd/go/testdata/src/vend/vendor/strings/msg.go deleted file mode 100644 index 438126ba2be..00000000000 --- a/libgo/go/cmd/go/testdata/src/vend/vendor/strings/msg.go +++ /dev/null @@ -1,3 +0,0 @@ -package strings - -var Msg = "hello, world" diff --git a/libgo/go/cmd/go/testdata/src/vend/vendor/vend/dir1/dir2/dir2.go b/libgo/go/cmd/go/testdata/src/vend/vendor/vend/dir1/dir2/dir2.go deleted file mode 100644 index 6fe35e9e59b..00000000000 --- a/libgo/go/cmd/go/testdata/src/vend/vendor/vend/dir1/dir2/dir2.go +++ /dev/null @@ -1 +0,0 @@ -package dir2 diff --git a/libgo/go/cmd/go/testdata/src/vend/x/invalid/invalid.go b/libgo/go/cmd/go/testdata/src/vend/x/invalid/invalid.go deleted file mode 100644 index e250d5bb31b..00000000000 --- a/libgo/go/cmd/go/testdata/src/vend/x/invalid/invalid.go +++ /dev/null @@ -1,3 +0,0 @@ -package invalid - -import "vend/x/invalid/vendor/foo" diff --git a/libgo/go/cmd/go/testdata/src/vend/x/vendor/p/p.go b/libgo/go/cmd/go/testdata/src/vend/x/vendor/p/p.go deleted file mode 100644 index c89cd18d0fe..00000000000 --- a/libgo/go/cmd/go/testdata/src/vend/x/vendor/p/p.go +++ /dev/null @@ -1 +0,0 @@ -package p diff --git a/libgo/go/cmd/go/testdata/src/vend/x/vendor/p/p/p.go b/libgo/go/cmd/go/testdata/src/vend/x/vendor/p/p/p.go deleted file mode 100644 index e12e12c2f4c..00000000000 --- a/libgo/go/cmd/go/testdata/src/vend/x/vendor/p/p/p.go +++ /dev/null @@ -1,3 +0,0 @@ -package p - -import _ "notfound" diff --git a/libgo/go/cmd/go/testdata/src/vend/x/vendor/r/r.go b/libgo/go/cmd/go/testdata/src/vend/x/vendor/r/r.go deleted file mode 100644 index 838c177a570..00000000000 --- a/libgo/go/cmd/go/testdata/src/vend/x/vendor/r/r.go +++ /dev/null @@ -1 +0,0 @@ -package r diff --git a/libgo/go/cmd/go/testdata/src/vend/x/x.go b/libgo/go/cmd/go/testdata/src/vend/x/x.go deleted file mode 100644 index bdcde575c99..00000000000 --- a/libgo/go/cmd/go/testdata/src/vend/x/x.go +++ /dev/null @@ -1,7 +0,0 @@ -package x - -import _ "p" -import _ "q" -import _ "r" -import _ "vend/dir1" // not vendored -import _ "vend/dir1/dir2" // vendored diff --git a/libgo/go/cmd/go/testdata/src/vetcycle/p.go b/libgo/go/cmd/go/testdata/src/vetcycle/p.go deleted file mode 100644 index 5b058e7806e..00000000000 --- a/libgo/go/cmd/go/testdata/src/vetcycle/p.go +++ /dev/null @@ -1,13 +0,0 @@ -package p - -type ( - _ interface{ m(B1) } - A1 interface{ a(D1) } - B1 interface{ A1 } - C1 interface { - B1 /* ERROR issue #18395 */ - } - D1 interface{ C1 } -) - -var _ A1 = C1 /* ERROR cannot use C1 */ (nil) diff --git a/libgo/go/cmd/go/testdata/src/vetfail/p1/p1.go b/libgo/go/cmd/go/testdata/src/vetfail/p1/p1.go deleted file mode 100644 index eaa9b183331..00000000000 --- a/libgo/go/cmd/go/testdata/src/vetfail/p1/p1.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build !foo-bar - -package p1 - -import "fmt" - -func F() { - fmt.Printf("%d", "hello") // causes vet error -} diff --git a/libgo/go/cmd/go/testdata/src/vetfail/p2/p2.go b/libgo/go/cmd/go/testdata/src/vetfail/p2/p2.go deleted file mode 100644 index 88b1cc23736..00000000000 --- a/libgo/go/cmd/go/testdata/src/vetfail/p2/p2.go +++ /dev/null @@ -1,6 +0,0 @@ -package p2 - -import _ "vetfail/p1" - -func F() { -} diff --git a/libgo/go/cmd/go/testdata/src/vetfail/p2/p2_test.go b/libgo/go/cmd/go/testdata/src/vetfail/p2/p2_test.go deleted file mode 100644 index fde0d1a73f3..00000000000 --- a/libgo/go/cmd/go/testdata/src/vetfail/p2/p2_test.go +++ /dev/null @@ -1,7 +0,0 @@ -package p2 - -import "testing" - -func TestF(t *testing.T) { - F() -} diff --git a/libgo/go/cmd/go/testdata/src/vetpkg/a_test.go b/libgo/go/cmd/go/testdata/src/vetpkg/a_test.go deleted file mode 100644 index 9b64e8e1a26..00000000000 --- a/libgo/go/cmd/go/testdata/src/vetpkg/a_test.go +++ /dev/null @@ -1 +0,0 @@ -package p_test diff --git a/libgo/go/cmd/go/testdata/src/vetpkg/b.go b/libgo/go/cmd/go/testdata/src/vetpkg/b.go deleted file mode 100644 index 99e18f63dc6..00000000000 --- a/libgo/go/cmd/go/testdata/src/vetpkg/b.go +++ /dev/null @@ -1,7 +0,0 @@ -package p - -import "fmt" - -func f() { - fmt.Printf("%d") -} diff --git a/libgo/go/cmd/go/testdata/src/vetpkg/c.go b/libgo/go/cmd/go/testdata/src/vetpkg/c.go deleted file mode 100644 index ef5648f0590..00000000000 --- a/libgo/go/cmd/go/testdata/src/vetpkg/c.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build tagtest - -package p - -import "fmt" - -func g() { - fmt.Printf("%d", 3, 4) -} diff --git a/libgo/go/cmd/go/testdata/src/xtestonly/f.go b/libgo/go/cmd/go/testdata/src/xtestonly/f.go deleted file mode 100644 index dac039e1ad0..00000000000 --- a/libgo/go/cmd/go/testdata/src/xtestonly/f.go +++ /dev/null @@ -1,3 +0,0 @@ -package xtestonly - -func F() int { return 42 } diff --git a/libgo/go/cmd/go/testdata/src/xtestonly/f_test.go b/libgo/go/cmd/go/testdata/src/xtestonly/f_test.go deleted file mode 100644 index 01f6e83730c..00000000000 --- a/libgo/go/cmd/go/testdata/src/xtestonly/f_test.go +++ /dev/null @@ -1,12 +0,0 @@ -package xtestonly_test - -import ( - "testing" - "xtestonly" -) - -func TestF(t *testing.T) { - if x := xtestonly.F(); x != 42 { - t.Errorf("f.F() = %d, want 42", x) - } -} diff --git a/libgo/go/cmd/go/testdata/standalone_benchmark_test.go b/libgo/go/cmd/go/testdata/standalone_benchmark_test.go deleted file mode 100644 index 4850f98d80c..00000000000 --- a/libgo/go/cmd/go/testdata/standalone_benchmark_test.go +++ /dev/null @@ -1,6 +0,0 @@ -package standalone_benchmark - -import "testing" - -func Benchmark(b *testing.B) { -} diff --git a/libgo/go/cmd/go/testdata/standalone_fail_sub_test.go b/libgo/go/cmd/go/testdata/standalone_fail_sub_test.go deleted file mode 100644 index ac483f9e0c4..00000000000 --- a/libgo/go/cmd/go/testdata/standalone_fail_sub_test.go +++ /dev/null @@ -1,8 +0,0 @@ -package standalone_fail_sub_test - -import "testing" - -func TestThatFails(t *testing.T) { - t.Run("Sub", func(t *testing.T) {}) - t.Fail() -} diff --git a/libgo/go/cmd/go/testdata/standalone_main_normal_test.go b/libgo/go/cmd/go/testdata/standalone_main_normal_test.go deleted file mode 100644 index 018ce75b2e3..00000000000 --- a/libgo/go/cmd/go/testdata/standalone_main_normal_test.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package standalone_main_normal_test - -import "testing" - -func TestMain(t *testing.T) { -} diff --git a/libgo/go/cmd/go/testdata/standalone_main_wrong_test.go b/libgo/go/cmd/go/testdata/standalone_main_wrong_test.go deleted file mode 100644 index 59998873f94..00000000000 --- a/libgo/go/cmd/go/testdata/standalone_main_wrong_test.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package standalone_main_wrong_test - -import "testing" - -func TestMain(m *testing.Main) { -} diff --git a/libgo/go/cmd/go/testdata/standalone_parallel_sub_test.go b/libgo/go/cmd/go/testdata/standalone_parallel_sub_test.go deleted file mode 100644 index d326de0a5ac..00000000000 --- a/libgo/go/cmd/go/testdata/standalone_parallel_sub_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package standalone_parallel_sub_test - -import "testing" - -func Test(t *testing.T) { - ch := make(chan bool, 1) - t.Run("Sub", func(t *testing.T) { - t.Parallel() - <-ch - t.Run("Nested", func(t *testing.T) {}) - }) - // Ensures that Sub will finish after its t.Run call already returned. - ch <- true -} diff --git a/libgo/go/cmd/go/testdata/standalone_sub_test.go b/libgo/go/cmd/go/testdata/standalone_sub_test.go deleted file mode 100644 index f6c31db9c81..00000000000 --- a/libgo/go/cmd/go/testdata/standalone_sub_test.go +++ /dev/null @@ -1,7 +0,0 @@ -package standalone_sub_test - -import "testing" - -func Test(t *testing.T) { - t.Run("Sub", func(t *testing.T) {}) -} diff --git a/libgo/go/cmd/go/testdata/standalone_test.go b/libgo/go/cmd/go/testdata/standalone_test.go deleted file mode 100644 index 59cf918b9bc..00000000000 --- a/libgo/go/cmd/go/testdata/standalone_test.go +++ /dev/null @@ -1,6 +0,0 @@ -package standalone_test - -import "testing" - -func Test(t *testing.T) { -} diff --git a/libgo/go/cmd/go/testdata/standalone_testmain_flag_test.go b/libgo/go/cmd/go/testdata/standalone_testmain_flag_test.go deleted file mode 100644 index a59555bb61d..00000000000 --- a/libgo/go/cmd/go/testdata/standalone_testmain_flag_test.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package standalone_testmain_flag_test - -import ( - "flag" - "fmt" - "os" - "testing" -) - -func TestMain(m *testing.M) { - // A TestMain should be able to access testing flags if it calls - // flag.Parse without needing to use testing.Init. - flag.Parse() - found := false - flag.VisitAll(func(f *flag.Flag) { - if f.Name == "test.count" { - found = true - } - }) - if !found { - fmt.Println("testing flags not registered") - os.Exit(1) - } - os.Exit(m.Run()) -} diff --git a/libgo/go/cmd/go/testdata/testcover/pkg1/a.go b/libgo/go/cmd/go/testdata/testcover/pkg1/a.go deleted file mode 100644 index e2916119d4f..00000000000 --- a/libgo/go/cmd/go/testdata/testcover/pkg1/a.go +++ /dev/null @@ -1,7 +0,0 @@ -package pkg1 - -import "fmt" - -func F() { - fmt.Println("pkg1") -} diff --git a/libgo/go/cmd/go/testdata/testcover/pkg2/a.go b/libgo/go/cmd/go/testdata/testcover/pkg2/a.go deleted file mode 100644 index 7bd9bd44ee9..00000000000 --- a/libgo/go/cmd/go/testdata/testcover/pkg2/a.go +++ /dev/null @@ -1,7 +0,0 @@ -package pkg2 - -import "fmt" - -func F() { - fmt.Println("pkg2") -} diff --git a/libgo/go/cmd/go/testdata/testcover/pkg2/a_test.go b/libgo/go/cmd/go/testdata/testcover/pkg2/a_test.go deleted file mode 100644 index 4f791ad6ab0..00000000000 --- a/libgo/go/cmd/go/testdata/testcover/pkg2/a_test.go +++ /dev/null @@ -1 +0,0 @@ -package pkg2 diff --git a/libgo/go/cmd/go/testdata/testcover/pkg3/a.go b/libgo/go/cmd/go/testdata/testcover/pkg3/a.go deleted file mode 100644 index bf86ed8dc0e..00000000000 --- a/libgo/go/cmd/go/testdata/testcover/pkg3/a.go +++ /dev/null @@ -1,7 +0,0 @@ -package pkg3 - -import "fmt" - -func F() { - fmt.Println("pkg3") -} diff --git a/libgo/go/cmd/go/testdata/testcover/pkg3/a_test.go b/libgo/go/cmd/go/testdata/testcover/pkg3/a_test.go deleted file mode 100644 index 39c2c5a6fc5..00000000000 --- a/libgo/go/cmd/go/testdata/testcover/pkg3/a_test.go +++ /dev/null @@ -1,7 +0,0 @@ -package pkg3 - -import "testing" - -func TestF(t *testing.T) { - F() -} diff --git a/libgo/go/cmd/go/testdata/testcover/pkg4/a.go b/libgo/go/cmd/go/testdata/testcover/pkg4/a.go deleted file mode 100644 index cf09e6f1b0e..00000000000 --- a/libgo/go/cmd/go/testdata/testcover/pkg4/a.go +++ /dev/null @@ -1,5 +0,0 @@ -package pkg4 - -type T struct { - X bool -} diff --git a/libgo/go/cmd/go/testdata/testcover/pkg4/a_test.go b/libgo/go/cmd/go/testdata/testcover/pkg4/a_test.go deleted file mode 100644 index 12b8685294d..00000000000 --- a/libgo/go/cmd/go/testdata/testcover/pkg4/a_test.go +++ /dev/null @@ -1,9 +0,0 @@ -package pkg4 - -import ( - "testing" -) - -func TestT(t *testing.T) { - _ = T{} -} diff --git a/libgo/go/cmd/go/testdata/testimport/p.go b/libgo/go/cmd/go/testdata/testimport/p.go deleted file mode 100644 index f94d2cd0e66..00000000000 --- a/libgo/go/cmd/go/testdata/testimport/p.go +++ /dev/null @@ -1,3 +0,0 @@ -package p - -func F() int { return 1 } diff --git a/libgo/go/cmd/go/testdata/testimport/p1/p1.go b/libgo/go/cmd/go/testdata/testimport/p1/p1.go deleted file mode 100644 index fd315272ea2..00000000000 --- a/libgo/go/cmd/go/testdata/testimport/p1/p1.go +++ /dev/null @@ -1,3 +0,0 @@ -package p1 - -func F() int { return 1 } diff --git a/libgo/go/cmd/go/testdata/testimport/p2/p2.go b/libgo/go/cmd/go/testdata/testimport/p2/p2.go deleted file mode 100644 index d4888865ddb..00000000000 --- a/libgo/go/cmd/go/testdata/testimport/p2/p2.go +++ /dev/null @@ -1,3 +0,0 @@ -package p2 - -func F() int { return 1 } diff --git a/libgo/go/cmd/go/testdata/testimport/p_test.go b/libgo/go/cmd/go/testdata/testimport/p_test.go deleted file mode 100644 index a3fb4a9e278..00000000000 --- a/libgo/go/cmd/go/testdata/testimport/p_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package p - -import ( - "./p1" - - "testing" -) - -func TestF(t *testing.T) { - if F() != p1.F() { - t.Fatal(F()) - } -} diff --git a/libgo/go/cmd/go/testdata/testimport/x_test.go b/libgo/go/cmd/go/testdata/testimport/x_test.go deleted file mode 100644 index b253e3fd2dd..00000000000 --- a/libgo/go/cmd/go/testdata/testimport/x_test.go +++ /dev/null @@ -1,15 +0,0 @@ -package p_test - -import ( - . "../testimport" - - "./p2" - - "testing" -) - -func TestF1(t *testing.T) { - if F() != p2.F() { - t.Fatal(F()) - } -} diff --git a/libgo/go/cmd/go/testdata/testinternal/p.go b/libgo/go/cmd/go/testdata/testinternal/p.go deleted file mode 100644 index e3558a53b24..00000000000 --- a/libgo/go/cmd/go/testdata/testinternal/p.go +++ /dev/null @@ -1,3 +0,0 @@ -package p - -import _ "net/http/internal" diff --git a/libgo/go/cmd/go/testdata/testinternal2/p.go b/libgo/go/cmd/go/testdata/testinternal2/p.go deleted file mode 100644 index c594f5c5e9e..00000000000 --- a/libgo/go/cmd/go/testdata/testinternal2/p.go +++ /dev/null @@ -1,3 +0,0 @@ -package p - -import _ "./x/y/z/internal/w" diff --git a/libgo/go/cmd/go/testdata/testinternal2/x/y/z/internal/w/w.go b/libgo/go/cmd/go/testdata/testinternal2/x/y/z/internal/w/w.go deleted file mode 100644 index a796c0b5f4b..00000000000 --- a/libgo/go/cmd/go/testdata/testinternal2/x/y/z/internal/w/w.go +++ /dev/null @@ -1 +0,0 @@ -package w diff --git a/libgo/go/cmd/go/testdata/testinternal3/t.go b/libgo/go/cmd/go/testdata/testinternal3/t.go deleted file mode 100644 index 8576a4b4d76..00000000000 --- a/libgo/go/cmd/go/testdata/testinternal3/t.go +++ /dev/null @@ -1,3 +0,0 @@ -package t - -import _ "internal/does-not-exist" diff --git a/libgo/go/cmd/go/testdata/testinternal4/src/p/p.go b/libgo/go/cmd/go/testdata/testinternal4/src/p/p.go deleted file mode 100644 index 6bdee27be2f..00000000000 --- a/libgo/go/cmd/go/testdata/testinternal4/src/p/p.go +++ /dev/null @@ -1,6 +0,0 @@ -package p - -import ( - _ "q/internal/x" - _ "q/j" -) diff --git a/libgo/go/cmd/go/testdata/testinternal4/src/q/internal/x/x.go b/libgo/go/cmd/go/testdata/testinternal4/src/q/internal/x/x.go deleted file mode 100644 index 823aafd0712..00000000000 --- a/libgo/go/cmd/go/testdata/testinternal4/src/q/internal/x/x.go +++ /dev/null @@ -1 +0,0 @@ -package x diff --git a/libgo/go/cmd/go/testdata/testinternal4/src/q/j/j.go b/libgo/go/cmd/go/testdata/testinternal4/src/q/j/j.go deleted file mode 100644 index 9f075438940..00000000000 --- a/libgo/go/cmd/go/testdata/testinternal4/src/q/j/j.go +++ /dev/null @@ -1,3 +0,0 @@ -package j - -import _ "q/internal/x" diff --git a/libgo/go/cmd/go/testdata/testonly/p_test.go b/libgo/go/cmd/go/testdata/testonly/p_test.go deleted file mode 100644 index c89cd18d0fe..00000000000 --- a/libgo/go/cmd/go/testdata/testonly/p_test.go +++ /dev/null @@ -1 +0,0 @@ -package p diff --git a/libgo/go/cmd/go/testdata/testonly2/t.go b/libgo/go/cmd/go/testdata/testonly2/t.go deleted file mode 100644 index 82267d32e41..00000000000 --- a/libgo/go/cmd/go/testdata/testonly2/t.go +++ /dev/null @@ -1,6 +0,0 @@ -// This package is not a test-only package, -// but it still matches the pattern ./testdata/testonly... when in cmd/go. - -package main - -func main() {} diff --git a/libgo/go/cmd/go/testdata/testvendor/src/p/p.go b/libgo/go/cmd/go/testdata/testvendor/src/p/p.go deleted file mode 100644 index e740715186e..00000000000 --- a/libgo/go/cmd/go/testdata/testvendor/src/p/p.go +++ /dev/null @@ -1,6 +0,0 @@ -package p - -import ( - _ "q/y" - _ "q/z" -) diff --git a/libgo/go/cmd/go/testdata/testvendor/src/q/vendor/x/x.go b/libgo/go/cmd/go/testdata/testvendor/src/q/vendor/x/x.go deleted file mode 100644 index 823aafd0712..00000000000 --- a/libgo/go/cmd/go/testdata/testvendor/src/q/vendor/x/x.go +++ /dev/null @@ -1 +0,0 @@ -package x diff --git a/libgo/go/cmd/go/testdata/testvendor/src/q/y/y.go b/libgo/go/cmd/go/testdata/testvendor/src/q/y/y.go deleted file mode 100644 index 4f842237675..00000000000 --- a/libgo/go/cmd/go/testdata/testvendor/src/q/y/y.go +++ /dev/null @@ -1,3 +0,0 @@ -package y - -import _ "x" diff --git a/libgo/go/cmd/go/testdata/testvendor/src/q/z/z.go b/libgo/go/cmd/go/testdata/testvendor/src/q/z/z.go deleted file mode 100644 index a8d4924936a..00000000000 --- a/libgo/go/cmd/go/testdata/testvendor/src/q/z/z.go +++ /dev/null @@ -1,3 +0,0 @@ -package z - -import _ "q/vendor/x" diff --git a/libgo/go/cmd/go/testdata/testvendor2/src/p/p.go b/libgo/go/cmd/go/testdata/testvendor2/src/p/p.go deleted file mode 100644 index 220b2b2a071..00000000000 --- a/libgo/go/cmd/go/testdata/testvendor2/src/p/p.go +++ /dev/null @@ -1,3 +0,0 @@ -package p - -import "x" diff --git a/libgo/go/cmd/go/testdata/testvendor2/vendor/x/x.go b/libgo/go/cmd/go/testdata/testvendor2/vendor/x/x.go deleted file mode 100644 index 823aafd0712..00000000000 --- a/libgo/go/cmd/go/testdata/testvendor2/vendor/x/x.go +++ /dev/null @@ -1 +0,0 @@ -package x diff --git a/libgo/go/cmd/go/testdata/timeoutbench_test.go b/libgo/go/cmd/go/testdata/timeoutbench_test.go deleted file mode 100644 index 57a88882996..00000000000 --- a/libgo/go/cmd/go/testdata/timeoutbench_test.go +++ /dev/null @@ -1,10 +0,0 @@ -package timeoutbench_test - -import ( - "testing" - "time" -) - -func BenchmarkSleep1s(b *testing.B) { - time.Sleep(1 * time.Second) -} diff --git a/libgo/go/cmd/go/vendor_test.go b/libgo/go/cmd/go/vendor_test.go deleted file mode 100644 index 8b67de06ca6..00000000000 --- a/libgo/go/cmd/go/vendor_test.go +++ /dev/null @@ -1,412 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Tests for vendoring semantics. - -package main_test - -import ( - "bytes" - "fmt" - "internal/testenv" - "os" - "path/filepath" - "regexp" - "strings" - "testing" -) - -func TestVendorImports(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.run("list", "-f", "{{.ImportPath}} {{.Imports}}", "vend/...", "vend/vendor/...", "vend/x/vendor/...") - want := ` - vend [vend/vendor/p r] - vend/dir1 [] - vend/hello [fmt vend/vendor/strings] - vend/subdir [vend/vendor/p r] - vend/x [vend/x/vendor/p vend/vendor/q vend/x/vendor/r vend/dir1 vend/vendor/vend/dir1/dir2] - vend/x/invalid [vend/x/invalid/vendor/foo] - vend/vendor/p [] - vend/vendor/q [] - vend/vendor/strings [] - vend/vendor/vend/dir1/dir2 [] - vend/x/vendor/p [] - vend/x/vendor/p/p [notfound] - vend/x/vendor/r [] - ` - want = strings.ReplaceAll(want+"\t", "\n\t\t", "\n") - want = strings.TrimPrefix(want, "\n") - - have := tg.stdout.String() - - if have != want { - t.Errorf("incorrect go list output:\n%s", diffSortedOutputs(have, want)) - } -} - -func TestVendorBuild(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.run("build", "vend/x") -} - -func TestVendorRun(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.cd(filepath.Join(tg.pwd(), "testdata/src/vend/hello")) - tg.run("run", "hello.go") - tg.grepStdout("hello, world", "missing hello world output") -} - -func TestVendorGOPATH(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - changeVolume := func(s string, f func(s string) string) string { - vol := filepath.VolumeName(s) - return f(vol) + s[len(vol):] - } - gopath := changeVolume(filepath.Join(tg.pwd(), "testdata"), strings.ToLower) - tg.setenv("GOPATH", gopath) - cd := changeVolume(filepath.Join(tg.pwd(), "testdata/src/vend/hello"), strings.ToUpper) - tg.cd(cd) - tg.run("run", "hello.go") - tg.grepStdout("hello, world", "missing hello world output") -} - -func TestVendorTest(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.cd(filepath.Join(tg.pwd(), "testdata/src/vend/hello")) - tg.run("test", "-v") - tg.grepStdout("TestMsgInternal", "missing use in internal test") - tg.grepStdout("TestMsgExternal", "missing use in external test") -} - -func TestVendorInvalid(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - - tg.runFail("build", "vend/x/invalid") - tg.grepStderr("must be imported as foo", "missing vendor import error") -} - -func TestVendorImportError(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - - tg.runFail("build", "vend/x/vendor/p/p") - - re := regexp.MustCompile(`cannot find package "notfound" in any of: - .*[\\/]testdata[\\/]src[\\/]vend[\\/]x[\\/]vendor[\\/]notfound \(vendor tree\) - .*[\\/]testdata[\\/]src[\\/]vend[\\/]vendor[\\/]notfound - .*[\\/]src[\\/]notfound \(from \$GOROOT\) - .*[\\/]testdata[\\/]src[\\/]notfound \(from \$GOPATH\)`) - - if !re.MatchString(tg.stderr.String()) { - t.Errorf("did not find expected search list in error text") - } -} - -// diffSortedOutput prepares a diff of the already sorted outputs haveText and wantText. -// The diff shows common lines prefixed by a tab, lines present only in haveText -// prefixed by "unexpected: ", and lines present only in wantText prefixed by "missing: ". -func diffSortedOutputs(haveText, wantText string) string { - var diff bytes.Buffer - have := splitLines(haveText) - want := splitLines(wantText) - for len(have) > 0 || len(want) > 0 { - if len(want) == 0 || len(have) > 0 && have[0] < want[0] { - fmt.Fprintf(&diff, "unexpected: %s\n", have[0]) - have = have[1:] - continue - } - if len(have) == 0 || len(want) > 0 && want[0] < have[0] { - fmt.Fprintf(&diff, "missing: %s\n", want[0]) - want = want[1:] - continue - } - fmt.Fprintf(&diff, "\t%s\n", want[0]) - want = want[1:] - have = have[1:] - } - return diff.String() -} - -func splitLines(s string) []string { - x := strings.Split(s, "\n") - if x[len(x)-1] == "" { - x = x[:len(x)-1] - } - return x -} - -func TestVendorGet(t *testing.T) { - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - tg.tempFile("src/v/m.go", ` - package main - import ("fmt"; "vendor.org/p") - func main() { - fmt.Println(p.C) - }`) - tg.tempFile("src/v/m_test.go", ` - package main - import ("fmt"; "testing"; "vendor.org/p") - func TestNothing(t *testing.T) { - fmt.Println(p.C) - }`) - tg.tempFile("src/v/vendor/vendor.org/p/p.go", ` - package p - const C = 1`) - tg.setenv("GOPATH", tg.path(".")) - tg.cd(tg.path("src/v")) - tg.run("run", "m.go") - tg.run("test") - tg.run("list", "-f", "{{.Imports}}") - tg.grepStdout("v/vendor/vendor.org/p", "import not in vendor directory") - tg.run("list", "-f", "{{.TestImports}}") - tg.grepStdout("v/vendor/vendor.org/p", "test import not in vendor directory") - tg.run("get", "-d") - tg.run("get", "-t", "-d") -} - -func TestVendorGetUpdate(t *testing.T) { - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") - - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path(".")) - tg.run("get", "github.com/rsc/go-get-issue-11864") - tg.run("get", "-u", "github.com/rsc/go-get-issue-11864") -} - -func TestVendorGetU(t *testing.T) { - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") - - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path(".")) - tg.run("get", "-u", "github.com/rsc/go-get-issue-11864") -} - -func TestVendorGetTU(t *testing.T) { - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") - - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path(".")) - tg.run("get", "-t", "-u", "github.com/rsc/go-get-issue-11864/...") -} - -func TestVendorGetBadVendor(t *testing.T) { - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") - - for _, suffix := range []string{"bad/imp", "bad/imp2", "bad/imp3", "..."} { - t.Run(suffix, func(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path(".")) - tg.runFail("get", "-t", "-u", "github.com/rsc/go-get-issue-18219/"+suffix) - tg.grepStderr("must be imported as", "did not find error about vendor import") - tg.mustNotExist(tg.path("src/github.com/rsc/vendor")) - }) - } -} - -func TestGetSubmodules(t *testing.T) { - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") - - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path(".")) - tg.run("get", "-d", "github.com/rsc/go-get-issue-12612") - tg.run("get", "-u", "-d", "github.com/rsc/go-get-issue-12612") - tg.mustExist(tg.path("src/github.com/rsc/go-get-issue-12612/vendor/golang.org/x/crypto/.git")) -} - -func TestVendorCache(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/testvendor")) - tg.runFail("build", "p") - tg.grepStderr("must be imported as x", "did not fail to build p") -} - -func TestVendorTest2(t *testing.T) { - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") - - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path(".")) - tg.run("get", "github.com/rsc/go-get-issue-11864") - - // build -i should work - tg.run("build", "-i", "github.com/rsc/go-get-issue-11864") - tg.run("build", "-i", "github.com/rsc/go-get-issue-11864/t") - - // test -i should work like build -i (golang.org/issue/11988) - tg.run("test", "-i", "github.com/rsc/go-get-issue-11864") - tg.run("test", "-i", "github.com/rsc/go-get-issue-11864/t") - - // test should work too - tg.run("test", "github.com/rsc/go-get-issue-11864") - tg.run("test", "github.com/rsc/go-get-issue-11864/t") - - // external tests should observe internal test exports (golang.org/issue/11977) - tg.run("test", "github.com/rsc/go-get-issue-11864/vendor/vendor.org/tx2") -} - -func TestVendorTest3(t *testing.T) { - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") - - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path(".")) - tg.run("get", "github.com/clsung/go-vendor-issue-14613") - - tg.run("build", "-o", tg.path("a.out"), "-i", "github.com/clsung/go-vendor-issue-14613") - - // test folder should work - tg.run("test", "-i", "github.com/clsung/go-vendor-issue-14613") - tg.run("test", "github.com/clsung/go-vendor-issue-14613") - - // test with specified _test.go should work too - tg.cd(filepath.Join(tg.path("."), "src")) - tg.run("test", "-i", "github.com/clsung/go-vendor-issue-14613/vendor_test.go") - tg.run("test", "github.com/clsung/go-vendor-issue-14613/vendor_test.go") - - // test with imported and not used - tg.run("test", "-i", "github.com/clsung/go-vendor-issue-14613/vendor/mylibtesttest/myapp/myapp_test.go") - tg.runFail("test", "github.com/clsung/go-vendor-issue-14613/vendor/mylibtesttest/myapp/myapp_test.go") - tg.grepStderr("imported and not used:", `should say "imported and not used"`) -} - -func TestVendorList(t *testing.T) { - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") - - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path(".")) - tg.run("get", "github.com/rsc/go-get-issue-11864") - - tg.run("list", "-f", `{{join .TestImports "\n"}}`, "github.com/rsc/go-get-issue-11864/t") - tg.grepStdout("go-get-issue-11864/vendor/vendor.org/p", "did not find vendor-expanded p") - - tg.run("list", "-f", `{{join .XTestImports "\n"}}`, "github.com/rsc/go-get-issue-11864/tx") - tg.grepStdout("go-get-issue-11864/vendor/vendor.org/p", "did not find vendor-expanded p") - - tg.run("list", "-f", `{{join .XTestImports "\n"}}`, "github.com/rsc/go-get-issue-11864/vendor/vendor.org/tx2") - tg.grepStdout("go-get-issue-11864/vendor/vendor.org/tx2", "did not find vendor-expanded tx2") - - tg.run("list", "-f", `{{join .XTestImports "\n"}}`, "github.com/rsc/go-get-issue-11864/vendor/vendor.org/tx3") - tg.grepStdout("go-get-issue-11864/vendor/vendor.org/tx3", "did not find vendor-expanded tx3") -} - -func TestVendor12156(t *testing.T) { - // Former index out of range panic. - tg := testgo(t) - defer tg.cleanup() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/testvendor2")) - tg.cd(filepath.Join(tg.pwd(), "testdata/testvendor2/src/p")) - tg.runFail("build", "p.go") - tg.grepStderrNot("panic", "panicked") - tg.grepStderr(`cannot find package "x"`, "wrong error") -} - -// Module legacy support does path rewriting very similar to vendoring. - -func TestLegacyMod(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/modlegacy")) - tg.run("list", "-f", "{{.Imports}}", "old/p1") - tg.grepStdout("new/p1", "old/p1 should import new/p1") - tg.run("list", "-f", "{{.Imports}}", "new/p1") - tg.grepStdout("new/p2", "new/p1 should import new/p2 (not new/v2/p2)") - tg.grepStdoutNot("new/v2", "new/p1 should NOT import new/v2*") - tg.grepStdout("new/sub/x/v1/y", "new/p1 should import new/sub/x/v1/y (not new/sub/v2/x/v1/y)") - tg.grepStdoutNot("new/sub/v2", "new/p1 should NOT import new/sub/v2*") - tg.grepStdout("new/sub/inner/x", "new/p1 should import new/sub/inner/x (no rewrites)") - tg.run("build", "old/p1", "new/p1") -} - -func TestLegacyModGet(t *testing.T) { - testenv.MustHaveExternalNetwork(t) - testenv.MustHaveExecPath(t, "git") - - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() - tg.setenv("GOPATH", tg.path("d1")) - tg.run("get", "vcs-test.golang.org/git/modlegacy1-old.git/p1") - tg.run("list", "-f", "{{.Deps}}", "vcs-test.golang.org/git/modlegacy1-old.git/p1") - tg.grepStdout("new.git/p2", "old/p1 should depend on new/p2") - tg.grepStdoutNot("new.git/v2/p2", "old/p1 should NOT depend on new/v2/p2") - tg.run("build", "vcs-test.golang.org/git/modlegacy1-old.git/p1", "vcs-test.golang.org/git/modlegacy1-new.git/p1") - - tg.setenv("GOPATH", tg.path("d2")) - - tg.must(os.RemoveAll(tg.path("d2"))) - tg.run("get", "github.com/rsc/vgotest5") - tg.run("get", "github.com/rsc/vgotest4") - tg.run("get", "github.com/myitcv/vgo_example_compat") - - if testing.Short() { - return - } - - tg.must(os.RemoveAll(tg.path("d2"))) - tg.run("get", "github.com/rsc/vgotest4") - tg.run("get", "github.com/rsc/vgotest5") - tg.run("get", "github.com/myitcv/vgo_example_compat") - - tg.must(os.RemoveAll(tg.path("d2"))) - tg.run("get", "github.com/rsc/vgotest4", "github.com/rsc/vgotest5") - tg.run("get", "github.com/myitcv/vgo_example_compat") - - tg.must(os.RemoveAll(tg.path("d2"))) - tg.run("get", "github.com/rsc/vgotest5", "github.com/rsc/vgotest4") - tg.run("get", "github.com/myitcv/vgo_example_compat") - - tg.must(os.RemoveAll(tg.path("d2"))) - tg.run("get", "github.com/myitcv/vgo_example_compat") - tg.run("get", "github.com/rsc/vgotest4", "github.com/rsc/vgotest5") - - pkgs := []string{"github.com/myitcv/vgo_example_compat", "github.com/rsc/vgotest4", "github.com/rsc/vgotest5"} - for i := 0; i < 3; i++ { - for j := 0; j < 3; j++ { - for k := 0; k < 3; k++ { - if i == j || i == k || k == j { - continue - } - tg.must(os.RemoveAll(tg.path("d2"))) - tg.run("get", pkgs[i], pkgs[j], pkgs[k]) - } - } - } -} diff --git a/libgo/go/cmd/gofmt/gofmt.go b/libgo/go/cmd/gofmt/gofmt.go index 9e472b2d51c..8c56af75596 100644 --- a/libgo/go/cmd/gofmt/gofmt.go +++ b/libgo/go/cmd/gofmt/gofmt.go @@ -37,9 +37,16 @@ var ( cpuprofile = flag.String("cpuprofile", "", "write cpu profile to this file") ) +// Keep these in sync with go/format/format.go. const ( tabWidth = 8 - printerMode = printer.UseSpaces | printer.TabIndent + printerMode = printer.UseSpaces | printer.TabIndent | printerNormalizeNumbers + + // printerNormalizeNumbers means to canonicalize number literal prefixes + // and exponents while printing. See https://golang.org/doc/go1.13#gofmt. + // + // This value is defined in go/printer specifically for go/format and cmd/gofmt. + printerNormalizeNumbers = 1 << 30 ) var ( @@ -113,8 +120,6 @@ func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error simplify(file) } - ast.Inspect(file, normalizeNumbers) - res, err := format(fileSet, file, sourceAdj, indentAdj, src, printer.Config{Mode: printerMode, Tabwidth: tabWidth}) if err != nil { return err @@ -294,56 +299,3 @@ func backupFile(filename string, data []byte, perm os.FileMode) (string, error) return bakname, err } - -// normalizeNumbers rewrites base prefixes and exponents to -// use lower-case letters, and removes leading 0's from -// integer imaginary literals. It leaves hexadecimal digits -// alone. -func normalizeNumbers(n ast.Node) bool { - lit, _ := n.(*ast.BasicLit) - if lit == nil || (lit.Kind != token.INT && lit.Kind != token.FLOAT && lit.Kind != token.IMAG) { - return true - } - if len(lit.Value) < 2 { - return false // only one digit (common case) - nothing to do - } - // len(lit.Value) >= 2 - - // We ignore lit.Kind because for lit.Kind == token.IMAG the literal may be an integer - // or floating-point value, decimal or not. Instead, just consider the literal pattern. - x := lit.Value - switch x[:2] { - default: - // 0-prefix octal, decimal int, or float (possibly with 'i' suffix) - if i := strings.LastIndexByte(x, 'E'); i >= 0 { - x = x[:i] + "e" + x[i+1:] - break - } - // remove leading 0's from integer (but not floating-point) imaginary literals - if x[len(x)-1] == 'i' && strings.IndexByte(x, '.') < 0 && strings.IndexByte(x, 'e') < 0 { - x = strings.TrimLeft(x, "0_") - if x == "i" { - x = "0i" - } - } - case "0X": - x = "0x" + x[2:] - fallthrough - case "0x": - // possibly a hexadecimal float - if i := strings.LastIndexByte(x, 'P'); i >= 0 { - x = x[:i] + "p" + x[i+1:] - } - case "0O": - x = "0o" + x[2:] - case "0o": - // nothing to do - case "0B": - x = "0b" + x[2:] - case "0b": - // nothing to do - } - - lit.Value = x - return false -} diff --git a/libgo/go/cmd/gofmt/internal.go b/libgo/go/cmd/gofmt/internal.go index cbc6983b612..058158ad403 100644 --- a/libgo/go/cmd/gofmt/internal.go +++ b/libgo/go/cmd/gofmt/internal.go @@ -37,14 +37,14 @@ func parse(fset *token.FileSet, filename string, src []byte, fragmentOk bool) ( // If this is a declaration list, make it a source file // by inserting a package clause. - // Insert using a ;, not a newline, so that the line numbers + // Insert using a ';', not a newline, so that the line numbers // in psrc match the ones in src. psrc := append([]byte("package p;"), src...) file, err = parser.ParseFile(fset, filename, psrc, parserMode) if err == nil { sourceAdj = func(src []byte, indent int) []byte { // Remove the package clause. - // Gofmt has turned the ; into a \n. + // Gofmt has turned the ';' into a '\n'. src = src[indent+len("package p\n"):] return bytes.TrimSpace(src) } @@ -60,7 +60,7 @@ func parse(fset *token.FileSet, filename string, src []byte, fragmentOk bool) ( // If this is a statement list, make it a source file // by inserting a package clause and turning the list // into a function body. This handles expressions too. - // Insert using a ;, not a newline, so that the line numbers + // Insert using a ';', not a newline, so that the line numbers // in fsrc match the ones in src. Add an extra '\n' before the '}' // to make sure comments are flushed before the '}'. fsrc := append(append([]byte("package p; func _() {"), src...), '\n', '\n', '}') @@ -72,7 +72,7 @@ func parse(fset *token.FileSet, filename string, src []byte, fragmentOk bool) ( indent = 0 } // Remove the wrapping. - // Gofmt has turned the ; into a \n\n. + // Gofmt has turned the "; " into a "\n\n". // There will be two non-blank lines with indent, hence 2*indent. src = src[2*indent+len("package p\n\nfunc _() {"):] // Remove only the "}\n" suffix: remaining whitespaces will be trimmed anyway diff --git a/libgo/go/cmd/internal/objabi/autotype.go b/libgo/go/cmd/internal/objabi/autotype.go index 1b46b0ffece..f9d17a3b99e 100644 --- a/libgo/go/cmd/internal/objabi/autotype.go +++ b/libgo/go/cmd/internal/objabi/autotype.go @@ -1,5 +1,5 @@ // Derived from Inferno utils/6l/l.h and related files. -// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h +// https://bitbucket.org/inferno-os/inferno-os/src/master/utils/6l/l.h // // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) diff --git a/libgo/go/cmd/internal/objabi/funcdata.go b/libgo/go/cmd/internal/objabi/funcdata.go index 08b75eb9fed..d5bacb5900b 100644 --- a/libgo/go/cmd/internal/objabi/funcdata.go +++ b/libgo/go/cmd/internal/objabi/funcdata.go @@ -11,13 +11,14 @@ package objabi // ../../../runtime/symtab.go. const ( - PCDATA_RegMapIndex = 0 + PCDATA_RegMapIndex = 0 // if !go115ReduceLiveness + PCDATA_UnsafePoint = 0 // if go115ReduceLiveness PCDATA_StackMapIndex = 1 PCDATA_InlTreeIndex = 2 FUNCDATA_ArgsPointerMaps = 0 FUNCDATA_LocalsPointerMaps = 1 - FUNCDATA_RegPointerMaps = 2 + FUNCDATA_RegPointerMaps = 2 // if !go115ReduceLiveness FUNCDATA_StackObjects = 3 FUNCDATA_InlTree = 4 FUNCDATA_OpenCodedDeferInfo = 5 @@ -28,3 +29,26 @@ const ( // This value is generated by the compiler, assembler, or linker. ArgsSizeUnknown = -0x80000000 ) + +// Special PCDATA values. +const ( + // PCDATA_RegMapIndex values. + // + // Only if !go115ReduceLiveness. + PCDATA_RegMapUnsafe = -2 // Unsafe for async preemption + + // PCDATA_UnsafePoint values. + PCDATA_UnsafePointSafe = -1 // Safe for async preemption + PCDATA_UnsafePointUnsafe = -2 // Unsafe for async preemption + + // PCDATA_Restart1(2) apply on a sequence of instructions, within + // which if an async preemption happens, we should back off the PC + // to the start of the sequence when resuming. + // We need two so we can distinguish the start/end of the sequence + // in case that two sequences are next to each other. + PCDATA_Restart1 = -3 + PCDATA_Restart2 = -4 + + // Like PCDATA_Restart1, but back to function entry if async preempted. + PCDATA_RestartAtEntry = -5 +) diff --git a/libgo/go/cmd/internal/objabi/head.go b/libgo/go/cmd/internal/objabi/head.go index 6836c338c93..95b8db3809b 100644 --- a/libgo/go/cmd/internal/objabi/head.go +++ b/libgo/go/cmd/internal/objabi/head.go @@ -1,5 +1,5 @@ // Derived from Inferno utils/6l/l.h and related files. -// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h +// https://bitbucket.org/inferno-os/inferno-os/src/master/utils/6l/l.h // // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) diff --git a/libgo/go/cmd/internal/objabi/reloctype.go b/libgo/go/cmd/internal/objabi/reloctype.go index dc6482802af..f029a3c396d 100644 --- a/libgo/go/cmd/internal/objabi/reloctype.go +++ b/libgo/go/cmd/internal/objabi/reloctype.go @@ -1,5 +1,5 @@ // Derived from Inferno utils/6l/l.h and related files. -// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h +// https://bitbucket.org/inferno-os/inferno-os/src/master/utils/6l/l.h // // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) diff --git a/libgo/go/cmd/internal/objabi/stack.go b/libgo/go/cmd/internal/objabi/stack.go index 7320dbf365f..05a1d4a4b58 100644 --- a/libgo/go/cmd/internal/objabi/stack.go +++ b/libgo/go/cmd/internal/objabi/stack.go @@ -18,7 +18,7 @@ const ( ) // Initialize StackGuard and StackLimit according to target system. -var StackGuard = 896*stackGuardMultiplier() + StackSystem +var StackGuard = 928*stackGuardMultiplier() + StackSystem var StackLimit = StackGuard - StackSystem - StackSmall // stackGuardMultiplier returns a multiplier to apply to the default diff --git a/libgo/go/cmd/internal/objabi/symkind.go b/libgo/go/cmd/internal/objabi/symkind.go index 69f15286cde..374aaa6514a 100644 --- a/libgo/go/cmd/internal/objabi/symkind.go +++ b/libgo/go/cmd/internal/objabi/symkind.go @@ -1,5 +1,5 @@ // Derived from Inferno utils/6l/l.h and related files. -// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h +// https://bitbucket.org/inferno-os/inferno-os/src/master/utils/6l/l.h // // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) diff --git a/libgo/go/cmd/internal/objabi/symkind_string.go b/libgo/go/cmd/internal/objabi/symkind_string.go index 2b9a9080e8c..919a666e7b1 100644 --- a/libgo/go/cmd/internal/objabi/symkind_string.go +++ b/libgo/go/cmd/internal/objabi/symkind_string.go @@ -4,9 +4,29 @@ package objabi import "strconv" -const _SymKind_name = "SxxxSTEXTSRODATASNOPTRDATASDATASBSSSNOPTRBSSSTLSBSSSDWARFINFOSDWARFRANGESDWARFLOCSDWARFMISCSABIALIAS" +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[Sxxx-0] + _ = x[STEXT-1] + _ = x[SRODATA-2] + _ = x[SNOPTRDATA-3] + _ = x[SDATA-4] + _ = x[SBSS-5] + _ = x[SNOPTRBSS-6] + _ = x[STLSBSS-7] + _ = x[SDWARFINFO-8] + _ = x[SDWARFRANGE-9] + _ = x[SDWARFLOC-10] + _ = x[SDWARFLINES-11] + _ = x[SABIALIAS-12] + _ = x[SLIBFUZZER_EXTRA_COUNTER-13] +} + +const _SymKind_name = "SxxxSTEXTSRODATASNOPTRDATASDATASBSSSNOPTRBSSSTLSBSSSDWARFINFOSDWARFRANGESDWARFLOCSDWARFLINESSABIALIASSLIBFUZZER_EXTRA_COUNTER" -var _SymKind_index = [...]uint8{0, 4, 9, 16, 26, 31, 35, 44, 51, 61, 72, 81, 91, 100} +var _SymKind_index = [...]uint8{0, 4, 9, 16, 26, 31, 35, 44, 51, 61, 72, 81, 92, 101, 125} func (i SymKind) String() string { if i >= SymKind(len(_SymKind_index)-1) { diff --git a/libgo/go/cmd/internal/objabi/util.go b/libgo/go/cmd/internal/objabi/util.go index 0e7693ee564..30d9ac51366 100644 --- a/libgo/go/cmd/internal/objabi/util.go +++ b/libgo/go/cmd/internal/objabi/util.go @@ -25,6 +25,7 @@ var ( GOARCH = envOr("GOARCH", defaultGOARCH) GOOS = envOr("GOOS", defaultGOOS) GO386 = envOr("GO386", defaultGO386) + GOAMD64 = goamd64() GOARM = goarm() GOMIPS = gomips() GOMIPS64 = gomips64() @@ -36,9 +37,15 @@ var ( const ( ElfRelocOffset = 256 - MachoRelocOffset = 2048 // reserve enough space for ELF relocations + MachoRelocOffset = 2048 // reserve enough space for ELF relocations + Go115AMD64 = "alignedjumps" // Should be "alignedjumps" or "normaljumps"; this replaces environment variable introduced in CL 219357. ) +// TODO(1.16): assuming no issues in 1.15 release, remove this and related constant. +func goamd64() string { + return Go115AMD64 +} + func goarm() int { switch v := envOr("GOARM", defaultGOARM); v { case "5": @@ -127,7 +134,7 @@ func init() { } func Framepointer_enabled(goos, goarch string) bool { - return framepointer_enabled != 0 && (goarch == "amd64" || goarch == "arm64" && goos == "linux") + return framepointer_enabled != 0 && (goarch == "amd64" || goarch == "arm64" && (goos == "linux" || goos == "darwin")) } func addexp(s string) { @@ -152,9 +159,10 @@ func addexp(s string) { } var ( - framepointer_enabled int = 1 - Fieldtrack_enabled int - Preemptibleloops_enabled int + framepointer_enabled int = 1 + Fieldtrack_enabled int + Preemptibleloops_enabled int + Staticlockranking_enabled int ) // Toolchain experiments. @@ -168,6 +176,7 @@ var exper = []struct { {"fieldtrack", &Fieldtrack_enabled}, {"framepointer", &framepointer_enabled}, {"preemptibleloops", &Preemptibleloops_enabled}, + {"staticlockranking", &Staticlockranking_enabled}, } var defaultExpstring = Expstring() diff --git a/libgo/go/cmd/internal/sys/supported.go b/libgo/go/cmd/internal/sys/supported.go index 02f833e945e..c27b3b986d8 100644 --- a/libgo/go/cmd/internal/sys/supported.go +++ b/libgo/go/cmd/internal/sys/supported.go @@ -35,9 +35,11 @@ func MSanSupported(goos, goarch string) bool { func MustLinkExternal(goos, goarch string) bool { switch goos { case "android": - return true + if goarch != "arm64" { + return true + } case "darwin": - if goarch == "arm" || goarch == "arm64" { + if goarch == "arm64" { return true } } @@ -67,7 +69,7 @@ func BuildModeSupported(compiler, buildmode, goos, goarch string) bool { case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/ppc64le", "linux/s390x", "android/amd64", "android/arm", "android/arm64", "android/386", "freebsd/amd64", - "darwin/amd64", "darwin/386", + "darwin/amd64", "windows/amd64", "windows/386": return true } @@ -85,7 +87,8 @@ func BuildModeSupported(compiler, buildmode, goos, goarch string) bool { "android/amd64", "android/arm", "android/arm64", "android/386", "freebsd/amd64", "darwin/amd64", - "aix/ppc64": + "aix/ppc64", + "windows/386", "windows/amd64", "windows/arm": return true } return false diff --git a/libgo/go/cmd/vet/main.go b/libgo/go/cmd/vet/main.go index 2a4f929d609..6381de840c0 100644 --- a/libgo/go/cmd/vet/main.go +++ b/libgo/go/cmd/vet/main.go @@ -15,12 +15,14 @@ import ( "golang.org/x/tools/go/analysis/passes/copylock" "golang.org/x/tools/go/analysis/passes/errorsas" "golang.org/x/tools/go/analysis/passes/httpresponse" + "golang.org/x/tools/go/analysis/passes/ifaceassert" "golang.org/x/tools/go/analysis/passes/loopclosure" "golang.org/x/tools/go/analysis/passes/lostcancel" "golang.org/x/tools/go/analysis/passes/nilfunc" "golang.org/x/tools/go/analysis/passes/printf" "golang.org/x/tools/go/analysis/passes/shift" "golang.org/x/tools/go/analysis/passes/stdmethods" + "golang.org/x/tools/go/analysis/passes/stringintconv" "golang.org/x/tools/go/analysis/passes/structtag" "golang.org/x/tools/go/analysis/passes/tests" "golang.org/x/tools/go/analysis/passes/unmarshal" @@ -43,12 +45,14 @@ func main() { copylock.Analyzer, errorsas.Analyzer, httpresponse.Analyzer, + ifaceassert.Analyzer, loopclosure.Analyzer, lostcancel.Analyzer, nilfunc.Analyzer, printf.Analyzer, shift.Analyzer, stdmethods.Analyzer, + stringintconv.Analyzer, structtag.Analyzer, tests.Analyzer, unmarshal.Analyzer, diff --git a/libgo/go/compress/flate/deflate_test.go b/libgo/go/compress/flate/deflate_test.go index 4288f62a8d1..3362d256cf4 100644 --- a/libgo/go/compress/flate/deflate_test.go +++ b/libgo/go/compress/flate/deflate_test.go @@ -512,33 +512,57 @@ func TestWriterReset(t *testing.T) { t.Errorf("level %d Writer not reset after Reset", level) } } - testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriter(w, NoCompression) }) - testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriter(w, DefaultCompression) }) - testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriter(w, BestCompression) }) - dict := []byte("we are the world") - testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriterDict(w, NoCompression, dict) }) - testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriterDict(w, DefaultCompression, dict) }) - testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriterDict(w, BestCompression, dict) }) + + levels := []int{0, 1, 2, 5, 9} + for _, level := range levels { + t.Run(fmt.Sprint(level), func(t *testing.T) { + testResetOutput(t, level, nil) + }) + } + + t.Run("dict", func(t *testing.T) { + for _, level := range levels { + t.Run(fmt.Sprint(level), func(t *testing.T) { + testResetOutput(t, level, nil) + }) + } + }) } -func testResetOutput(t *testing.T, newWriter func(w io.Writer) (*Writer, error)) { +func testResetOutput(t *testing.T, level int, dict []byte) { + writeData := func(w *Writer) { + msg := []byte("now is the time for all good gophers") + w.Write(msg) + w.Flush() + + hello := []byte("hello world") + for i := 0; i < 1024; i++ { + w.Write(hello) + } + + fill := bytes.Repeat([]byte("x"), 65000) + w.Write(fill) + } + buf := new(bytes.Buffer) - w, err := newWriter(buf) + var w *Writer + var err error + if dict == nil { + w, err = NewWriter(buf, level) + } else { + w, err = NewWriterDict(buf, level, dict) + } if err != nil { t.Fatalf("NewWriter: %v", err) } - b := []byte("hello world") - for i := 0; i < 1024; i++ { - w.Write(b) - } + + writeData(w) w.Close() out1 := buf.Bytes() buf2 := new(bytes.Buffer) w.Reset(buf2) - for i := 0; i < 1024; i++ { - w.Write(b) - } + writeData(w) w.Close() out2 := buf2.Bytes() diff --git a/libgo/go/compress/flate/deflatefast.go b/libgo/go/compress/flate/deflatefast.go index 08298b76bbb..24f8be9d5db 100644 --- a/libgo/go/compress/flate/deflatefast.go +++ b/libgo/go/compress/flate/deflatefast.go @@ -4,6 +4,8 @@ package flate +import "math" + // This encoding algorithm, which prioritizes speed over output size, is // based on Snappy's LZ77-style encoder: github.com/golang/snappy @@ -12,6 +14,13 @@ const ( tableSize = 1 << tableBits // Size of the table. tableMask = tableSize - 1 // Mask for table indices. Redundant, but can eliminate bounds checks. tableShift = 32 - tableBits // Right-shift to get the tableBits most significant bits of a uint32. + + // Reset the buffer offset when reaching this. + // Offsets are stored between blocks as int32 values. + // Since the offset we are checking against is at the beginning + // of the buffer, we need to subtract the current and input + // buffer to not risk overflowing the int32. + bufferReset = math.MaxInt32 - maxStoreBlockSize*2 ) func load32(b []byte, i int32) uint32 { @@ -59,8 +68,8 @@ func newDeflateFast() *deflateFast { // to dst and returns the result. func (e *deflateFast) encode(dst []token, src []byte) []token { // Ensure that e.cur doesn't wrap. - if e.cur > 1<<30 { - e.resetAll() + if e.cur >= bufferReset { + e.shiftOffsets() } // This check isn't in the Snappy implementation, but there, the caller @@ -264,22 +273,32 @@ func (e *deflateFast) reset() { e.cur += maxMatchOffset // Protect against e.cur wraparound. - if e.cur > 1<<30 { - e.resetAll() + if e.cur >= bufferReset { + e.shiftOffsets() } } -// resetAll resets the deflateFast struct and is only called in rare -// situations to prevent integer overflow. It manually resets each field -// to avoid causing large stack growth. +// shiftOffsets will shift down all match offset. +// This is only called in rare situations to prevent integer overflow. // -// See https://golang.org/issue/18636. -func (e *deflateFast) resetAll() { - // This is equivalent to: - // *e = deflateFast{cur: maxStoreBlockSize, prev: e.prev[:0]} - e.cur = maxStoreBlockSize - e.prev = e.prev[:0] - for i := range e.table { - e.table[i] = tableEntry{} +// See https://golang.org/issue/18636 and https://github.com/golang/go/issues/34121. +func (e *deflateFast) shiftOffsets() { + if len(e.prev) == 0 { + // We have no history; just clear the table. + for i := range e.table[:] { + e.table[i] = tableEntry{} + } + e.cur = maxMatchOffset + return + } + + // Shift down everything in the table that isn't already too far away. + for i := range e.table[:] { + v := e.table[i].offset - e.cur + maxMatchOffset + if v < 0 { + v = 0 + } + e.table[i].offset = v } + e.cur = maxMatchOffset } diff --git a/libgo/go/compress/flate/huffman_bit_writer.go b/libgo/go/compress/flate/huffman_bit_writer.go index 3e19061f8b5..f111f9f592c 100644 --- a/libgo/go/compress/flate/huffman_bit_writer.go +++ b/libgo/go/compress/flate/huffman_bit_writer.go @@ -634,6 +634,7 @@ func (w *huffmanBitWriter) writeBlockHuff(eof bool, input []byte) { w.literalFreq[endBlockMarker] = 1 const numLiterals = endBlockMarker + 1 + w.offsetFreq[0] = 1 const numOffsets = 1 w.literalEncoding.generate(w.literalFreq, 15) diff --git a/libgo/go/compress/flate/writer_test.go b/libgo/go/compress/flate/writer_test.go index c4d36aa37e9..881cb71cc3a 100644 --- a/libgo/go/compress/flate/writer_test.go +++ b/libgo/go/compress/flate/writer_test.go @@ -173,3 +173,66 @@ func testDeterministic(i int, t *testing.T) { t.Errorf("level %d did not produce deterministic result, result mismatch, len(a) = %d, len(b) = %d", i, len(b1b), len(b2b)) } } + +// TestDeflateFast_Reset will test that encoding is consistent +// across a warparound of the table offset. +// See https://github.com/golang/go/issues/34121 +func TestDeflateFast_Reset(t *testing.T) { + buf := new(bytes.Buffer) + n := 65536 + + for i := 0; i < n; i++ { + fmt.Fprintf(buf, "asdfasdfasdfasdf%d%dfghfgujyut%dyutyu\n", i, i, i) + } + // This is specific to level 1. + const level = 1 + in := buf.Bytes() + offset := 1 + if testing.Short() { + offset = 256 + } + + // We do an encode with a clean buffer to compare. + var want bytes.Buffer + w, err := NewWriter(&want, level) + if err != nil { + t.Fatalf("NewWriter: level %d: %v", level, err) + } + + // Output written 3 times. + w.Write(in) + w.Write(in) + w.Write(in) + w.Close() + + for ; offset <= 256; offset *= 2 { + w, err := NewWriter(ioutil.Discard, level) + if err != nil { + t.Fatalf("NewWriter: level %d: %v", level, err) + } + + // Reset until we are right before the wraparound. + // Each reset adds maxMatchOffset to the offset. + for i := 0; i < (bufferReset-len(in)-offset-maxMatchOffset)/maxMatchOffset; i++ { + // skip ahead to where we are close to wrap around... + w.d.reset(nil) + } + var got bytes.Buffer + w.Reset(&got) + + // Write 3 times, close. + for i := 0; i < 3; i++ { + _, err = w.Write(in) + if err != nil { + t.Fatal(err) + } + } + err = w.Close() + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(got.Bytes(), want.Bytes()) { + t.Fatalf("output did not match at wraparound, len(want) = %d, len(got) = %d", want.Len(), got.Len()) + } + } +} diff --git a/libgo/go/container/list/list.go b/libgo/go/container/list/list.go index b8b599aabb1..210424ceed7 100644 --- a/libgo/go/container/list/list.go +++ b/libgo/go/container/list/list.go @@ -90,11 +90,10 @@ func (l *List) lazyInit() { // insert inserts e after at, increments l.len, and returns e. func (l *List) insert(e, at *Element) *Element { - n := at.next - at.next = e e.prev = at - e.next = n - n.prev = e + e.next = at.next + e.prev.next = e + e.next.prev = e e.list = l l.len++ return e @@ -124,11 +123,10 @@ func (l *List) move(e, at *Element) *Element { e.prev.next = e.next e.next.prev = e.prev - n := at.next - at.next = e e.prev = at - e.next = n - n.prev = e + e.next = at.next + e.prev.next = e + e.next.prev = e return e } @@ -221,7 +219,7 @@ func (l *List) MoveAfter(e, mark *Element) { l.move(e, mark) } -// PushBackList inserts a copy of an other list at the back of list l. +// PushBackList inserts a copy of another list at the back of list l. // The lists l and other may be the same. They must not be nil. func (l *List) PushBackList(other *List) { l.lazyInit() @@ -230,7 +228,7 @@ func (l *List) PushBackList(other *List) { } } -// PushFrontList inserts a copy of an other list at the front of list l. +// PushFrontList inserts a copy of another list at the front of list l. // The lists l and other may be the same. They must not be nil. func (l *List) PushFrontList(other *List) { l.lazyInit() diff --git a/libgo/go/context/context.go b/libgo/go/context/context.go index b561968f31c..b3fdb8277af 100644 --- a/libgo/go/context/context.go +++ b/libgo/go/context/context.go @@ -230,6 +230,9 @@ type CancelFunc func() // Canceling this context releases resources associated with it, so code should // call cancel as soon as the operations running in this Context complete. func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { + if parent == nil { + panic("cannot create context from nil parent") + } c := newCancelCtx(parent) propagateCancel(parent, &c) return &c, func() { c.cancel(true, Canceled) } @@ -425,6 +428,9 @@ func (c *cancelCtx) cancel(removeFromParent bool, err error) { // Canceling this context releases resources associated with it, so code should // call cancel as soon as the operations running in this Context complete. func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) { + if parent == nil { + panic("cannot create context from nil parent") + } if cur, ok := parent.Deadline(); ok && cur.Before(d) { // The current deadline is already sooner than the new one. return WithCancel(parent) @@ -511,6 +517,9 @@ func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { // struct{}. Alternatively, exported context key variables' static // type should be a pointer or interface. func WithValue(parent Context, key, val interface{}) Context { + if parent == nil { + panic("cannot create context from nil parent") + } if key == nil { panic("nil key") } diff --git a/libgo/go/context/context_test.go b/libgo/go/context/context_test.go index cff09fd322f..6b392a29da5 100644 --- a/libgo/go/context/context_test.go +++ b/libgo/go/context/context_test.go @@ -15,6 +15,7 @@ import ( ) type testingT interface { + Deadline() (time.Time, bool) Error(args ...interface{}) Errorf(format string, args ...interface{}) Fail() @@ -26,6 +27,7 @@ type testingT interface { Log(args ...interface{}) Logf(format string, args ...interface{}) Name() string + Parallel() Skip(args ...interface{}) SkipNow() Skipf(format string, args ...interface{}) @@ -39,6 +41,23 @@ type otherContext struct { Context } +const ( + shortDuration = 1 * time.Millisecond // a reasonable duration to block in a test + veryLongDuration = 1000 * time.Hour // an arbitrary upper bound on the test's running time +) + +// quiescent returns an arbitrary duration by which the program should have +// completed any remaining work and reached a steady (idle) state. +func quiescent(t testingT) time.Duration { + deadline, ok := t.Deadline() + if !ok { + return 5 * time.Second + } + + const arbitraryCleanupMargin = 1 * time.Second + return time.Until(deadline) - arbitraryCleanupMargin +} + func XTestBackground(t testingT) { c := Background() if c == nil { @@ -95,9 +114,7 @@ func XTestWithCancel(t testingT) { } } - cancel() - time.Sleep(100 * time.Millisecond) // let cancellation propagate - + cancel() // Should propagate synchronously. for i, c := range contexts { select { case <-c.Done(): @@ -123,7 +140,7 @@ func XTestParentFinishesChild(t testingT) { cancelChild, stop := WithCancel(parent) defer stop() valueChild := WithValue(parent, "key", "value") - timerChild, stop := WithTimeout(valueChild, 10000*time.Hour) + timerChild, stop := WithTimeout(valueChild, veryLongDuration) defer stop() select { @@ -252,11 +269,14 @@ func XTestChildFinishesFirst(t testingT) { } } -func testDeadline(c Context, name string, failAfter time.Duration, t testingT) { +func testDeadline(c Context, name string, t testingT) { t.Helper() + d := quiescent(t) + timer := time.NewTimer(d) + defer timer.Stop() select { - case <-time.After(failAfter): - t.Fatalf("%s: context should have timed out", name) + case <-timer.C: + t.Fatalf("%s: context not timed out after %v", name, d) case <-c.Done(): } if e := c.Err(); e != DeadlineExceeded { @@ -265,51 +285,54 @@ func testDeadline(c Context, name string, failAfter time.Duration, t testingT) { } func XTestDeadline(t testingT) { - c, _ := WithDeadline(Background(), time.Now().Add(50*time.Millisecond)) + t.Parallel() + + c, _ := WithDeadline(Background(), time.Now().Add(shortDuration)) if got, prefix := fmt.Sprint(c), "context.Background.WithDeadline("; !strings.HasPrefix(got, prefix) { t.Errorf("c.String() = %q want prefix %q", got, prefix) } - testDeadline(c, "WithDeadline", time.Second, t) + testDeadline(c, "WithDeadline", t) - c, _ = WithDeadline(Background(), time.Now().Add(50*time.Millisecond)) + c, _ = WithDeadline(Background(), time.Now().Add(shortDuration)) o := otherContext{c} - testDeadline(o, "WithDeadline+otherContext", time.Second, t) + testDeadline(o, "WithDeadline+otherContext", t) - c, _ = WithDeadline(Background(), time.Now().Add(50*time.Millisecond)) + c, _ = WithDeadline(Background(), time.Now().Add(shortDuration)) o = otherContext{c} - c, _ = WithDeadline(o, time.Now().Add(4*time.Second)) - testDeadline(c, "WithDeadline+otherContext+WithDeadline", 2*time.Second, t) + c, _ = WithDeadline(o, time.Now().Add(veryLongDuration)) + testDeadline(c, "WithDeadline+otherContext+WithDeadline", t) - c, _ = WithDeadline(Background(), time.Now().Add(-time.Millisecond)) - testDeadline(c, "WithDeadline+inthepast", time.Second, t) + c, _ = WithDeadline(Background(), time.Now().Add(-shortDuration)) + testDeadline(c, "WithDeadline+inthepast", t) c, _ = WithDeadline(Background(), time.Now()) - testDeadline(c, "WithDeadline+now", time.Second, t) + testDeadline(c, "WithDeadline+now", t) } func XTestTimeout(t testingT) { - c, _ := WithTimeout(Background(), 50*time.Millisecond) + t.Parallel() + + c, _ := WithTimeout(Background(), shortDuration) if got, prefix := fmt.Sprint(c), "context.Background.WithDeadline("; !strings.HasPrefix(got, prefix) { t.Errorf("c.String() = %q want prefix %q", got, prefix) } - testDeadline(c, "WithTimeout", time.Second, t) + testDeadline(c, "WithTimeout", t) - c, _ = WithTimeout(Background(), 50*time.Millisecond) + c, _ = WithTimeout(Background(), shortDuration) o := otherContext{c} - testDeadline(o, "WithTimeout+otherContext", time.Second, t) + testDeadline(o, "WithTimeout+otherContext", t) - c, _ = WithTimeout(Background(), 50*time.Millisecond) + c, _ = WithTimeout(Background(), shortDuration) o = otherContext{c} - c, _ = WithTimeout(o, 3*time.Second) - testDeadline(c, "WithTimeout+otherContext+WithTimeout", 2*time.Second, t) + c, _ = WithTimeout(o, veryLongDuration) + testDeadline(c, "WithTimeout+otherContext+WithTimeout", t) } func XTestCanceledTimeout(t testingT) { c, _ := WithTimeout(Background(), time.Second) o := otherContext{c} - c, cancel := WithTimeout(o, 2*time.Second) - cancel() - time.Sleep(100 * time.Millisecond) // let cancellation propagate + c, cancel := WithTimeout(o, veryLongDuration) + cancel() // Should propagate synchronously. select { case <-c.Done(): default: @@ -399,9 +422,9 @@ func XTestAllocs(t testingT, testingShort func() bool, testingAllocsPerRun func( gccgoLimit: 3, }, { - desc: "WithTimeout(bg, 15*time.Millisecond)", + desc: "WithTimeout(bg, 1*time.Nanosecond)", f: func() { - c, _ := WithTimeout(bg, 15*time.Millisecond) + c, _ := WithTimeout(bg, 1*time.Nanosecond) <-c.Done() }, limit: 12, @@ -467,14 +490,20 @@ func XTestSimultaneousCancels(t testingT) { wg.Done() }(cancel) } + + d := quiescent(t) + stuck := make(chan struct{}) + timer := time.AfterFunc(d, func() { close(stuck) }) + defer timer.Stop() + // Wait on all the contexts in a random order. for ctx := range m { select { case <-ctx.Done(): - case <-time.After(1 * time.Second): + case <-stuck: buf := make([]byte, 10<<10) n := runtime.Stack(buf, true) - t.Fatalf("timed out waiting for <-ctx.Done(); stacks:\n%s", buf[:n]) + t.Fatalf("timed out after %v waiting for <-ctx.Done(); stacks:\n%s", d, buf[:n]) } } // Wait for all the cancel functions to return. @@ -485,10 +514,10 @@ func XTestSimultaneousCancels(t testingT) { }() select { case <-done: - case <-time.After(1 * time.Second): + case <-stuck: buf := make([]byte, 10<<10) n := runtime.Stack(buf, true) - t.Fatalf("timed out waiting for cancel functions; stacks:\n%s", buf[:n]) + t.Fatalf("timed out after %v waiting for cancel functions; stacks:\n%s", d, buf[:n]) } } @@ -500,12 +529,15 @@ func XTestInterlockedCancels(t testingT) { cancelChild() }() cancelParent() + d := quiescent(t) + timer := time.NewTimer(d) + defer timer.Stop() select { case <-child.Done(): - case <-time.After(1 * time.Second): + case <-timer.C: buf := make([]byte, 10<<10) n := runtime.Stack(buf, true) - t.Fatalf("timed out waiting for child.Done(); stacks:\n%s", buf[:n]) + t.Fatalf("timed out after %v waiting for child.Done(); stacks:\n%s", d, buf[:n]) } } @@ -518,12 +550,13 @@ func XTestLayersTimeout(t testingT) { } func testLayers(t testingT, seed int64, testTimeout bool) { - rand.Seed(seed) + t.Parallel() + + r := rand.New(rand.NewSource(seed)) errorf := func(format string, a ...interface{}) { t.Errorf(fmt.Sprintf("seed=%d: %s", seed, format), a...) } const ( - timeout = 200 * time.Millisecond minLayers = 30 ) type value int @@ -534,7 +567,7 @@ func testLayers(t testingT, seed int64, testTimeout bool) { ctx = Background() ) for i := 0; i < minLayers || numTimers == 0 || len(cancels) == 0 || len(vals) == 0; i++ { - switch rand.Intn(3) { + switch r.Intn(3) { case 0: v := new(value) ctx = WithValue(ctx, v, v) @@ -545,7 +578,11 @@ func testLayers(t testingT, seed int64, testTimeout bool) { cancels = append(cancels, cancel) case 2: var cancel CancelFunc - ctx, cancel = WithTimeout(ctx, timeout) + d := veryLongDuration + if testTimeout { + d = shortDuration + } + ctx, cancel = WithTimeout(ctx, d) cancels = append(cancels, cancel) numTimers++ } @@ -557,10 +594,12 @@ func testLayers(t testingT, seed int64, testTimeout bool) { } } } - select { - case <-ctx.Done(): - errorf("ctx should not be canceled yet") - default: + if !testTimeout { + select { + case <-ctx.Done(): + errorf("ctx should not be canceled yet") + default: + } } if s, prefix := fmt.Sprint(ctx), "context.Background."; !strings.HasPrefix(s, prefix) { t.Errorf("ctx.String() = %q want prefix %q", s, prefix) @@ -568,14 +607,17 @@ func testLayers(t testingT, seed int64, testTimeout bool) { t.Log(ctx) checkValues("before cancel") if testTimeout { + d := quiescent(t) + timer := time.NewTimer(d) + defer timer.Stop() select { case <-ctx.Done(): - case <-time.After(timeout + time.Second): - errorf("ctx should have timed out") + case <-timer.C: + errorf("ctx should have timed out after %v", d) } checkValues("after timeout") } else { - cancel := cancels[rand.Intn(len(cancels))] + cancel := cancels[r.Intn(len(cancels))] cancel() select { case <-ctx.Done(): @@ -615,8 +657,8 @@ func XTestWithCancelCanceledParent(t testingT) { c, _ := WithCancel(parent) select { case <-c.Done(): - case <-time.After(5 * time.Second): - t.Fatal("timeout waiting for Done") + default: + t.Errorf("child not done immediately upon construction") } if got, want := c.Err(), Canceled; got != want { t.Errorf("child not cancelled; got = %v, want = %v", got, want) @@ -634,6 +676,21 @@ func XTestWithValueChecksKey(t testingT) { } } +func XTestInvalidDerivedFail(t testingT) { + panicVal := recoveredValue(func() { WithCancel(nil) }) + if panicVal == nil { + t.Error("expected panic") + } + panicVal = recoveredValue(func() { WithDeadline(nil, time.Now().Add(shortDuration)) }) + if panicVal == nil { + t.Error("expected panic") + } + panicVal = recoveredValue(func() { WithValue(nil, "foo", "bar") }) + if panicVal == nil { + t.Error("expected panic") + } +} + func recoveredValue(fn func()) (v interface{}) { defer func() { v = recover() }() fn() @@ -687,7 +744,7 @@ func XTestCustomContextGoroutines(t testingT) { cancel0() checkCreatedGoroutine() - _, cancel0 = WithTimeout(&myDoneCtx{Background()}, 1*time.Hour) + _, cancel0 = WithTimeout(&myDoneCtx{Background()}, veryLongDuration) cancel0() checkCreatedGoroutine() @@ -707,7 +764,7 @@ func XTestCustomContextGoroutines(t testingT) { defer cancel3b() checkCreatedGoroutine() // ctx1 is not providing Done, must not be used - ctx4, cancel4 := WithTimeout(ctx3, 1*time.Hour) + ctx4, cancel4 := WithTimeout(ctx3, veryLongDuration) defer cancel4() checkNoGoroutine() @@ -718,7 +775,7 @@ func XTestCustomContextGoroutines(t testingT) { cancel5() checkNoGoroutine() - _, cancel6 := WithTimeout(ctx5, 1*time.Hour) + _, cancel6 := WithTimeout(ctx5, veryLongDuration) defer cancel6() checkNoGoroutine() diff --git a/libgo/go/context/example_test.go b/libgo/go/context/example_test.go index b91a8acef3a..72ac5d2e49c 100644 --- a/libgo/go/context/example_test.go +++ b/libgo/go/context/example_test.go @@ -10,6 +10,8 @@ import ( "time" ) +const shortDuration = 1 * time.Millisecond // a reasonable duration to block in an example + // This example demonstrates the use of a cancelable context to prevent a // goroutine leak. By the end of the example function, the goroutine started // by gen will return without leaking. @@ -55,7 +57,7 @@ func ExampleWithCancel() { // This example passes a context with an arbitrary deadline to tell a blocking // function that it should abandon its work as soon as it gets to it. func ExampleWithDeadline() { - d := time.Now().Add(50 * time.Millisecond) + d := time.Now().Add(shortDuration) ctx, cancel := context.WithDeadline(context.Background(), d) // Even though ctx will be expired, it is good practice to call its @@ -79,7 +81,7 @@ func ExampleWithDeadline() { func ExampleWithTimeout() { // Pass a context with a timeout to tell a blocking function that it // should abandon its work after the timeout elapses. - ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond) + ctx, cancel := context.WithTimeout(context.Background(), shortDuration) defer cancel() select { diff --git a/libgo/go/context/x_test.go b/libgo/go/context/x_test.go index e85ef2d50e5..00eca72d5af 100644 --- a/libgo/go/context/x_test.go +++ b/libgo/go/context/x_test.go @@ -26,5 +26,6 @@ func TestLayersTimeout(t *testing.T) { XTestLayersTimeout(t) } func TestCancelRemoves(t *testing.T) { XTestCancelRemoves(t) } func TestWithCancelCanceledParent(t *testing.T) { XTestWithCancelCanceledParent(t) } func TestWithValueChecksKey(t *testing.T) { XTestWithValueChecksKey(t) } +func TestInvalidDerivedFail(t *testing.T) { XTestInvalidDerivedFail(t) } func TestDeadlineExceededSupportsTimeout(t *testing.T) { XTestDeadlineExceededSupportsTimeout(t) } func TestCustomContextGoroutines(t *testing.T) { XTestCustomContextGoroutines(t) } diff --git a/libgo/go/crypto/crypto.go b/libgo/go/crypto/crypto.go index b4d6cdcab4e..ce473b5afe1 100644 --- a/libgo/go/crypto/crypto.go +++ b/libgo/go/crypto/crypto.go @@ -20,6 +20,51 @@ func (h Hash) HashFunc() Hash { return h } +func (h Hash) String() string { + switch h { + case MD4: + return "MD4" + case MD5: + return "MD5" + case SHA1: + return "SHA-1" + case SHA224: + return "SHA-224" + case SHA256: + return "SHA-256" + case SHA384: + return "SHA-384" + case SHA512: + return "SHA-512" + case MD5SHA1: + return "MD5+SHA1" + case RIPEMD160: + return "RIPEMD-160" + case SHA3_224: + return "SHA3-224" + case SHA3_256: + return "SHA3-256" + case SHA3_384: + return "SHA3-384" + case SHA3_512: + return "SHA3-512" + case SHA512_224: + return "SHA-512/224" + case SHA512_256: + return "SHA-512/256" + case BLAKE2s_256: + return "BLAKE2s-256" + case BLAKE2b_256: + return "BLAKE2b-256" + case BLAKE2b_384: + return "BLAKE2b-384" + case BLAKE2b_512: + return "BLAKE2b-512" + default: + return "unknown hash value " + strconv.Itoa(int(h)) + } +} + const ( MD4 Hash = 1 + iota // import golang.org/x/crypto/md4 MD5 // import crypto/md5 @@ -119,7 +164,7 @@ type Signer interface { // Sign signs digest with the private key, possibly using entropy from // rand. For an RSA key, the resulting signature should be either a - // PKCS#1 v1.5 or PSS signature (as indicated by opts). For an (EC)DSA + // PKCS #1 v1.5 or PSS signature (as indicated by opts). For an (EC)DSA // key, it should be a DER-serialised, ASN.1 signature structure. // // Hash implements the SignerOpts interface and, in most cases, one can diff --git a/libgo/go/crypto/ecdsa/ecdsa.go b/libgo/go/crypto/ecdsa/ecdsa.go index 65911e737ac..ccce8738594 100644 --- a/libgo/go/crypto/ecdsa/ecdsa.go +++ b/libgo/go/crypto/ecdsa/ecdsa.go @@ -33,10 +33,12 @@ import ( "crypto/elliptic" "crypto/internal/randutil" "crypto/sha512" - "encoding/asn1" "errors" "io" "math/big" + + "golang.org/x/crypto/cryptobyte" + "golang.org/x/crypto/cryptobyte/asn1" ) // A invertible implements fast inverse mod Curve.Params().N @@ -60,21 +62,49 @@ type PublicKey struct { X, Y *big.Int } +// Any methods implemented on PublicKey might need to also be implemented on +// PrivateKey, as the latter embeds the former and will expose its methods. + +// Equal reports whether pub and x have the same value. +// +// Two keys are only considered to have the same value if they have the same Curve value. +// Note that for example elliptic.P256() and elliptic.P256().Params() are different +// values, as the latter is a generic not constant time implementation. +func (pub *PublicKey) Equal(x crypto.PublicKey) bool { + xx, ok := x.(*PublicKey) + if !ok { + return false + } + return pub.X.Cmp(xx.X) == 0 && pub.Y.Cmp(xx.Y) == 0 && + // Standard library Curve implementations are singletons, so this check + // will work for those. Other Curves might be equivalent even if not + // singletons, but there is no definitive way to check for that, and + // better to err on the side of safety. + pub.Curve == xx.Curve +} + // PrivateKey represents an ECDSA private key. type PrivateKey struct { PublicKey D *big.Int } -type ecdsaSignature struct { - R, S *big.Int -} - // Public returns the public key corresponding to priv. func (priv *PrivateKey) Public() crypto.PublicKey { return &priv.PublicKey } +// Equal reports whether priv and x have the same value. +// +// See PublicKey.Equal for details on how Curve is compared. +func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool { + xx, ok := x.(*PrivateKey) + if !ok { + return false + } + return priv.PublicKey.Equal(&xx.PublicKey) && priv.D.Cmp(xx.D) == 0 +} + // Sign signs digest with priv, reading randomness from rand. The opts argument // is not currently used but, in keeping with the crypto.Signer interface, // should be the hash function used to digest the message. @@ -88,7 +118,12 @@ func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOp return nil, err } - return asn1.Marshal(ecdsaSignature{r, s}) + var b cryptobyte.Builder + b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) { + b.AddASN1BigInt(r) + b.AddASN1BigInt(s) + }) + return b.Bytes() } var one = new(big.Int).SetInt64(1) @@ -159,7 +194,7 @@ var errZeroParam = errors.New("zero parameter") // Sign signs a hash (which should be the result of hashing a larger message) // using the private key, priv. If the hash is longer than the bit-length of the -// private key's curve order, the hash will be truncated to that length. It +// private key's curve order, the hash will be truncated to that length. It // returns the signature as a pair of integers. The security of the private key // depends on the entropy of rand. func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) { @@ -199,6 +234,10 @@ func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err err // See [NSA] 3.4.1 c := priv.PublicKey.Curve + return sign(priv, &csprng, c, hash) +} + +func signGeneric(priv *PrivateKey, csprng *cipher.StreamReader, c elliptic.Curve, hash []byte) (r, s *big.Int, err error) { N := c.Params().N if N.Sign() == 0 { return nil, nil, errZeroParam @@ -206,7 +245,7 @@ func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err err var k, kInv *big.Int for { for { - k, err = randFieldElement(c, csprng) + k, err = randFieldElement(c, *csprng) if err != nil { r = nil return @@ -238,6 +277,15 @@ func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err err return } +// SignASN1 signs a hash (which should be the result of hashing a larger message) +// using the private key, priv. If the hash is longer than the bit-length of the +// private key's curve order, the hash will be truncated to that length. It +// returns the ASN.1 encoded signature. The security of the private key +// depends on the entropy of rand. +func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) { + return priv.Sign(rand, hash, nil) +} + // Verify verifies the signature in r, s of hash using the public key, pub. Its // return value records whether the signature is valid. func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool { @@ -251,9 +299,13 @@ func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool { if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 { return false } - e := hashToInt(hash, c) + return verify(pub, c, hash, r, s) +} +func verifyGeneric(pub *PublicKey, c elliptic.Curve, hash []byte, r, s *big.Int) bool { + e := hashToInt(hash, c) var w *big.Int + N := c.Params().N if in, ok := c.(invertible); ok { w = in.Inverse(s) } else { @@ -282,6 +334,24 @@ func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool { return x.Cmp(r) == 0 } +// VerifyASN1 verifies the ASN.1 encoded signature, sig, of hash using the +// public key, pub. Its return value records whether the signature is valid. +func VerifyASN1(pub *PublicKey, hash, sig []byte) bool { + var ( + r, s = &big.Int{}, &big.Int{} + inner cryptobyte.String + ) + input := cryptobyte.String(sig) + if !input.ReadASN1(&inner, asn1.SEQUENCE) || + !input.Empty() || + !inner.ReadASN1Integer(r) || + !inner.ReadASN1Integer(s) || + !inner.Empty() { + return false + } + return Verify(pub, hash, r, s) +} + type zr struct { io.Reader } diff --git a/libgo/go/crypto/ecdsa/ecdsa_noasm.go b/libgo/go/crypto/ecdsa/ecdsa_noasm.go new file mode 100644 index 00000000000..b7e73179cde --- /dev/null +++ b/libgo/go/crypto/ecdsa/ecdsa_noasm.go @@ -0,0 +1,21 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// -build !s390x + +package ecdsa + +import ( + "crypto/cipher" + "crypto/elliptic" + "math/big" +) + +func sign(priv *PrivateKey, csprng *cipher.StreamReader, c elliptic.Curve, hash []byte) (r, s *big.Int, err error) { + return signGeneric(priv, csprng, c, hash) +} + +func verify(pub *PublicKey, c elliptic.Curve, hash []byte, r, s *big.Int) bool { + return verifyGeneric(pub, c, hash, r, s) +} diff --git a/libgo/go/crypto/ecdsa/ecdsa_s390x.go b/libgo/go/crypto/ecdsa/ecdsa_s390x.go new file mode 100644 index 00000000000..dcbbef32c71 --- /dev/null +++ b/libgo/go/crypto/ecdsa/ecdsa_s390x.go @@ -0,0 +1,164 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore_for_gccgo + +package ecdsa + +import ( + "crypto/cipher" + "crypto/elliptic" + "internal/cpu" + "math/big" +) + +// kdsa invokes the "compute digital signature authentication" +// instruction with the given function code and 4096 byte +// parameter block. +// +// The return value corresponds to the condition code set by the +// instruction. Interrupted invocations are handled by the +// function. +//go:noescape +func kdsa(fc uint64, params *[4096]byte) (errn uint64) + +// canUseKDSA checks if KDSA instruction is available, and if it is, it checks +// the name of the curve to see if it matches the curves supported(P-256, P-384, P-521). +// Then, based on the curve name, a function code and a block size will be assigned. +// If KDSA instruction is not available or if the curve is not supported, canUseKDSA +// will set ok to false. +func canUseKDSA(c elliptic.Curve) (functionCode uint64, blockSize int, ok bool) { + if !cpu.S390X.HasECDSA { + return 0, 0, false + } + switch c.Params().Name { + case "P-256": + return 1, 32, true + case "P-384": + return 2, 48, true + case "P-521": + return 3, 80, true + } + return 0, 0, false // A mismatch +} + +// zeroExtendAndCopy pads src with leading zeros until it has the size given. +// It then copies the padded src into the dst. Bytes beyond size in dst are +// not modified. +func zeroExtendAndCopy(dst, src []byte, size int) { + nz := size - len(src) + if nz < 0 { + panic("src is too long") + } + // the compiler should replace this loop with a memclr call + z := dst[:nz] + for i := range z { + z[i] = 0 + } + copy(dst[nz:size], src[:size-nz]) + return +} + +func sign(priv *PrivateKey, csprng *cipher.StreamReader, c elliptic.Curve, hash []byte) (r, s *big.Int, err error) { + if functionCode, blockSize, ok := canUseKDSA(c); ok { + e := hashToInt(hash, c) + for { + var k *big.Int + k, err = randFieldElement(c, *csprng) + if err != nil { + return nil, nil, err + } + + // The parameter block looks like the following for sign. + // +---------------------+ + // | Signature(R) | + // +---------------------+ + // | Signature(S) | + // +---------------------+ + // | Hashed Message | + // +---------------------+ + // | Private Key | + // +---------------------+ + // | Random Number | + // +---------------------+ + // | | + // | ... | + // | | + // +---------------------+ + // The common components(signatureR, signatureS, hashedMessage, privateKey and + // random number) each takes block size of bytes. The block size is different for + // different curves and is set by canUseKDSA function. + var params [4096]byte + + startingOffset := 2 * blockSize // Set the starting location for copying + // Copy content into the parameter block. In the sign case, + // we copy hashed message, private key and random number into + // the parameter block. Since those are consecutive components in the parameter + // block, we use a for loop here. + for i, v := range []*big.Int{e, priv.D, k} { + startPosition := startingOffset + i*blockSize + endPosition := startPosition + blockSize + zeroExtendAndCopy(params[startPosition:endPosition], v.Bytes(), blockSize) + } + + // Convert verify function code into a sign function code by adding 8. + // We also need to set the 'deterministic' bit in the function code, by + // adding 128, in order to stop the instruction using its own random number + // generator in addition to the random number we supply. + switch kdsa(functionCode+136, ¶ms) { + case 0: // success + r = new(big.Int) + r.SetBytes(params[:blockSize]) + s = new(big.Int) + s.SetBytes(params[blockSize : 2*blockSize]) + return + case 1: // error + return nil, nil, errZeroParam + case 2: // retry + continue + } + panic("unreachable") + } + } + return signGeneric(priv, csprng, c, hash) +} + +func verify(pub *PublicKey, c elliptic.Curve, hash []byte, r, s *big.Int) bool { + if functionCode, blockSize, ok := canUseKDSA(c); ok { + e := hashToInt(hash, c) + // The parameter block looks like the following for verify: + // +---------------------+ + // | Signature(R) | + // +---------------------+ + // | Signature(S) | + // +---------------------+ + // | Hashed Message | + // +---------------------+ + // | Public Key X | + // +---------------------+ + // | Public Key Y | + // +---------------------+ + // | | + // | ... | + // | | + // +---------------------+ + // The common components(signatureR, signatureS, hashed message, public key X, + // and public key Y) each takes block size of bytes. The block size is different for + // different curves and is set by canUseKDSA function. + var params [4096]byte + + // Copy content into the parameter block. In the verify case, + // we copy signature (r), signature(s), hashed message, public key x component, + // and public key y component into the parameter block. + // Since those are consecutive components in the parameter block, we use a for loop here. + for i, v := range []*big.Int{r, s, e, pub.X, pub.Y} { + startPosition := i * blockSize + endPosition := startPosition + blockSize + zeroExtendAndCopy(params[startPosition:endPosition], v.Bytes(), blockSize) + } + + return kdsa(functionCode, ¶ms) == 0 + } + return verifyGeneric(pub, c, hash, r, s) +} diff --git a/libgo/go/crypto/ecdsa/ecdsa_s390x_test.go b/libgo/go/crypto/ecdsa/ecdsa_s390x_test.go new file mode 100644 index 00000000000..4fc6dfbe2f9 --- /dev/null +++ b/libgo/go/crypto/ecdsa/ecdsa_s390x_test.go @@ -0,0 +1,34 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore_for_gccgo +// +build s390x + +package ecdsa + +import ( + "crypto/elliptic" + "testing" +) + +func TestNoAsm(t *testing.T) { + curves := [...]elliptic.Curve{ + elliptic.P256(), + elliptic.P384(), + elliptic.P521(), + } + + for _, curve := range curves { + // override the name of the curve to stop the assembly path being taken + params := *curve.Params() + name := params.Name + params.Name = name + "_GENERIC_OVERRIDE" + + testKeyGeneration(t, ¶ms, name) + testSignAndVerify(t, ¶ms, name) + testNonceSafety(t, ¶ms, name) + testINDCCA(t, ¶ms, name) + testNegativeInputs(t, ¶ms, name) + } +} diff --git a/libgo/go/crypto/ecdsa/ecdsa_test.go b/libgo/go/crypto/ecdsa/ecdsa_test.go index 6284e06bd43..0c1ff6d2008 100644 --- a/libgo/go/crypto/ecdsa/ecdsa_test.go +++ b/libgo/go/crypto/ecdsa/ecdsa_test.go @@ -131,6 +131,36 @@ func TestSignAndVerify(t *testing.T) { testSignAndVerify(t, elliptic.P521(), "p521") } +func testSignAndVerifyASN1(t *testing.T, c elliptic.Curve, tag string) { + priv, _ := GenerateKey(c, rand.Reader) + + hashed := []byte("testing") + sig, err := SignASN1(rand.Reader, priv, hashed) + if err != nil { + t.Errorf("%s: error signing: %s", tag, err) + return + } + + if !VerifyASN1(&priv.PublicKey, hashed, sig) { + t.Errorf("%s: VerifyASN1 failed", tag) + } + + hashed[0] ^= 0xff + if VerifyASN1(&priv.PublicKey, hashed, sig) { + t.Errorf("%s: VerifyASN1 always works!", tag) + } +} + +func TestSignAndVerifyASN1(t *testing.T) { + testSignAndVerifyASN1(t, elliptic.P224(), "p224") + if testing.Short() { + return + } + testSignAndVerifyASN1(t, elliptic.P256(), "p256") + testSignAndVerifyASN1(t, elliptic.P384(), "p384") + testSignAndVerifyASN1(t, elliptic.P521(), "p521") +} + func testNonceSafety(t *testing.T, c elliptic.Curve, tag string) { priv, _ := GenerateKey(c, rand.Reader) diff --git a/libgo/go/crypto/ecdsa/equal_test.go b/libgo/go/crypto/ecdsa/equal_test.go new file mode 100644 index 00000000000..53ac8504c2f --- /dev/null +++ b/libgo/go/crypto/ecdsa/equal_test.go @@ -0,0 +1,75 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ecdsa_test + +import ( + "crypto" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/x509" + "testing" +) + +func testEqual(t *testing.T, c elliptic.Curve) { + private, _ := ecdsa.GenerateKey(c, rand.Reader) + public := &private.PublicKey + + if !public.Equal(public) { + t.Errorf("public key is not equal to itself: %v", public) + } + if !public.Equal(crypto.Signer(private).Public().(*ecdsa.PublicKey)) { + t.Errorf("private.Public() is not Equal to public: %q", public) + } + if !private.Equal(private) { + t.Errorf("private key is not equal to itself: %v", private) + } + + enc, err := x509.MarshalPKCS8PrivateKey(private) + if err != nil { + t.Fatal(err) + } + decoded, err := x509.ParsePKCS8PrivateKey(enc) + if err != nil { + t.Fatal(err) + } + if !public.Equal(decoded.(crypto.Signer).Public()) { + t.Errorf("public key is not equal to itself after decoding: %v", public) + } + if !private.Equal(decoded) { + t.Errorf("private key is not equal to itself after decoding: %v", private) + } + + other, _ := ecdsa.GenerateKey(c, rand.Reader) + if public.Equal(other.Public()) { + t.Errorf("different public keys are Equal") + } + if private.Equal(other) { + t.Errorf("different private keys are Equal") + } + + // Ensure that keys with the same coordinates but on different curves + // aren't considered Equal. + differentCurve := &ecdsa.PublicKey{} + *differentCurve = *public // make a copy of the public key + if differentCurve.Curve == elliptic.P256() { + differentCurve.Curve = elliptic.P224() + } else { + differentCurve.Curve = elliptic.P256() + } + if public.Equal(differentCurve) { + t.Errorf("public keys with different curves are Equal") + } +} + +func TestEqual(t *testing.T) { + t.Run("P224", func(t *testing.T) { testEqual(t, elliptic.P224()) }) + if testing.Short() { + return + } + t.Run("P256", func(t *testing.T) { testEqual(t, elliptic.P256()) }) + t.Run("P384", func(t *testing.T) { testEqual(t, elliptic.P384()) }) + t.Run("P521", func(t *testing.T) { testEqual(t, elliptic.P521()) }) +} diff --git a/libgo/go/crypto/ecdsa/example_test.go b/libgo/go/crypto/ecdsa/example_test.go index 7c7fb1b27b1..a9e7a03de73 100644 --- a/libgo/go/crypto/ecdsa/example_test.go +++ b/libgo/go/crypto/ecdsa/example_test.go @@ -23,12 +23,12 @@ func Example() { msg := "hello, world" hash := sha256.Sum256([]byte(msg)) - r, s, err := ecdsa.Sign(rand.Reader, privateKey, hash[:]) + sig, err := ecdsa.SignASN1(rand.Reader, privateKey, hash[:]) if err != nil { panic(err) } - fmt.Printf("signature: (0x%x, 0x%x)\n", r, s) + fmt.Printf("signature: %x\n", sig) - valid := ecdsa.Verify(&privateKey.PublicKey, hash[:], r, s) + valid := ecdsa.VerifyASN1(&privateKey.PublicKey, hash[:], sig) fmt.Println("signature verified:", valid) } diff --git a/libgo/go/crypto/ed25519/ed25519.go b/libgo/go/crypto/ed25519/ed25519.go index dcb4f9544f9..5766970f827 100644 --- a/libgo/go/crypto/ed25519/ed25519.go +++ b/libgo/go/crypto/ed25519/ed25519.go @@ -40,6 +40,18 @@ const ( // PublicKey is the type of Ed25519 public keys. type PublicKey []byte +// Any methods implemented on PublicKey might need to also be implemented on +// PrivateKey, as the latter embeds the former and will expose its methods. + +// Equal reports whether pub and x have the same value. +func (pub PublicKey) Equal(x crypto.PublicKey) bool { + xx, ok := x.(PublicKey) + if !ok { + return false + } + return bytes.Equal(pub, xx) +} + // PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer. type PrivateKey []byte @@ -50,6 +62,15 @@ func (priv PrivateKey) Public() crypto.PublicKey { return PublicKey(publicKey) } +// Equal reports whether priv and x have the same value. +func (priv PrivateKey) Equal(x crypto.PrivateKey) bool { + xx, ok := x.(PrivateKey) + if !ok { + return false + } + return bytes.Equal(priv, xx) +} + // Seed returns the private key seed corresponding to priv. It is provided for // interoperability with RFC 8032. RFC 8032's private keys correspond to seeds // in this package. @@ -133,7 +154,7 @@ func Sign(privateKey PrivateKey, message []byte) []byte { return signature } -func sign(signature, privateKey, message []byte) { +func signGeneric(signature, privateKey, message []byte) { if l := len(privateKey); l != PrivateKeySize { panic("ed25519: bad private key length: " + strconv.Itoa(l)) } @@ -180,6 +201,10 @@ func sign(signature, privateKey, message []byte) { // Verify reports whether sig is a valid signature of message by publicKey. It // will panic if len(publicKey) is not PublicKeySize. func Verify(publicKey PublicKey, message, sig []byte) bool { + return verify(publicKey, message, sig) +} + +func verifyGeneric(publicKey PublicKey, message, sig []byte) bool { if l := len(publicKey); l != PublicKeySize { panic("ed25519: bad public key length: " + strconv.Itoa(l)) } diff --git a/libgo/go/crypto/ed25519/ed25519_noasm.go b/libgo/go/crypto/ed25519/ed25519_noasm.go new file mode 100644 index 00000000000..4425bb2766d --- /dev/null +++ b/libgo/go/crypto/ed25519/ed25519_noasm.go @@ -0,0 +1,15 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// -build !s390x + +package ed25519 + +func sign(signature, privateKey, message []byte) { + signGeneric(signature, privateKey, message) +} + +func verify(publicKey PublicKey, message, sig []byte) bool { + return verifyGeneric(publicKey, message, sig) +} diff --git a/libgo/go/crypto/ed25519/ed25519_s390x.go b/libgo/go/crypto/ed25519/ed25519_s390x.go new file mode 100644 index 00000000000..d7e5243884e --- /dev/null +++ b/libgo/go/crypto/ed25519/ed25519_s390x.go @@ -0,0 +1,53 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore_for_gccgo + +package ed25519 + +import ( + "internal/cpu" + "strconv" +) + +//go:noescape +func kdsaSign(message, signature, privateKey []byte) bool + +//go:noescape +func kdsaVerify(message, signature, publicKey []byte) bool + +// sign does a check to see if hardware has Edwards Curve instruction available. +// If it does, use the hardware implementation. Otherwise, use the generic version. +func sign(signature, privateKey, message []byte) { + if cpu.S390X.HasEDDSA { + if l := len(privateKey); l != PrivateKeySize { + panic("ed25519: bad private key length: " + strconv.Itoa(l)) + } + + ret := kdsaSign(message, signature, privateKey[:32]) + if !ret { + panic("ed25519: kdsa sign has a failure") + } + return + } + signGeneric(signature, privateKey, message) +} + +// verify does a check to see if hardware has Edwards Curve instruction available. +// If it does, use the hardware implementation for eddsa verfication. Otherwise, the generic +// version is used +func verify(publicKey PublicKey, message, sig []byte) bool { + if cpu.S390X.HasEDDSA { + if l := len(publicKey); l != PublicKeySize { + panic("ed25519: bad public key length: " + strconv.Itoa(l)) + } + + if len(sig) != SignatureSize || sig[63]&224 != 0 { + return false + } + + return kdsaVerify(message, sig, publicKey) + } + return verifyGeneric(publicKey, message, sig) +} diff --git a/libgo/go/crypto/ed25519/ed25519_test.go b/libgo/go/crypto/ed25519/ed25519_test.go index cacd281f1cc..f77d463721c 100644 --- a/libgo/go/crypto/ed25519/ed25519_test.go +++ b/libgo/go/crypto/ed25519/ed25519_test.go @@ -26,6 +26,14 @@ func (zeroReader) Read(buf []byte) (int, error) { return len(buf), nil } +// signGenericWrapper is identical to Sign except that it unconditionally calls signGeneric directly +// rather than going through the sign function that might call assembly code. +func signGenericWrapper(privateKey PrivateKey, msg []byte) []byte { + sig := make([]byte, SignatureSize) + signGeneric(sig, privateKey, msg) + return sig +} + func TestUnmarshalMarshal(t *testing.T) { pub, _, _ := GenerateKey(rand.Reader) @@ -45,22 +53,33 @@ func TestUnmarshalMarshal(t *testing.T) { } func TestSignVerify(t *testing.T) { + t.Run("Generic", func(t *testing.T) { testSignVerify(t, signGenericWrapper, verifyGeneric) }) + t.Run("Native", func(t *testing.T) { testSignVerify(t, Sign, Verify) }) +} + +func testSignVerify(t *testing.T, signImpl func(privateKey PrivateKey, message []byte) []byte, + verifyImpl func(publicKey PublicKey, message, sig []byte) bool) { var zero zeroReader public, private, _ := GenerateKey(zero) message := []byte("test message") - sig := Sign(private, message) - if !Verify(public, message, sig) { + sig := signImpl(private, message) + if !verifyImpl(public, message, sig) { t.Errorf("valid signature rejected") } wrongMessage := []byte("wrong message") - if Verify(public, wrongMessage, sig) { + if verifyImpl(public, wrongMessage, sig) { t.Errorf("signature of different message accepted") } } func TestCryptoSigner(t *testing.T) { + t.Run("Generic", func(t *testing.T) { testCryptoSigner(t, verifyGeneric) }) + t.Run("Native", func(t *testing.T) { testCryptoSigner(t, Verify) }) +} + +func testCryptoSigner(t *testing.T, verifyImpl func(publicKey PublicKey, message, sig []byte) bool) { var zero zeroReader public, private, _ := GenerateKey(zero) @@ -83,12 +102,40 @@ func TestCryptoSigner(t *testing.T) { t.Fatalf("error from Sign(): %s", err) } - if !Verify(public, message, signature) { + if !verifyImpl(public, message, signature) { t.Errorf("Verify failed on signature from Sign()") } } +func TestEqual(t *testing.T) { + public, private, _ := GenerateKey(rand.Reader) + + if !public.Equal(public) { + t.Errorf("public key is not equal to itself: %q", public) + } + if !public.Equal(crypto.Signer(private).Public()) { + t.Errorf("private.Public() is not Equal to public: %q", public) + } + if !private.Equal(private) { + t.Errorf("private key is not equal to itself: %q", private) + } + + otherPub, otherPriv, _ := GenerateKey(rand.Reader) + if public.Equal(otherPub) { + t.Errorf("different public keys are Equal") + } + if private.Equal(otherPriv) { + t.Errorf("different private keys are Equal") + } +} + func TestGolden(t *testing.T) { + t.Run("Generic", func(t *testing.T) { testGolden(t, signGenericWrapper, verifyGeneric) }) + t.Run("Native", func(t *testing.T) { testGolden(t, Sign, Verify) }) +} + +func testGolden(t *testing.T, signImpl func(privateKey PrivateKey, message []byte) []byte, + verifyImpl func(publicKey PublicKey, message, sig []byte) bool) { // sign.input.gz is a selection of test cases from // https://ed25519.cr.yp.to/python/sign.input testDataZ, err := os.Open("testdata/sign.input.gz") @@ -130,12 +177,12 @@ func TestGolden(t *testing.T) { copy(priv[:], privBytes) copy(priv[32:], pubKey) - sig2 := Sign(priv[:], msg) + sig2 := signImpl(priv[:], msg) if !bytes.Equal(sig, sig2[:]) { t.Errorf("different signature result on line %d: %x vs %x", lineNo, sig, sig2) } - if !Verify(pubKey, msg, sig2) { + if !verifyImpl(pubKey, msg, sig2) { t.Errorf("signature failed to verify on line %d", lineNo) } @@ -159,6 +206,11 @@ func TestGolden(t *testing.T) { } func TestMalleability(t *testing.T) { + t.Run("Generic", func(t *testing.T) { testMalleability(t, verifyGeneric) }) + t.Run("Native", func(t *testing.T) { testMalleability(t, Verify) }) +} + +func testMalleability(t *testing.T, verifyImpl func(publicKey PublicKey, message, sig []byte) bool) { // https://tools.ietf.org/html/rfc8032#section-5.1.7 adds an additional test // that s be in [0, order). This prevents someone from adding a multiple of // order to s and obtaining a second valid signature for the same message. @@ -177,7 +229,7 @@ func TestMalleability(t *testing.T) { 0xb1, 0x08, 0xc3, 0xbd, 0xae, 0x36, 0x9e, 0xf5, 0x49, 0xfa, } - if Verify(publicKey, msg, sig) { + if verifyImpl(publicKey, msg, sig) { t.Fatal("non-canonical signature accepted") } } diff --git a/libgo/go/crypto/elliptic/elliptic.go b/libgo/go/crypto/elliptic/elliptic.go index e2f71cdb63b..f93dc16419f 100644 --- a/libgo/go/crypto/elliptic/elliptic.go +++ b/libgo/go/crypto/elliptic/elliptic.go @@ -20,7 +20,10 @@ import ( ) // A Curve represents a short-form Weierstrass curve with a=-3. -// See https://www.hyperelliptic.org/EFD/g1p/auto-shortw.html +// +// Note that the point at infinity (0, 0) is not considered on the curve, and +// although it can be returned by Add, Double, ScalarMult, or ScalarBaseMult, it +// can't be marshaled or unmarshaled, and IsOnCurve will return false for it. type Curve interface { // Params returns the parameters for the curve. Params() *CurveParams @@ -52,11 +55,8 @@ func (curve *CurveParams) Params() *CurveParams { return curve } -func (curve *CurveParams) IsOnCurve(x, y *big.Int) bool { - // y² = x³ - 3x + b - y2 := new(big.Int).Mul(y, y) - y2.Mod(y2, curve.P) - +// polynomial returns x³ - 3x + b. +func (curve *CurveParams) polynomial(x *big.Int) *big.Int { x3 := new(big.Int).Mul(x, x) x3.Mul(x3, x) @@ -67,7 +67,15 @@ func (curve *CurveParams) IsOnCurve(x, y *big.Int) bool { x3.Add(x3, curve.B) x3.Mod(x3, curve.P) - return x3.Cmp(y2) == 0 + return x3 +} + +func (curve *CurveParams) IsOnCurve(x, y *big.Int) bool { + // y² = x³ - 3x + b + y2 := new(big.Int).Mul(y, y) + y2.Mod(y2, curve.P) + + return curve.polynomial(x).Cmp(y2) == 0 } // zForAffine returns a Jacobian Z value for the affine point (x, y). If x and @@ -277,7 +285,7 @@ var mask = []byte{0xff, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f} func GenerateKey(curve Curve, rand io.Reader) (priv []byte, x, y *big.Int, err error) { N := curve.Params().N bitSize := N.BitLen() - byteLen := (bitSize + 7) >> 3 + byteLen := (bitSize + 7) / 8 priv = make([]byte, byteLen) for x == nil { @@ -302,30 +310,40 @@ func GenerateKey(curve Curve, rand io.Reader) (priv []byte, x, y *big.Int, err e return } -// Marshal converts a point into the uncompressed form specified in section 4.3.6 of ANSI X9.62. +// Marshal converts a point on the curve into the uncompressed form specified in +// section 4.3.6 of ANSI X9.62. func Marshal(curve Curve, x, y *big.Int) []byte { - byteLen := (curve.Params().BitSize + 7) >> 3 + byteLen := (curve.Params().BitSize + 7) / 8 ret := make([]byte, 1+2*byteLen) ret[0] = 4 // uncompressed point - xBytes := x.Bytes() - copy(ret[1+byteLen-len(xBytes):], xBytes) - yBytes := y.Bytes() - copy(ret[1+2*byteLen-len(yBytes):], yBytes) + x.FillBytes(ret[1 : 1+byteLen]) + y.FillBytes(ret[1+byteLen : 1+2*byteLen]) + return ret } +// MarshalCompressed converts a point on the curve into the compressed form +// specified in section 4.3.6 of ANSI X9.62. +func MarshalCompressed(curve Curve, x, y *big.Int) []byte { + byteLen := (curve.Params().BitSize + 7) / 8 + compressed := make([]byte, 1+byteLen) + compressed[0] = byte(y.Bit(0)) | 2 + x.FillBytes(compressed[1:]) + return compressed +} + // Unmarshal converts a point, serialized by Marshal, into an x, y pair. // It is an error if the point is not in uncompressed form or is not on the curve. // On error, x = nil. func Unmarshal(curve Curve, data []byte) (x, y *big.Int) { - byteLen := (curve.Params().BitSize + 7) >> 3 + byteLen := (curve.Params().BitSize + 7) / 8 if len(data) != 1+2*byteLen { - return + return nil, nil } if data[0] != 4 { // uncompressed form - return + return nil, nil } p := curve.Params().P x = new(big.Int).SetBytes(data[1 : 1+byteLen]) @@ -339,6 +357,37 @@ func Unmarshal(curve Curve, data []byte) (x, y *big.Int) { return } +// UnmarshalCompressed converts a point, serialized by MarshalCompressed, into an x, y pair. +// It is an error if the point is not in compressed form or is not on the curve. +// On error, x = nil. +func UnmarshalCompressed(curve Curve, data []byte) (x, y *big.Int) { + byteLen := (curve.Params().BitSize + 7) / 8 + if len(data) != 1+byteLen { + return nil, nil + } + if data[0] != 2 && data[0] != 3 { // compressed form + return nil, nil + } + p := curve.Params().P + x = new(big.Int).SetBytes(data[1:]) + if x.Cmp(p) >= 0 { + return nil, nil + } + // y² = x³ - 3x + b + y = curve.Params().polynomial(x) + y = y.ModSqrt(y, p) + if y == nil { + return nil, nil + } + if byte(y.Bit(0)) != data[0]&1 { + y.Neg(y).Mod(y, p) + } + if !curve.IsOnCurve(x, y) { + return nil, nil + } + return +} + var initonce sync.Once var p384 *CurveParams var p521 *CurveParams diff --git a/libgo/go/crypto/elliptic/elliptic_test.go b/libgo/go/crypto/elliptic/elliptic_test.go index 09c5483520e..e80e7731aaa 100644 --- a/libgo/go/crypto/elliptic/elliptic_test.go +++ b/libgo/go/crypto/elliptic/elliptic_test.go @@ -5,6 +5,7 @@ package elliptic import ( + "bytes" "crypto/rand" "encoding/hex" "fmt" @@ -417,41 +418,62 @@ func TestP256Mult(t *testing.T) { } } -func TestInfinity(t *testing.T) { - tests := []struct { - name string - curve Curve - }{ - {"p224", P224()}, - {"p256", P256()}, +func testInfinity(t *testing.T, curve Curve) { + _, x, y, _ := GenerateKey(curve, rand.Reader) + x, y = curve.ScalarMult(x, y, curve.Params().N.Bytes()) + if x.Sign() != 0 || y.Sign() != 0 { + t.Errorf("x^q != ∞") } - for _, test := range tests { - curve := test.curve - x, y := curve.ScalarBaseMult(nil) - if x.Sign() != 0 || y.Sign() != 0 { - t.Errorf("%s: x^0 != ∞", test.name) - } + x, y = curve.ScalarBaseMult([]byte{0}) + if x.Sign() != 0 || y.Sign() != 0 { + t.Errorf("b^0 != ∞") x.SetInt64(0) y.SetInt64(0) + } - x2, y2 := curve.Double(x, y) - if x2.Sign() != 0 || y2.Sign() != 0 { - t.Errorf("%s: 2∞ != ∞", test.name) - } + x2, y2 := curve.Double(x, y) + if x2.Sign() != 0 || y2.Sign() != 0 { + t.Errorf("2∞ != ∞") + } - baseX := curve.Params().Gx - baseY := curve.Params().Gy + baseX := curve.Params().Gx + baseY := curve.Params().Gy - x3, y3 := curve.Add(baseX, baseY, x, y) - if x3.Cmp(baseX) != 0 || y3.Cmp(baseY) != 0 { - t.Errorf("%s: x+∞ != x", test.name) - } + x3, y3 := curve.Add(baseX, baseY, x, y) + if x3.Cmp(baseX) != 0 || y3.Cmp(baseY) != 0 { + t.Errorf("x+∞ != x") + } - x4, y4 := curve.Add(x, y, baseX, baseY) - if x4.Cmp(baseX) != 0 || y4.Cmp(baseY) != 0 { - t.Errorf("%s: ∞+x != x", test.name) - } + x4, y4 := curve.Add(x, y, baseX, baseY) + if x4.Cmp(baseX) != 0 || y4.Cmp(baseY) != 0 { + t.Errorf("∞+x != x") + } + + if curve.IsOnCurve(x, y) { + t.Errorf("IsOnCurve(∞) == true") + } +} + +func TestInfinity(t *testing.T) { + tests := []struct { + name string + curve Curve + }{ + {"P-224", P224()}, + {"P-256", P256()}, + {"P-256/Generic", P256().Params()}, + {"P-384", P384()}, + {"P-521", P521()}, + } + if testing.Short() { + tests = tests[:1] + } + for _, test := range tests { + curve := test.curve + t.Run(test.name, func(t *testing.T) { + testInfinity(t, curve) + }) } } @@ -628,3 +650,74 @@ func TestUnmarshalToLargeCoordinates(t *testing.T) { t.Errorf("Unmarshal accepts invalid Y coordinate") } } + +func TestMarshalCompressed(t *testing.T) { + t.Run("P-256/03", func(t *testing.T) { + data, _ := hex.DecodeString("031e3987d9f9ea9d7dd7155a56a86b2009e1e0ab332f962d10d8beb6406ab1ad79") + x, _ := new(big.Int).SetString("13671033352574878777044637384712060483119675368076128232297328793087057702265", 10) + y, _ := new(big.Int).SetString("66200849279091436748794323380043701364391950689352563629885086590854940586447", 10) + testMarshalCompressed(t, P256(), x, y, data) + }) + t.Run("P-256/02", func(t *testing.T) { + data, _ := hex.DecodeString("021e3987d9f9ea9d7dd7155a56a86b2009e1e0ab332f962d10d8beb6406ab1ad79") + x, _ := new(big.Int).SetString("13671033352574878777044637384712060483119675368076128232297328793087057702265", 10) + y, _ := new(big.Int).SetString("49591239931264812013903123569363872165694192725937750565648544718012157267504", 10) + testMarshalCompressed(t, P256(), x, y, data) + }) + + t.Run("Invalid", func(t *testing.T) { + data, _ := hex.DecodeString("02fd4bf61763b46581fd9174d623516cf3c81edd40e29ffa2777fb6cb0ae3ce535") + X, Y := UnmarshalCompressed(P256(), data) + if X != nil || Y != nil { + t.Error("expected an error for invalid encoding") + } + }) + + if testing.Short() { + t.Skip("skipping other curves on short test") + } + + t.Run("P-224", func(t *testing.T) { + _, x, y, err := GenerateKey(P224(), rand.Reader) + if err != nil { + t.Fatal(err) + } + testMarshalCompressed(t, P224(), x, y, nil) + }) + t.Run("P-384", func(t *testing.T) { + _, x, y, err := GenerateKey(P384(), rand.Reader) + if err != nil { + t.Fatal(err) + } + testMarshalCompressed(t, P384(), x, y, nil) + }) + t.Run("P-521", func(t *testing.T) { + _, x, y, err := GenerateKey(P521(), rand.Reader) + if err != nil { + t.Fatal(err) + } + testMarshalCompressed(t, P521(), x, y, nil) + }) +} + +func testMarshalCompressed(t *testing.T, curve Curve, x, y *big.Int, want []byte) { + if !curve.IsOnCurve(x, y) { + t.Fatal("invalid test point") + } + got := MarshalCompressed(curve, x, y) + if want != nil && !bytes.Equal(got, want) { + t.Errorf("got unexpected MarshalCompressed result: got %x, want %x", got, want) + } + + X, Y := UnmarshalCompressed(curve, got) + if X == nil || Y == nil { + t.Fatalf("UnmarshalCompressed failed unexpectedly") + } + + if !curve.IsOnCurve(X, Y) { + t.Error("UnmarshalCompressed returned a point not on the curve") + } + if X.Cmp(x) != 0 || Y.Cmp(y) != 0 { + t.Errorf("point did not round-trip correctly: got (%v, %v), want (%v, %v)", X, Y, x, y) + } +} diff --git a/libgo/go/crypto/hmac/hmac.go b/libgo/go/crypto/hmac/hmac.go index 801ece67ae4..a6ba71c2756 100644 --- a/libgo/go/crypto/hmac/hmac.go +++ b/libgo/go/crypto/hmac/hmac.go @@ -34,18 +34,36 @@ import ( // opad = 0x5c byte repeated for key length // hmac = H([key ^ opad] H([key ^ ipad] text)) +// Marshalable is the combination of encoding.BinaryMarshaler and +// encoding.BinaryUnmarshaler. Their method definitions are repeated here to +// avoid a dependency on the encoding package. +type marshalable interface { + MarshalBinary() ([]byte, error) + UnmarshalBinary([]byte) error +} + type hmac struct { - size int - blocksize int opad, ipad []byte outer, inner hash.Hash + + // If marshaled is true, then opad and ipad do not contain a padded + // copy of the key, but rather the marshaled state of outer/inner after + // opad/ipad has been fed into it. + marshaled bool } func (h *hmac) Sum(in []byte) []byte { origLen := len(in) in = h.inner.Sum(in) - h.outer.Reset() - h.outer.Write(h.opad) + + if h.marshaled { + if err := h.outer.(marshalable).UnmarshalBinary(h.opad); err != nil { + panic(err) + } + } else { + h.outer.Reset() + h.outer.Write(h.opad) + } h.outer.Write(in[origLen:]) return h.outer.Sum(in[:origLen]) } @@ -54,13 +72,51 @@ func (h *hmac) Write(p []byte) (n int, err error) { return h.inner.Write(p) } -func (h *hmac) Size() int { return h.size } - -func (h *hmac) BlockSize() int { return h.blocksize } +func (h *hmac) Size() int { return h.outer.Size() } +func (h *hmac) BlockSize() int { return h.inner.BlockSize() } func (h *hmac) Reset() { + if h.marshaled { + if err := h.inner.(marshalable).UnmarshalBinary(h.ipad); err != nil { + panic(err) + } + return + } + h.inner.Reset() h.inner.Write(h.ipad) + + // If the underlying hash is marshalable, we can save some time by + // saving a copy of the hash state now, and restoring it on future + // calls to Reset and Sum instead of writing ipad/opad every time. + // + // If either hash is unmarshalable for whatever reason, + // it's safe to bail out here. + marshalableInner, innerOK := h.inner.(marshalable) + if !innerOK { + return + } + marshalableOuter, outerOK := h.outer.(marshalable) + if !outerOK { + return + } + + imarshal, err := marshalableInner.MarshalBinary() + if err != nil { + return + } + + h.outer.Reset() + h.outer.Write(h.opad) + omarshal, err := marshalableOuter.MarshalBinary() + if err != nil { + return + } + + // Marshaling succeeded; save the marshaled state for later + h.ipad = imarshal + h.opad = omarshal + h.marshaled = true } // New returns a new HMAC hash using the given hash.Hash type and key. @@ -71,11 +127,10 @@ func New(h func() hash.Hash, key []byte) hash.Hash { hm := new(hmac) hm.outer = h() hm.inner = h() - hm.size = hm.inner.Size() - hm.blocksize = hm.inner.BlockSize() - hm.ipad = make([]byte, hm.blocksize) - hm.opad = make([]byte, hm.blocksize) - if len(key) > hm.blocksize { + blocksize := hm.inner.BlockSize() + hm.ipad = make([]byte, blocksize) + hm.opad = make([]byte, blocksize) + if len(key) > blocksize { // If key is too big, hash it. hm.outer.Write(key) key = hm.outer.Sum(nil) @@ -89,6 +144,7 @@ func New(h func() hash.Hash, key []byte) hash.Hash { hm.opad[i] ^= 0x5c } hm.inner.Write(hm.ipad) + return hm } diff --git a/libgo/go/crypto/hmac/hmac_test.go b/libgo/go/crypto/hmac/hmac_test.go index eea345edb63..453bfb3b7fd 100644 --- a/libgo/go/crypto/hmac/hmac_test.go +++ b/libgo/go/crypto/hmac/hmac_test.go @@ -529,7 +529,7 @@ func TestHMAC(t *testing.T) { if b := h.BlockSize(); b != tt.blocksize { t.Errorf("BlockSize: got %v, want %v", b, tt.blocksize) } - for j := 0; j < 2; j++ { + for j := 0; j < 4; j++ { n, err := h.Write(tt.in) if n != len(tt.in) || err != nil { t.Errorf("test %d.%d: Write(%d) = %d, %v", i, j, len(tt.in), n, err) @@ -546,10 +546,21 @@ func TestHMAC(t *testing.T) { // Second iteration: make sure reset works. h.Reset() + + // Third and fourth iteration: make sure hmac works on + // hashes without MarshalBinary/UnmarshalBinary + if j == 1 { + h = New(func() hash.Hash { return justHash{tt.hash()} }, tt.key) + } } } } +// justHash implements just the hash.Hash methods and nothing else +type justHash struct { + hash.Hash +} + func TestEqual(t *testing.T) { a := []byte("test") b := []byte("test1") diff --git a/libgo/go/crypto/rsa/equal_test.go b/libgo/go/crypto/rsa/equal_test.go new file mode 100644 index 00000000000..90f4bf94753 --- /dev/null +++ b/libgo/go/crypto/rsa/equal_test.go @@ -0,0 +1,51 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package rsa_test + +import ( + "crypto" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "testing" +) + +func TestEqual(t *testing.T) { + private, _ := rsa.GenerateKey(rand.Reader, 512) + public := &private.PublicKey + + if !public.Equal(public) { + t.Errorf("public key is not equal to itself: %v", public) + } + if !public.Equal(crypto.Signer(private).Public().(*rsa.PublicKey)) { + t.Errorf("private.Public() is not Equal to public: %q", public) + } + if !private.Equal(private) { + t.Errorf("private key is not equal to itself: %v", private) + } + + enc, err := x509.MarshalPKCS8PrivateKey(private) + if err != nil { + t.Fatal(err) + } + decoded, err := x509.ParsePKCS8PrivateKey(enc) + if err != nil { + t.Fatal(err) + } + if !public.Equal(decoded.(crypto.Signer).Public()) { + t.Errorf("public key is not equal to itself after decoding: %v", public) + } + if !private.Equal(decoded) { + t.Errorf("private key is not equal to itself after decoding: %v", private) + } + + other, _ := rsa.GenerateKey(rand.Reader, 512) + if public.Equal(other.Public()) { + t.Errorf("different public keys are Equal") + } + if private.Equal(other) { + t.Errorf("different private keys are Equal") + } +} diff --git a/libgo/go/crypto/rsa/example_test.go b/libgo/go/crypto/rsa/example_test.go index 1435b701460..ce5c2d91cd4 100644 --- a/libgo/go/crypto/rsa/example_test.go +++ b/libgo/go/crypto/rsa/example_test.go @@ -27,7 +27,7 @@ import ( // exponentiation is larger than the modulus. (Otherwise it could be // decrypted with a square-root.) // -// In these designs, when using PKCS#1 v1.5, it's vitally important to +// In these designs, when using PKCS #1 v1.5, it's vitally important to // avoid disclosing whether the received RSA message was well-formed // (that is, whether the result of decrypting is a correctly padded // message) because this leaks secret information. diff --git a/libgo/go/crypto/rsa/pkcs1v15.go b/libgo/go/crypto/rsa/pkcs1v15.go index 37790acb986..0cbd6d00456 100644 --- a/libgo/go/crypto/rsa/pkcs1v15.go +++ b/libgo/go/crypto/rsa/pkcs1v15.go @@ -14,9 +14,9 @@ import ( "crypto/internal/randutil" ) -// This file implements encryption and decryption using PKCS#1 v1.5 padding. +// This file implements encryption and decryption using PKCS #1 v1.5 padding. -// PKCS1v15DecrypterOpts is for passing options to PKCS#1 v1.5 decryption using +// PKCS1v15DecrypterOpts is for passing options to PKCS #1 v1.5 decryption using // the crypto.Decrypter interface. type PKCS1v15DecryptOptions struct { // SessionKeyLen is the length of the session key that is being @@ -27,7 +27,7 @@ type PKCS1v15DecryptOptions struct { } // EncryptPKCS1v15 encrypts the given message with RSA and the padding -// scheme from PKCS#1 v1.5. The message must be no longer than the +// scheme from PKCS #1 v1.5. The message must be no longer than the // length of the public modulus minus 11 bytes. // // The rand parameter is used as a source of entropy to ensure that @@ -61,11 +61,10 @@ func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) ([]byte, error) m := new(big.Int).SetBytes(em) c := encrypt(new(big.Int), pub, m) - copyWithLeftPad(em, c.Bytes()) - return em, nil + return c.FillBytes(em), nil } -// DecryptPKCS1v15 decrypts a plaintext using RSA and the padding scheme from PKCS#1 v1.5. +// DecryptPKCS1v15 decrypts a plaintext using RSA and the padding scheme from PKCS #1 v1.5. // If rand != nil, it uses RSA blinding to avoid timing side-channel attacks. // // Note that whether this function returns an error or not discloses secret @@ -87,7 +86,7 @@ func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) ([]byt return out[index:], nil } -// DecryptPKCS1v15SessionKey decrypts a session key using RSA and the padding scheme from PKCS#1 v1.5. +// DecryptPKCS1v15SessionKey decrypts a session key using RSA and the padding scheme from PKCS #1 v1.5. // If rand != nil, it uses RSA blinding to avoid timing side-channel attacks. // It returns an error if the ciphertext is the wrong length or if the // ciphertext is greater than the public modulus. Otherwise, no error is @@ -150,7 +149,7 @@ func decryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (valid return } - em = leftPad(m.Bytes(), k) + em = m.FillBytes(make([]byte, k)) firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0) secondByteIsTwo := subtle.ConstantTimeByteEq(em[1], 2) @@ -217,7 +216,7 @@ var hashPrefixes = map[crypto.Hash][]byte{ } // SignPKCS1v15 calculates the signature of hashed using -// RSASSA-PKCS1-V1_5-SIGN from RSA PKCS#1 v1.5. Note that hashed must +// RSASSA-PKCS1-V1_5-SIGN from RSA PKCS #1 v1.5. Note that hashed must // be the result of hashing the input message using the given hash // function. If hash is zero, hashed is signed directly. This isn't // advisable except for interoperability. @@ -256,11 +255,10 @@ func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []b return nil, err } - copyWithLeftPad(em, c.Bytes()) - return em, nil + return c.FillBytes(em), nil } -// VerifyPKCS1v15 verifies an RSA PKCS#1 v1.5 signature. +// VerifyPKCS1v15 verifies an RSA PKCS #1 v1.5 signature. // hashed is the result of hashing the input message using the given hash // function and sig is the signature. A valid signature is indicated by // returning a nil error. If hash is zero then hashed is used directly. This @@ -277,9 +275,16 @@ func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) return ErrVerification } + // RFC 8017 Section 8.2.2: If the length of the signature S is not k + // octets (where k is the length in octets of the RSA modulus n), output + // "invalid signature" and stop. + if k != len(sig) { + return ErrVerification + } + c := new(big.Int).SetBytes(sig) m := encrypt(new(big.Int), pub, c) - em := leftPad(m.Bytes(), k) + em := m.FillBytes(make([]byte, k)) // EM = 0x00 || 0x01 || PS || 0x00 || T ok := subtle.ConstantTimeByteEq(em[0], 0) @@ -316,13 +321,3 @@ func pkcs1v15HashInfo(hash crypto.Hash, inLen int) (hashLen int, prefix []byte, } return } - -// copyWithLeftPad copies src to the end of dest, padding with zero bytes as -// needed. -func copyWithLeftPad(dest, src []byte) { - numPaddingBytes := len(dest) - len(src) - for i := 0; i < numPaddingBytes; i++ { - dest[i] = 0 - } - copy(dest[numPaddingBytes:], src) -} diff --git a/libgo/go/crypto/rsa/pkcs1v15_test.go b/libgo/go/crypto/rsa/pkcs1v15_test.go index 7e62560a04f..26b8c5f26fe 100644 --- a/libgo/go/crypto/rsa/pkcs1v15_test.go +++ b/libgo/go/crypto/rsa/pkcs1v15_test.go @@ -9,6 +9,7 @@ import ( "crypto" "crypto/rand" "crypto/sha1" + "crypto/sha256" "encoding/base64" "encoding/hex" "io" @@ -296,3 +297,20 @@ var rsaPrivateKey = &PrivateKey{ fromBase10("94560208308847015747498523884063394671606671904944666360068158221458669711639"), }, } + +func TestShortPKCS1v15Signature(t *testing.T) { + pub := &PublicKey{ + E: 65537, + N: fromBase10("8272693557323587081220342447407965471608219912416565371060697606400726784709760494166080686904546560026343451112103559482851304715739629410219358933351333"), + } + sig, err := hex.DecodeString("193a310d0dcf64094c6e3a00c8219b80ded70535473acff72c08e1222974bb24a93a535b1dc4c59fc0e65775df7ba2007dd20e9193f4c4025a18a7070aee93") + if err != nil { + t.Fatalf("failed to decode signature: %s", err) + } + + h := sha256.Sum256([]byte("hello")) + err = VerifyPKCS1v15(pub, crypto.SHA256, h[:], sig) + if err == nil { + t.Fatal("VerifyPKCS1v15 accepted a truncated signature") + } +} diff --git a/libgo/go/crypto/rsa/pss.go b/libgo/go/crypto/rsa/pss.go index 3ff0c2f4d00..b2adbedb28f 100644 --- a/libgo/go/crypto/rsa/pss.go +++ b/libgo/go/crypto/rsa/pss.go @@ -4,9 +4,7 @@ package rsa -// This file implements the PSS signature scheme [1]. -// -// [1] https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf +// This file implements the RSASSA-PSS signature scheme according to RFC 8017. import ( "bytes" @@ -17,8 +15,22 @@ import ( "math/big" ) +// Per RFC 8017, Section 9.1 +// +// EM = MGF1 xor DB || H( 8*0x00 || mHash || salt ) || 0xbc +// +// where +// +// DB = PS || 0x01 || salt +// +// and PS can be empty so +// +// emLen = dbLen + hLen + 1 = psLen + sLen + hLen + 2 +// + func emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash hash.Hash) ([]byte, error) { - // See [1], section 9.1.1 + // See RFC 8017, Section 9.1.1. + hLen := hash.Size() sLen := len(salt) emLen := (emBits + 7) / 8 @@ -30,7 +42,7 @@ func emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash hash.Hash) ([]byt // 2. Let mHash = Hash(M), an octet string of length hLen. if len(mHash) != hLen { - return nil, errors.New("crypto/rsa: input must be hashed message") + return nil, errors.New("crypto/rsa: input must be hashed with given hash") } // 3. If emLen < hLen + sLen + 2, output "encoding error" and stop. @@ -40,8 +52,9 @@ func emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash hash.Hash) ([]byt } em := make([]byte, emLen) - db := em[:emLen-sLen-hLen-2+1+sLen] - h := em[emLen-sLen-hLen-2+1+sLen : emLen-1] + psLen := emLen - sLen - hLen - 2 + db := em[:psLen+1+sLen] + h := em[psLen+1+sLen : emLen-1] // 4. Generate a random octet string salt of length sLen; if sLen = 0, // then salt is the empty string. @@ -69,8 +82,8 @@ func emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash hash.Hash) ([]byt // 8. Let DB = PS || 0x01 || salt; DB is an octet string of length // emLen - hLen - 1. - db[emLen-sLen-hLen-2] = 0x01 - copy(db[emLen-sLen-hLen-1:], salt) + db[psLen] = 0x01 + copy(db[psLen+1:], salt) // 9. Let dbMask = MGF(H, emLen - hLen - 1). // @@ -81,47 +94,57 @@ func emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash hash.Hash) ([]byt // 11. Set the leftmost 8 * emLen - emBits bits of the leftmost octet in // maskedDB to zero. - db[0] &= (0xFF >> uint(8*emLen-emBits)) + db[0] &= 0xff >> (8*emLen - emBits) // 12. Let EM = maskedDB || H || 0xbc. - em[emLen-1] = 0xBC + em[emLen-1] = 0xbc // 13. Output EM. return em, nil } func emsaPSSVerify(mHash, em []byte, emBits, sLen int, hash hash.Hash) error { + // See RFC 8017, Section 9.1.2. + + hLen := hash.Size() + if sLen == PSSSaltLengthEqualsHash { + sLen = hLen + } + emLen := (emBits + 7) / 8 + if emLen != len(em) { + return errors.New("rsa: internal error: inconsistent length") + } + // 1. If the length of M is greater than the input limitation for the // hash function (2^61 - 1 octets for SHA-1), output "inconsistent" // and stop. // // 2. Let mHash = Hash(M), an octet string of length hLen. - hLen := hash.Size() if hLen != len(mHash) { return ErrVerification } // 3. If emLen < hLen + sLen + 2, output "inconsistent" and stop. - emLen := (emBits + 7) / 8 if emLen < hLen+sLen+2 { return ErrVerification } // 4. If the rightmost octet of EM does not have hexadecimal value // 0xbc, output "inconsistent" and stop. - if em[len(em)-1] != 0xBC { + if em[emLen-1] != 0xbc { return ErrVerification } // 5. Let maskedDB be the leftmost emLen - hLen - 1 octets of EM, and // let H be the next hLen octets. db := em[:emLen-hLen-1] - h := em[emLen-hLen-1 : len(em)-1] + h := em[emLen-hLen-1 : emLen-1] // 6. If the leftmost 8 * emLen - emBits bits of the leftmost octet in // maskedDB are not all equal to zero, output "inconsistent" and // stop. - if em[0]&(0xFF<> (8*emLen - emBits) + if em[0] & ^bitMask != 0 { return ErrVerification } @@ -132,37 +155,30 @@ func emsaPSSVerify(mHash, em []byte, emBits, sLen int, hash hash.Hash) error { // 9. Set the leftmost 8 * emLen - emBits bits of the leftmost octet in DB // to zero. - db[0] &= (0xFF >> uint(8*emLen-emBits)) + db[0] &= bitMask + // If we don't know the salt length, look for the 0x01 delimiter. if sLen == PSSSaltLengthAuto { - FindSaltLength: - for sLen = emLen - (hLen + 2); sLen >= 0; sLen-- { - switch db[emLen-hLen-sLen-2] { - case 1: - break FindSaltLength - case 0: - continue - default: - return ErrVerification - } - } - if sLen < 0 { + psLen := bytes.IndexByte(db, 0x01) + if psLen < 0 { return ErrVerification } - } else { - // 10. If the emLen - hLen - sLen - 2 leftmost octets of DB are not zero - // or if the octet at position emLen - hLen - sLen - 1 (the leftmost - // position is "position 1") does not have hexadecimal value 0x01, - // output "inconsistent" and stop. - for _, e := range db[:emLen-hLen-sLen-2] { - if e != 0x00 { - return ErrVerification - } - } - if db[emLen-hLen-sLen-2] != 0x01 { + sLen = len(db) - psLen - 1 + } + + // 10. If the emLen - hLen - sLen - 2 leftmost octets of DB are not zero + // or if the octet at position emLen - hLen - sLen - 1 (the leftmost + // position is "position 1") does not have hexadecimal value 0x01, + // output "inconsistent" and stop. + psLen := emLen - hLen - sLen - 2 + for _, e := range db[:psLen] { + if e != 0x00 { return ErrVerification } } + if db[psLen] != 0x01 { + return ErrVerification + } // 11. Let salt be the last sLen octets of DB. salt := db[len(db)-sLen:] @@ -181,30 +197,29 @@ func emsaPSSVerify(mHash, em []byte, emBits, sLen int, hash hash.Hash) error { h0 := hash.Sum(nil) // 14. If H = H', output "consistent." Otherwise, output "inconsistent." - if !bytes.Equal(h0, h) { + if !bytes.Equal(h0, h) { // TODO: constant time? return ErrVerification } return nil } -// signPSSWithSalt calculates the signature of hashed using PSS [1] with specified salt. +// signPSSWithSalt calculates the signature of hashed using PSS with specified salt. // Note that hashed must be the result of hashing the input message using the // given hash function. salt is a random sequence of bytes whose length will be // later used to verify the signature. -func signPSSWithSalt(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed, salt []byte) (s []byte, err error) { - nBits := priv.N.BitLen() - em, err := emsaPSSEncode(hashed, nBits-1, salt, hash.New()) +func signPSSWithSalt(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed, salt []byte) ([]byte, error) { + emBits := priv.N.BitLen() - 1 + em, err := emsaPSSEncode(hashed, emBits, salt, hash.New()) if err != nil { - return + return nil, err } m := new(big.Int).SetBytes(em) c, err := decryptAndCheck(rand, priv, m) if err != nil { - return + return nil, err } - s = make([]byte, (nBits+7)/8) - copyWithLeftPad(s, c.Bytes()) - return + s := make([]byte, priv.Size()) + return c.FillBytes(s), nil } const ( @@ -223,16 +238,15 @@ type PSSOptions struct { // PSSSaltLength constants. SaltLength int - // Hash, if not zero, overrides the hash function passed to SignPSS. - // This is the only way to specify the hash function when using the - // crypto.Signer interface. + // Hash is the hash function used to generate the message digest. If not + // zero, it overrides the hash function passed to SignPSS. It's required + // when using PrivateKey.Sign. Hash crypto.Hash } -// HashFunc returns pssOpts.Hash so that PSSOptions implements -// crypto.SignerOpts. -func (pssOpts *PSSOptions) HashFunc() crypto.Hash { - return pssOpts.Hash +// HashFunc returns opts.Hash so that PSSOptions implements crypto.SignerOpts. +func (opts *PSSOptions) HashFunc() crypto.Hash { + return opts.Hash } func (opts *PSSOptions) saltLength() int { @@ -242,56 +256,48 @@ func (opts *PSSOptions) saltLength() int { return opts.SaltLength } -// SignPSS calculates the signature of hashed using RSASSA-PSS [1]. -// Note that hashed must be the result of hashing the input message using the -// given hash function. The opts argument may be nil, in which case sensible -// defaults are used. -func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte, opts *PSSOptions) ([]byte, error) { +// SignPSS calculates the signature of digest using PSS. +// +// digest must be the result of hashing the input message using the given hash +// function. The opts argument may be nil, in which case sensible defaults are +// used. If opts.Hash is set, it overrides hash. +func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte, opts *PSSOptions) ([]byte, error) { + if opts != nil && opts.Hash != 0 { + hash = opts.Hash + } + saltLength := opts.saltLength() switch saltLength { case PSSSaltLengthAuto: - saltLength = (priv.N.BitLen()+7)/8 - 2 - hash.Size() + saltLength = priv.Size() - 2 - hash.Size() case PSSSaltLengthEqualsHash: saltLength = hash.Size() } - if opts != nil && opts.Hash != 0 { - hash = opts.Hash - } - salt := make([]byte, saltLength) if _, err := io.ReadFull(rand, salt); err != nil { return nil, err } - return signPSSWithSalt(rand, priv, hash, hashed, salt) + return signPSSWithSalt(rand, priv, hash, digest, salt) } // VerifyPSS verifies a PSS signature. -// hashed is the result of hashing the input message using the given hash -// function and sig is the signature. A valid signature is indicated by -// returning a nil error. The opts argument may be nil, in which case sensible -// defaults are used. -func VerifyPSS(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte, opts *PSSOptions) error { - return verifyPSS(pub, hash, hashed, sig, opts.saltLength()) -} - -// verifyPSS verifies a PSS signature with the given salt length. -func verifyPSS(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte, saltLen int) error { - nBits := pub.N.BitLen() - if len(sig) != (nBits+7)/8 { +// +// A valid signature is indicated by returning a nil error. digest must be the +// result of hashing the input message using the given hash function. The opts +// argument may be nil, in which case sensible defaults are used. opts.Hash is +// ignored. +func VerifyPSS(pub *PublicKey, hash crypto.Hash, digest []byte, sig []byte, opts *PSSOptions) error { + if len(sig) != pub.Size() { return ErrVerification } s := new(big.Int).SetBytes(sig) m := encrypt(new(big.Int), pub, s) - emBits := nBits - 1 + emBits := pub.N.BitLen() - 1 emLen := (emBits + 7) / 8 - if emLen < len(m.Bytes()) { + if m.BitLen() > emLen*8 { return ErrVerification } - em := make([]byte, emLen) - copyWithLeftPad(em, m.Bytes()) - if saltLen == PSSSaltLengthEqualsHash { - saltLen = hash.Size() - } - return emsaPSSVerify(hashed, em, emBits, saltLen, hash.New()) + em := m.FillBytes(make([]byte, emLen)) + return emsaPSSVerify(digest, em, emBits, opts.saltLength(), hash.New()) } diff --git a/libgo/go/crypto/rsa/rsa.go b/libgo/go/crypto/rsa/rsa.go index d058949242d..178ade666a1 100644 --- a/libgo/go/crypto/rsa/rsa.go +++ b/libgo/go/crypto/rsa/rsa.go @@ -2,21 +2,21 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package rsa implements RSA encryption as specified in PKCS#1. +// Package rsa implements RSA encryption as specified in PKCS #1 and RFC 8017. // // RSA is a single, fundamental operation that is used in this package to // implement either public-key encryption or public-key signatures. // -// The original specification for encryption and signatures with RSA is PKCS#1 +// The original specification for encryption and signatures with RSA is PKCS #1 // and the terms "RSA encryption" and "RSA signatures" by default refer to -// PKCS#1 version 1.5. However, that specification has flaws and new designs -// should use version two, usually called by just OAEP and PSS, where +// PKCS #1 version 1.5. However, that specification has flaws and new designs +// should use version 2, usually called by just OAEP and PSS, where // possible. // // Two sets of interfaces are included in this package. When a more abstract // interface isn't necessary, there are functions for encrypting/decrypting // with v1.5/OAEP and signing/verifying with v1.5/PSS. If one needs to abstract -// over the public-key primitive, the PrivateKey struct implements the +// over the public key primitive, the PrivateKey type implements the // Decrypter and Signer interfaces from the crypto package. // // The RSA operations in this package are not implemented using constant-time algorithms. @@ -44,12 +44,24 @@ type PublicKey struct { E int // public exponent } +// Any methods implemented on PublicKey might need to also be implemented on +// PrivateKey, as the latter embeds the former and will expose its methods. + // Size returns the modulus size in bytes. Raw signatures and ciphertexts // for or by this public key will have the same size. func (pub *PublicKey) Size() int { return (pub.N.BitLen() + 7) / 8 } +// Equal reports whether pub and x have the same value. +func (pub *PublicKey) Equal(x crypto.PublicKey) bool { + xx, ok := x.(*PublicKey) + if !ok { + return false + } + return pub.N.Cmp(xx.N) == 0 && pub.E == xx.E +} + // OAEPOptions is an interface for passing options to OAEP decryption using the // crypto.Decrypter interface. type OAEPOptions struct { @@ -100,9 +112,31 @@ func (priv *PrivateKey) Public() crypto.PublicKey { return &priv.PublicKey } +// Equal reports whether priv and x have equivalent values. It ignores +// Precomputed values. +func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool { + xx, ok := x.(*PrivateKey) + if !ok { + return false + } + if !priv.PublicKey.Equal(&xx.PublicKey) || priv.D.Cmp(xx.D) != 0 { + return false + } + if len(priv.Primes) != len(xx.Primes) { + return false + } + for i := range priv.Primes { + if priv.Primes[i].Cmp(xx.Primes[i]) != 0 { + return false + } + } + return true +} + // Sign signs digest with priv, reading randomness from rand. If opts is a -// *PSSOptions then the PSS algorithm will be used, otherwise PKCS#1 v1.5 will -// be used. +// *PSSOptions then the PSS algorithm will be used, otherwise PKCS #1 v1.5 will +// be used. digest must be the result of hashing the input message using +// opts.HashFunc(). // // This method implements crypto.Signer, which is an interface to support keys // where the private part is kept in, for example, a hardware module. Common @@ -116,7 +150,7 @@ func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOp } // Decrypt decrypts ciphertext with priv. If opts is nil or of type -// *PKCS1v15DecryptOptions then PKCS#1 v1.5 decryption is performed. Otherwise +// *PKCS1v15DecryptOptions then PKCS #1 v1.5 decryption is performed. Otherwise // opts must have type *OAEPOptions and OAEP decryption is done. func (priv *PrivateKey) Decrypt(rand io.Reader, ciphertext []byte, opts crypto.DecrypterOpts) (plaintext []byte, err error) { if opts == nil { @@ -152,7 +186,7 @@ type PrecomputedValues struct { // CRTValues is used for the 3rd and subsequent primes. Due to a // historical accident, the CRT for the first two primes is handled - // differently in PKCS#1 and interoperability is sufficiently + // differently in PKCS #1 and interoperability is sufficiently // important that we mirror this. CRTValues []CRTValue } @@ -326,7 +360,7 @@ func incCounter(c *[4]byte) { } // mgf1XOR XORs the bytes in out with a mask generated using the MGF1 function -// specified in PKCS#1 v2.1. +// specified in PKCS #1 v2.1. func mgf1XOR(out []byte, hash hash.Hash, seed []byte) { var counter [4]byte var digest []byte @@ -406,16 +440,9 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l m := new(big.Int) m.SetBytes(em) c := encrypt(new(big.Int), pub, m) - out := c.Bytes() - - if len(out) < k { - // If the output is too small, we need to left-pad with zeros. - t := make([]byte, k) - copy(t[k-len(out):], out) - out = t - } - return out, nil + out := make([]byte, k) + return c.FillBytes(out), nil } // ErrDecryption represents a failure to decrypt a message. @@ -587,12 +614,9 @@ func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext lHash := hash.Sum(nil) hash.Reset() - // Converting the plaintext number to bytes will strip any - // leading zeros so we may have to left pad. We do this unconditionally - // to avoid leaking timing information. (Although we still probably - // leak the number of leading zeros. It's not clear that we can do - // anything about this.) - em := leftPad(m.Bytes(), k) + // We probably leak the number of leading zeros. + // It's not clear that we can do anything about this. + em := m.FillBytes(make([]byte, k)) firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0) @@ -633,15 +657,3 @@ func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext return rest[index+1:], nil } - -// leftPad returns a new slice of length size. The contents of input are right -// aligned in the new slice. -func leftPad(input []byte, size int) (out []byte) { - n := len(input) - if n > size { - n = size - } - out = make([]byte, size) - copy(out[len(out)-n:], input) - return -} diff --git a/libgo/go/crypto/sha512/sha512block_generic.go b/libgo/go/crypto/sha512/sha512block_generic.go index fb2e6c6bf5d..d3998a8283a 100644 --- a/libgo/go/crypto/sha512/sha512block_generic.go +++ b/libgo/go/crypto/sha512/sha512block_generic.go @@ -6,4 +6,6 @@ package sha512 -var block = blockGeneric +func block(dig *digest, p []byte) { + blockGeneric(dig, p) +} diff --git a/libgo/go/crypto/tls/alert.go b/libgo/go/crypto/tls/alert.go index 22b3eca92fa..4790b737245 100644 --- a/libgo/go/crypto/tls/alert.go +++ b/libgo/go/crypto/tls/alert.go @@ -15,63 +15,75 @@ const ( ) const ( - alertCloseNotify alert = 0 - alertUnexpectedMessage alert = 10 - alertBadRecordMAC alert = 20 - alertDecryptionFailed alert = 21 - alertRecordOverflow alert = 22 - alertDecompressionFailure alert = 30 - alertHandshakeFailure alert = 40 - alertBadCertificate alert = 42 - alertUnsupportedCertificate alert = 43 - alertCertificateRevoked alert = 44 - alertCertificateExpired alert = 45 - alertCertificateUnknown alert = 46 - alertIllegalParameter alert = 47 - alertUnknownCA alert = 48 - alertAccessDenied alert = 49 - alertDecodeError alert = 50 - alertDecryptError alert = 51 - alertProtocolVersion alert = 70 - alertInsufficientSecurity alert = 71 - alertInternalError alert = 80 - alertInappropriateFallback alert = 86 - alertUserCanceled alert = 90 - alertNoRenegotiation alert = 100 - alertMissingExtension alert = 109 - alertUnsupportedExtension alert = 110 - alertUnrecognizedName alert = 112 - alertNoApplicationProtocol alert = 120 + alertCloseNotify alert = 0 + alertUnexpectedMessage alert = 10 + alertBadRecordMAC alert = 20 + alertDecryptionFailed alert = 21 + alertRecordOverflow alert = 22 + alertDecompressionFailure alert = 30 + alertHandshakeFailure alert = 40 + alertBadCertificate alert = 42 + alertUnsupportedCertificate alert = 43 + alertCertificateRevoked alert = 44 + alertCertificateExpired alert = 45 + alertCertificateUnknown alert = 46 + alertIllegalParameter alert = 47 + alertUnknownCA alert = 48 + alertAccessDenied alert = 49 + alertDecodeError alert = 50 + alertDecryptError alert = 51 + alertExportRestriction alert = 60 + alertProtocolVersion alert = 70 + alertInsufficientSecurity alert = 71 + alertInternalError alert = 80 + alertInappropriateFallback alert = 86 + alertUserCanceled alert = 90 + alertNoRenegotiation alert = 100 + alertMissingExtension alert = 109 + alertUnsupportedExtension alert = 110 + alertCertificateUnobtainable alert = 111 + alertUnrecognizedName alert = 112 + alertBadCertificateStatusResponse alert = 113 + alertBadCertificateHashValue alert = 114 + alertUnknownPSKIdentity alert = 115 + alertCertificateRequired alert = 116 + alertNoApplicationProtocol alert = 120 ) var alertText = map[alert]string{ - alertCloseNotify: "close notify", - alertUnexpectedMessage: "unexpected message", - alertBadRecordMAC: "bad record MAC", - alertDecryptionFailed: "decryption failed", - alertRecordOverflow: "record overflow", - alertDecompressionFailure: "decompression failure", - alertHandshakeFailure: "handshake failure", - alertBadCertificate: "bad certificate", - alertUnsupportedCertificate: "unsupported certificate", - alertCertificateRevoked: "revoked certificate", - alertCertificateExpired: "expired certificate", - alertCertificateUnknown: "unknown certificate", - alertIllegalParameter: "illegal parameter", - alertUnknownCA: "unknown certificate authority", - alertAccessDenied: "access denied", - alertDecodeError: "error decoding message", - alertDecryptError: "error decrypting message", - alertProtocolVersion: "protocol version not supported", - alertInsufficientSecurity: "insufficient security level", - alertInternalError: "internal error", - alertInappropriateFallback: "inappropriate fallback", - alertUserCanceled: "user canceled", - alertNoRenegotiation: "no renegotiation", - alertMissingExtension: "missing extension", - alertUnsupportedExtension: "unsupported extension", - alertUnrecognizedName: "unrecognized name", - alertNoApplicationProtocol: "no application protocol", + alertCloseNotify: "close notify", + alertUnexpectedMessage: "unexpected message", + alertBadRecordMAC: "bad record MAC", + alertDecryptionFailed: "decryption failed", + alertRecordOverflow: "record overflow", + alertDecompressionFailure: "decompression failure", + alertHandshakeFailure: "handshake failure", + alertBadCertificate: "bad certificate", + alertUnsupportedCertificate: "unsupported certificate", + alertCertificateRevoked: "revoked certificate", + alertCertificateExpired: "expired certificate", + alertCertificateUnknown: "unknown certificate", + alertIllegalParameter: "illegal parameter", + alertUnknownCA: "unknown certificate authority", + alertAccessDenied: "access denied", + alertDecodeError: "error decoding message", + alertDecryptError: "error decrypting message", + alertExportRestriction: "export restriction", + alertProtocolVersion: "protocol version not supported", + alertInsufficientSecurity: "insufficient security level", + alertInternalError: "internal error", + alertInappropriateFallback: "inappropriate fallback", + alertUserCanceled: "user canceled", + alertNoRenegotiation: "no renegotiation", + alertMissingExtension: "missing extension", + alertUnsupportedExtension: "unsupported extension", + alertCertificateUnobtainable: "certificate unobtainable", + alertUnrecognizedName: "unrecognized name", + alertBadCertificateStatusResponse: "bad certificate status response", + alertBadCertificateHashValue: "bad certificate hash value", + alertUnknownPSKIdentity: "unknown PSK identity", + alertCertificateRequired: "certificate required", + alertNoApplicationProtocol: "no application protocol", } func (e alert) String() string { diff --git a/libgo/go/crypto/tls/auth.go b/libgo/go/crypto/tls/auth.go index 009f8d3d1ef..a9df0da6d62 100644 --- a/libgo/go/crypto/tls/auth.go +++ b/libgo/go/crypto/tls/auth.go @@ -11,7 +11,6 @@ import ( "crypto/ed25519" "crypto/elliptic" "crypto/rsa" - "encoding/asn1" "errors" "fmt" "hash" @@ -27,14 +26,7 @@ func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc c if !ok { return fmt.Errorf("expected an ECDSA public key, got %T", pubkey) } - ecdsaSig := new(ecdsaSignature) - if _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil { - return err - } - if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { - return errors.New("ECDSA signature contained zero or negative values") - } - if !ecdsa.Verify(pubKey, signed, ecdsaSig.R, ecdsaSig.S) { + if !ecdsa.VerifyASN1(pubKey, signed, sig) { return errors.New("ECDSA verification failure") } case signatureEd25519: @@ -114,7 +106,7 @@ func typeAndHashFromSignatureScheme(signatureAlgorithm SignatureScheme) (sigType case Ed25519: sigType = signatureEd25519 default: - return 0, 0, fmt.Errorf("unsupported signature algorithm: %#04x", signatureAlgorithm) + return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm) } switch signatureAlgorithm { case PKCS1WithSHA1, ECDSAWithSHA1: @@ -128,7 +120,7 @@ func typeAndHashFromSignatureScheme(signatureAlgorithm SignatureScheme) (sigType case Ed25519: hash = directSigning default: - return 0, 0, fmt.Errorf("unsupported signature algorithm: %#04x", signatureAlgorithm) + return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm) } return sigType, hash, nil } @@ -163,9 +155,9 @@ var rsaSignatureSchemes = []struct { {PSSWithSHA256, crypto.SHA256.Size()*2 + 2, VersionTLS13}, {PSSWithSHA384, crypto.SHA384.Size()*2 + 2, VersionTLS13}, {PSSWithSHA512, crypto.SHA512.Size()*2 + 2, VersionTLS13}, - // PKCS#1 v1.5 uses prefixes from hashPrefixes in crypto/rsa, and requires + // PKCS #1 v1.5 uses prefixes from hashPrefixes in crypto/rsa, and requires // emLen >= len(prefix) + hLen + 11 - // TLS 1.3 dropped support for PKCS#1 v1.5 in favor of RSA-PSS. + // TLS 1.3 dropped support for PKCS #1 v1.5 in favor of RSA-PSS. {PKCS1WithSHA256, 19 + crypto.SHA256.Size() + 11, VersionTLS12}, {PKCS1WithSHA384, 19 + crypto.SHA384.Size() + 11, VersionTLS12}, {PKCS1WithSHA512, 19 + crypto.SHA512.Size() + 11, VersionTLS12}, diff --git a/libgo/go/crypto/tls/auth_test.go b/libgo/go/crypto/tls/auth_test.go index c8d8c8fe4e0..c42e3491e46 100644 --- a/libgo/go/crypto/tls/auth_test.go +++ b/libgo/go/crypto/tls/auth_test.go @@ -62,7 +62,7 @@ func TestSignatureSelection(t *testing.T) { t.Errorf("test[%d]: unexpected selectSignatureScheme error: %v", testNo, err) } if test.expectedSigAlg != sigAlg { - t.Errorf("test[%d]: expected signature scheme %#x, got %#x", testNo, test.expectedSigAlg, sigAlg) + t.Errorf("test[%d]: expected signature scheme %v, got %v", testNo, test.expectedSigAlg, sigAlg) } sigType, hashFunc, err := typeAndHashFromSignatureScheme(sigAlg) if err != nil { @@ -115,7 +115,7 @@ func TestSignatureSelection(t *testing.T) { for testNo, test := range badTests { sigAlg, err := selectSignatureScheme(test.tlsVersion, test.cert, test.peerSigAlgs) if err == nil { - t.Errorf("test[%d]: unexpected success, got %#x", testNo, sigAlg) + t.Errorf("test[%d]: unexpected success, got %v", testNo, sigAlg) } } } @@ -129,7 +129,7 @@ func TestLegacyTypeAndHash(t *testing.T) { t.Errorf("RSA: expected signature type %#x, got %#x", expectedSigType, sigType) } if expectedHashFunc := crypto.MD5SHA1; expectedHashFunc != hashFunc { - t.Errorf("RSA: expected hash %#x, got %#x", expectedHashFunc, sigType) + t.Errorf("RSA: expected hash %#x, got %#x", expectedHashFunc, hashFunc) } sigType, hashFunc, err = legacyTypeAndHashFromPublicKey(testECDSAPrivateKey.Public()) @@ -140,7 +140,7 @@ func TestLegacyTypeAndHash(t *testing.T) { t.Errorf("ECDSA: expected signature type %#x, got %#x", expectedSigType, sigType) } if expectedHashFunc := crypto.SHA1; expectedHashFunc != hashFunc { - t.Errorf("ECDSA: expected hash %#x, got %#x", expectedHashFunc, sigType) + t.Errorf("ECDSA: expected hash %#x, got %#x", expectedHashFunc, hashFunc) } // Ed25519 is not supported by TLS 1.0 and 1.1. @@ -156,13 +156,13 @@ func TestSupportedSignatureAlgorithms(t *testing.T) { for _, sigAlg := range supportedSignatureAlgorithms { sigType, hash, err := typeAndHashFromSignatureScheme(sigAlg) if err != nil { - t.Errorf("%#04x: unexpected error: %v", sigAlg, err) + t.Errorf("%v: unexpected error: %v", sigAlg, err) } if sigType == 0 { - t.Errorf("%#04x: missing signature type", sigAlg) + t.Errorf("%v: missing signature type", sigAlg) } if hash == 0 && sigAlg != Ed25519 { - t.Errorf("%#04x: missing hash", sigAlg) + t.Errorf("%v: missing hash", sigAlg) } } } diff --git a/libgo/go/crypto/tls/common.go b/libgo/go/crypto/tls/common.go index c3de0b3deed..e8d009137ac 100644 --- a/libgo/go/crypto/tls/common.go +++ b/libgo/go/crypto/tls/common.go @@ -19,7 +19,6 @@ import ( "fmt" "internal/cpu" "io" - "math/big" "net" "strings" "sync" @@ -208,30 +207,78 @@ const ( downgradeCanaryTLS11 = "DOWNGRD\x00" ) +// testingOnlyForceDowngradeCanary is set in tests to force the server side to +// include downgrade canaries even if it's using its highers supported version. +var testingOnlyForceDowngradeCanary bool + // ConnectionState records basic TLS details about the connection. type ConnectionState struct { - Version uint16 // TLS version used by the connection (e.g. VersionTLS12) - HandshakeComplete bool // TLS handshake is complete - DidResume bool // connection resumes a previous TLS connection - CipherSuite uint16 // cipher suite in use (TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, ...) - NegotiatedProtocol string // negotiated next protocol (not guaranteed to be from Config.NextProtos) - NegotiatedProtocolIsMutual bool // negotiated protocol was advertised by server (client side only) - ServerName string // server name requested by client, if any (server side only) - PeerCertificates []*x509.Certificate // certificate chain presented by remote peer - VerifiedChains [][]*x509.Certificate // verified chains built from PeerCertificates - SignedCertificateTimestamps [][]byte // SCTs from the peer, if any - OCSPResponse []byte // stapled OCSP response from peer, if any + // Version is the TLS version used by the connection (e.g. VersionTLS12). + Version uint16 - // ekm is a closure exposed via ExportKeyingMaterial. - ekm func(label string, context []byte, length int) ([]byte, error) + // HandshakeComplete is true if the handshake has concluded. + HandshakeComplete bool + + // DidResume is true if this connection was successfully resumed from a + // previous session with a session ticket or similar mechanism. + DidResume bool + + // CipherSuite is the cipher suite negotiated for the connection (e.g. + // TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_AES_128_GCM_SHA256). + CipherSuite uint16 + + // NegotiatedProtocol is the application protocol negotiated with ALPN. + // + // Note that on the client side, this is currently not guaranteed to be from + // Config.NextProtos. + NegotiatedProtocol string + + // NegotiatedProtocolIsMutual used to indicate a mutual NPN negotiation. + // + // Deprecated: this value is always true. + NegotiatedProtocolIsMutual bool + + // ServerName is the value of the Server Name Indication extension sent by + // the client. It's available both on the server and on the client side. + ServerName string + + // PeerCertificates are the parsed certificates sent by the peer, in the + // order in which they were sent. The first element is the leaf certificate + // that the connection is verified against. + // + // On the client side, it can't be empty. On the server side, it can be + // empty if Config.ClientAuth is not RequireAnyClientCert or + // RequireAndVerifyClientCert. + PeerCertificates []*x509.Certificate + + // VerifiedChains is a list of one or more chains where the first element is + // PeerCertificates[0] and the last element is from Config.RootCAs (on the + // client side) or Config.ClientCAs (on the server side). + // + // On the client side, it's set if Config.InsecureSkipVerify is false. On + // the server side, it's set if Config.ClientAuth is VerifyClientCertIfGiven + // (and the peer provided a certificate) or RequireAndVerifyClientCert. + VerifiedChains [][]*x509.Certificate - // TLSUnique contains the "tls-unique" channel binding value (see RFC - // 5929, section 3). For resumed sessions this value will be nil - // because resumption does not include enough context (see - // https://mitls.org/pages/attacks/3SHAKE#channelbindings). This will - // change in future versions of Go once the TLS master-secret fix has - // been standardized and implemented. It is not defined in TLS 1.3. + // SignedCertificateTimestamps is a list of SCTs provided by the peer + // through the TLS handshake for the leaf certificate, if any. + SignedCertificateTimestamps [][]byte + + // OCSPResponse is a stapled Online Certificate Status Protocol (OCSP) + // response provided by the peer for the leaf certificate, if any. + OCSPResponse []byte + + // TLSUnique contains the "tls-unique" channel binding value (see RFC 5929, + // Section 3). This value will be nil for TLS 1.3 connections and for all + // resumed connections. + // + // Deprecated: there are conditions in which this value might not be unique + // to a connection. See the Security Considerations sections of RFC 5705 and + // RFC 7627, and https://mitls.org/pages/attacks/3SHAKE#channelbindings. TLSUnique []byte + + // ekm is a closure exposed via ExportKeyingMaterial. + ekm func(label string, context []byte, length int) ([]byte, error) } // ExportKeyingMaterial returns length bytes of exported key material in a new @@ -275,6 +322,8 @@ type ClientSessionState struct { serverCertificates []*x509.Certificate // Certificate chain presented by the server verifiedChains [][]*x509.Certificate // Certificate chains we built for verification receivedAt time.Time // When the session ticket was received from the server + ocspResponse []byte // Stapled OCSP response presented by the server + scts [][]byte // SCTs presented by the server // TLS 1.3 fields. nonce []byte // Ticket nonce sent by the server, to derive PSK @@ -300,6 +349,8 @@ type ClientSessionCache interface { Put(sessionKey string, cs *ClientSessionState) } +//go:generate stringer -type=SignatureScheme,CurveID,ClientAuthType -output=common_string.go + // SignatureScheme identifies a signature algorithm supported by TLS. See // RFC 8446, Section 4.2.3. type SignatureScheme uint16 @@ -496,15 +547,10 @@ type Config struct { // If GetConfigForClient is nil, the Config passed to Server() will be // used for all connections. // - // Uniquely for the fields in the returned Config, session ticket keys - // will be duplicated from the original Config if not set. - // Specifically, if SetSessionTicketKeys was called on the original - // config but not on the returned config then the ticket keys from the - // original config will be copied into the new config before use. - // Otherwise, if SessionTicketKey was set in the original config but - // not in the returned config then it will be copied into the returned - // config before use. If neither of those cases applies then the key - // material from the returned config will be used for session tickets. + // If SessionTicketKey was explicitly set on the returned Config, or if + // SetSessionTicketKeys was called on the returned Config, those keys will + // be used. Otherwise, the original Config keys will be used (and possibly + // rotated if they are automatically managed). GetConfigForClient func(*ClientHelloInfo) (*Config, error) // VerifyPeerCertificate, if not nil, is called after normal @@ -520,6 +566,16 @@ type Config struct { // be considered but the verifiedChains argument will always be nil. VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error + // VerifyConnection, if not nil, is called after normal certificate + // verification and after VerifyPeerCertificate by either a TLS client + // or server. If it returns a non-nil error, the handshake is aborted + // and that error results. + // + // If normal verification fails then the handshake will abort before + // considering this callback. This callback will run for all connections + // regardless of InsecureSkipVerify or ClientAuth settings. + VerifyConnection func(ConnectionState) error + // RootCAs defines the set of root certificate authorities // that clients use when verifying server certificates. // If RootCAs is nil, TLS uses the host's root CA set. @@ -544,12 +600,12 @@ type Config struct { // by the policy in ClientAuth. ClientCAs *x509.CertPool - // InsecureSkipVerify controls whether a client verifies the - // server's certificate chain and host name. - // If InsecureSkipVerify is true, TLS accepts any certificate - // presented by the server and any host name in that certificate. - // In this mode, TLS is susceptible to man-in-the-middle attacks. - // This should be used only for testing. + // InsecureSkipVerify controls whether a client verifies the server's + // certificate chain and host name. If InsecureSkipVerify is true, crypto/tls + // accepts any certificate presented by the server and any host name in that + // certificate. In this mode, TLS is susceptible to machine-in-the-middle + // attacks unless custom verification is used. This should be used only for + // testing or in combination with VerifyConnection or VerifyPeerCertificate. InsecureSkipVerify bool // CipherSuites is a list of supported cipher suites for TLS versions up to @@ -574,10 +630,10 @@ type Config struct { // See RFC 5077 and the PSK mode of RFC 8446. If zero, it will be filled // with random data before the first server handshake. // - // If multiple servers are terminating connections for the same host - // they should all have the same SessionTicketKey. If the - // SessionTicketKey leaks, previously recorded and future TLS - // connections using that key might be compromised. + // Deprecated: if this field is left at zero, session ticket keys will be + // automatically rotated every day and dropped after seven days. For + // customizing the rotation schedule or synchronizing servers that are + // terminating connections for the same host, use SetSessionTicketKeys. SessionTicketKey [32]byte // ClientSessionCache is a cache of ClientSessionState entries for TLS @@ -617,20 +673,32 @@ type Config struct { // used for debugging. KeyLogWriter io.Writer - serverInitOnce sync.Once // guards calling (*Config).serverInit - - // mutex protects sessionTicketKeys. + // mutex protects sessionTicketKeys and autoSessionTicketKeys. mutex sync.RWMutex - // sessionTicketKeys contains zero or more ticket keys. If the length - // is zero, SessionTicketsDisabled must be true. The first key is used - // for new tickets and any subsequent keys can be used to decrypt old - // tickets. + // sessionTicketKeys contains zero or more ticket keys. If set, it means the + // the keys were set with SessionTicketKey or SetSessionTicketKeys. The + // first key is used for new tickets and any subsequent keys can be used to + // decrypt old tickets. The slice contents are not protected by the mutex + // and are immutable. sessionTicketKeys []ticketKey + // autoSessionTicketKeys is like sessionTicketKeys but is owned by the + // auto-rotation logic. See Config.ticketKeys. + autoSessionTicketKeys []ticketKey } -// ticketKeyNameLen is the number of bytes of identifier that is prepended to -// an encrypted session ticket in order to identify the key used to encrypt it. -const ticketKeyNameLen = 16 +const ( + // ticketKeyNameLen is the number of bytes of identifier that is prepended to + // an encrypted session ticket in order to identify the key used to encrypt it. + ticketKeyNameLen = 16 + + // ticketKeyLifetime is how long a ticket key remains valid and can be used to + // resume a client connection. + ticketKeyLifetime = 7 * 24 * time.Hour // 7 days + + // ticketKeyRotation is how often the server should rotate the session ticket key + // that is used for new tickets. + ticketKeyRotation = 24 * time.Hour +) // ticketKey is the internal representation of a session ticket key. type ticketKey struct { @@ -639,16 +707,19 @@ type ticketKey struct { keyName [ticketKeyNameLen]byte aesKey [16]byte hmacKey [16]byte + // created is the time at which this ticket key was created. See Config.ticketKeys. + created time.Time } // ticketKeyFromBytes converts from the external representation of a session // ticket key to a ticketKey. Externally, session ticket keys are 32 random // bytes and this function expands that into sufficient name and key material. -func ticketKeyFromBytes(b [32]byte) (key ticketKey) { +func (c *Config) ticketKeyFromBytes(b [32]byte) (key ticketKey) { hashed := sha512.Sum512(b[:]) copy(key.keyName[:], hashed[:ticketKeyNameLen]) copy(key.aesKey[:], hashed[ticketKeyNameLen:ticketKeyNameLen+16]) copy(key.hmacKey[:], hashed[ticketKeyNameLen+16:ticketKeyNameLen+32]) + key.created = c.time() return key } @@ -659,15 +730,8 @@ const maxSessionTicketLifetime = 7 * 24 * time.Hour // Clone returns a shallow clone of c. It is safe to clone a Config that is // being used concurrently by a TLS client or server. func (c *Config) Clone() *Config { - // Running serverInit ensures that it's safe to read - // SessionTicketsDisabled. - c.serverInitOnce.Do(func() { c.serverInit(nil) }) - - var sessionTicketKeys []ticketKey c.mutex.RLock() - sessionTicketKeys = c.sessionTicketKeys - c.mutex.RUnlock() - + defer c.mutex.RUnlock() return &Config{ Rand: c.Rand, Time: c.Time, @@ -677,6 +741,7 @@ func (c *Config) Clone() *Config { GetClientCertificate: c.GetClientCertificate, GetConfigForClient: c.GetConfigForClient, VerifyPeerCertificate: c.VerifyPeerCertificate, + VerifyConnection: c.VerifyConnection, RootCAs: c.RootCAs, NextProtos: c.NextProtos, ServerName: c.ServerName, @@ -694,58 +759,122 @@ func (c *Config) Clone() *Config { DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled, Renegotiation: c.Renegotiation, KeyLogWriter: c.KeyLogWriter, - sessionTicketKeys: sessionTicketKeys, + sessionTicketKeys: c.sessionTicketKeys, + autoSessionTicketKeys: c.autoSessionTicketKeys, } } -// serverInit is run under c.serverInitOnce to do initialization of c. If c was -// returned by a GetConfigForClient callback then the argument should be the -// Config that was passed to Server, otherwise it should be nil. -func (c *Config) serverInit(originalConfig *Config) { - if c.SessionTicketsDisabled || len(c.ticketKeys()) != 0 { +// deprecatedSessionTicketKey is set as the prefix of SessionTicketKey if it was +// randomized for backwards compatibility but is not in use. +var deprecatedSessionTicketKey = []byte("DEPRECATED") + +// initLegacySessionTicketKeyRLocked ensures the legacy SessionTicketKey field is +// randomized if empty, and that sessionTicketKeys is populated from it otherwise. +func (c *Config) initLegacySessionTicketKeyRLocked() { + // Don't write if SessionTicketKey is already defined as our deprecated string, + // or if it is defined by the user but sessionTicketKeys is already set. + if c.SessionTicketKey != [32]byte{} && + (bytes.HasPrefix(c.SessionTicketKey[:], deprecatedSessionTicketKey) || len(c.sessionTicketKeys) > 0) { return } - alreadySet := false - for _, b := range c.SessionTicketKey { - if b != 0 { - alreadySet = true - break + // We need to write some data, so get an exclusive lock and re-check any conditions. + c.mutex.RUnlock() + defer c.mutex.RLock() + c.mutex.Lock() + defer c.mutex.Unlock() + if c.SessionTicketKey == [32]byte{} { + if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil { + panic(fmt.Sprintf("tls: unable to generate random session ticket key: %v", err)) } + // Write the deprecated prefix at the beginning so we know we created + // it. This key with the DEPRECATED prefix isn't used as an actual + // session ticket key, and is only randomized in case the application + // reuses it for some reason. + copy(c.SessionTicketKey[:], deprecatedSessionTicketKey) + } else if !bytes.HasPrefix(c.SessionTicketKey[:], deprecatedSessionTicketKey) && len(c.sessionTicketKeys) == 0 { + c.sessionTicketKeys = []ticketKey{c.ticketKeyFromBytes(c.SessionTicketKey)} } - if !alreadySet { - if originalConfig != nil { - copy(c.SessionTicketKey[:], originalConfig.SessionTicketKey[:]) - } else if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil { - c.SessionTicketsDisabled = true - return +} + +// ticketKeys returns the ticketKeys for this connection. +// If configForClient has explicitly set keys, those will +// be returned. Otherwise, the keys on c will be used and +// may be rotated if auto-managed. +// During rotation, any expired session ticket keys are deleted from +// c.sessionTicketKeys. If the session ticket key that is currently +// encrypting tickets (ie. the first ticketKey in c.sessionTicketKeys) +// is not fresh, then a new session ticket key will be +// created and prepended to c.sessionTicketKeys. +func (c *Config) ticketKeys(configForClient *Config) []ticketKey { + // If the ConfigForClient callback returned a Config with explicitly set + // keys, use those, otherwise just use the original Config. + if configForClient != nil { + configForClient.mutex.RLock() + if configForClient.SessionTicketsDisabled { + return nil } + configForClient.initLegacySessionTicketKeyRLocked() + if len(configForClient.sessionTicketKeys) != 0 { + ret := configForClient.sessionTicketKeys + configForClient.mutex.RUnlock() + return ret + } + configForClient.mutex.RUnlock() } - if originalConfig != nil { - originalConfig.mutex.RLock() - c.sessionTicketKeys = originalConfig.sessionTicketKeys - originalConfig.mutex.RUnlock() - } else { - c.sessionTicketKeys = []ticketKey{ticketKeyFromBytes(c.SessionTicketKey)} + c.mutex.RLock() + defer c.mutex.RUnlock() + if c.SessionTicketsDisabled { + return nil + } + c.initLegacySessionTicketKeyRLocked() + if len(c.sessionTicketKeys) != 0 { + return c.sessionTicketKeys + } + // Fast path for the common case where the key is fresh enough. + if len(c.autoSessionTicketKeys) > 0 && c.time().Sub(c.autoSessionTicketKeys[0].created) < ticketKeyRotation { + return c.autoSessionTicketKeys } -} -func (c *Config) ticketKeys() []ticketKey { - c.mutex.RLock() - // c.sessionTicketKeys is constant once created. SetSessionTicketKeys - // will only update it by replacing it with a new value. - ret := c.sessionTicketKeys + // autoSessionTicketKeys are managed by auto-rotation. c.mutex.RUnlock() - return ret + defer c.mutex.RLock() + c.mutex.Lock() + defer c.mutex.Unlock() + // Re-check the condition in case it changed since obtaining the new lock. + if len(c.autoSessionTicketKeys) == 0 || c.time().Sub(c.autoSessionTicketKeys[0].created) >= ticketKeyRotation { + var newKey [32]byte + if _, err := io.ReadFull(c.rand(), newKey[:]); err != nil { + panic(fmt.Sprintf("unable to generate random session ticket key: %v", err)) + } + valid := make([]ticketKey, 0, len(c.autoSessionTicketKeys)+1) + valid = append(valid, c.ticketKeyFromBytes(newKey)) + for _, k := range c.autoSessionTicketKeys { + // While rotating the current key, also remove any expired ones. + if c.time().Sub(k.created) < ticketKeyLifetime { + valid = append(valid, k) + } + } + c.autoSessionTicketKeys = valid + } + return c.autoSessionTicketKeys } -// SetSessionTicketKeys updates the session ticket keys for a server. The first -// key will be used when creating new tickets, while all keys can be used for -// decrypting tickets. It is safe to call this function while the server is -// running in order to rotate the session ticket keys. The function will panic -// if keys is empty. +// SetSessionTicketKeys updates the session ticket keys for a server. +// +// The first key will be used when creating new tickets, while all keys can be +// used for decrypting tickets. It is safe to call this function while the +// server is running in order to rotate the session ticket keys. The function +// will panic if keys is empty. +// +// Calling this function will turn off automatic session ticket key rotation. +// +// If multiple servers are terminating connections for the same host they should +// all have the same session ticket keys. If the session ticket keys leaks, +// previously recorded and future TLS connections using those keys might be +// compromised. func (c *Config) SetSessionTicketKeys(keys [][32]byte) { if len(keys) == 0 { panic("tls: keys must have at least one key") @@ -753,7 +882,7 @@ func (c *Config) SetSessionTicketKeys(keys [][32]byte) { newKeys := make([]ticketKey, len(keys)) for i, bytes := range keys { - newKeys[i] = ticketKeyFromBytes(bytes) + newKeys[i] = c.ticketKeyFromBytes(bytes) } c.mutex.Lock() @@ -1264,13 +1393,6 @@ func (c *lruSessionCache) Get(sessionKey string) (*ClientSessionState, bool) { return nil, false } -// TODO(jsing): Make these available to both crypto/x509 and crypto/tls. -type dsaSignature struct { - R, S *big.Int -} - -type ecdsaSignature dsaSignature - var emptyConfig Config func defaultConfig() *Config { diff --git a/libgo/go/crypto/tls/common_string.go b/libgo/go/crypto/tls/common_string.go new file mode 100644 index 00000000000..238108811f2 --- /dev/null +++ b/libgo/go/crypto/tls/common_string.go @@ -0,0 +1,116 @@ +// Code generated by "stringer -type=SignatureScheme,CurveID,ClientAuthType -output=common_string.go"; DO NOT EDIT. + +package tls + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[PKCS1WithSHA256-1025] + _ = x[PKCS1WithSHA384-1281] + _ = x[PKCS1WithSHA512-1537] + _ = x[PSSWithSHA256-2052] + _ = x[PSSWithSHA384-2053] + _ = x[PSSWithSHA512-2054] + _ = x[ECDSAWithP256AndSHA256-1027] + _ = x[ECDSAWithP384AndSHA384-1283] + _ = x[ECDSAWithP521AndSHA512-1539] + _ = x[Ed25519-2055] + _ = x[PKCS1WithSHA1-513] + _ = x[ECDSAWithSHA1-515] +} + +const ( + _SignatureScheme_name_0 = "PKCS1WithSHA1" + _SignatureScheme_name_1 = "ECDSAWithSHA1" + _SignatureScheme_name_2 = "PKCS1WithSHA256" + _SignatureScheme_name_3 = "ECDSAWithP256AndSHA256" + _SignatureScheme_name_4 = "PKCS1WithSHA384" + _SignatureScheme_name_5 = "ECDSAWithP384AndSHA384" + _SignatureScheme_name_6 = "PKCS1WithSHA512" + _SignatureScheme_name_7 = "ECDSAWithP521AndSHA512" + _SignatureScheme_name_8 = "PSSWithSHA256PSSWithSHA384PSSWithSHA512Ed25519" +) + +var ( + _SignatureScheme_index_8 = [...]uint8{0, 13, 26, 39, 46} +) + +func (i SignatureScheme) String() string { + switch { + case i == 513: + return _SignatureScheme_name_0 + case i == 515: + return _SignatureScheme_name_1 + case i == 1025: + return _SignatureScheme_name_2 + case i == 1027: + return _SignatureScheme_name_3 + case i == 1281: + return _SignatureScheme_name_4 + case i == 1283: + return _SignatureScheme_name_5 + case i == 1537: + return _SignatureScheme_name_6 + case i == 1539: + return _SignatureScheme_name_7 + case 2052 <= i && i <= 2055: + i -= 2052 + return _SignatureScheme_name_8[_SignatureScheme_index_8[i]:_SignatureScheme_index_8[i+1]] + default: + return "SignatureScheme(" + strconv.FormatInt(int64(i), 10) + ")" + } +} +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[CurveP256-23] + _ = x[CurveP384-24] + _ = x[CurveP521-25] + _ = x[X25519-29] +} + +const ( + _CurveID_name_0 = "CurveP256CurveP384CurveP521" + _CurveID_name_1 = "X25519" +) + +var ( + _CurveID_index_0 = [...]uint8{0, 9, 18, 27} +) + +func (i CurveID) String() string { + switch { + case 23 <= i && i <= 25: + i -= 23 + return _CurveID_name_0[_CurveID_index_0[i]:_CurveID_index_0[i+1]] + case i == 29: + return _CurveID_name_1 + default: + return "CurveID(" + strconv.FormatInt(int64(i), 10) + ")" + } +} +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[NoClientCert-0] + _ = x[RequestClientCert-1] + _ = x[RequireAnyClientCert-2] + _ = x[VerifyClientCertIfGiven-3] + _ = x[RequireAndVerifyClientCert-4] +} + +const _ClientAuthType_name = "NoClientCertRequestClientCertRequireAnyClientCertVerifyClientCertIfGivenRequireAndVerifyClientCert" + +var _ClientAuthType_index = [...]uint8{0, 12, 29, 49, 72, 98} + +func (i ClientAuthType) String() string { + if i < 0 || i >= ClientAuthType(len(_ClientAuthType_index)-1) { + return "ClientAuthType(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _ClientAuthType_name[_ClientAuthType_index[i]:_ClientAuthType_index[i+1]] +} diff --git a/libgo/go/crypto/tls/conn.go b/libgo/go/crypto/tls/conn.go index fac4b914734..edcfecf81d7 100644 --- a/libgo/go/crypto/tls/conn.go +++ b/libgo/go/crypto/tls/conn.go @@ -24,8 +24,9 @@ import ( // It implements the net.Conn interface. type Conn struct { // constant - conn net.Conn - isClient bool + conn net.Conn + isClient bool + handshakeFn func() error // (*Conn).clientHandshake or serverHandshake // handshakeStatus is 1 if the connection is currently transferring // application data (i.e. is not currently processing a handshake). @@ -61,6 +62,11 @@ type Conn struct { // NewSessionTicket messages. nil if config.SessionTicketsDisabled. resumptionSecret []byte + // ticketKeys is the set of active session ticket keys for this + // connection. The first one is used to encrypt new tickets and + // all are tried to decrypt tickets. + ticketKeys []ticketKey + // clientFinishedIsFirst is true if the client sent the first Finished // message during the most recent handshake. This is recorded because // the first transmitted Finished message is the tls-unique @@ -162,9 +168,22 @@ type halfConn struct { trafficSecret []byte // current TLS 1.3 traffic secret } +type permamentError struct { + err net.Error +} + +func (e *permamentError) Error() string { return e.err.Error() } +func (e *permamentError) Unwrap() error { return e.err } +func (e *permamentError) Timeout() bool { return e.err.Timeout() } +func (e *permamentError) Temporary() bool { return false } + func (hc *halfConn) setErrorLocked(err error) error { - hc.err = err - return err + if e, ok := err.(net.Error); ok { + hc.err = &permamentError{err: e} + } else { + hc.err = err + } + return hc.err } // prepareCipherSpec sets the encryption and MAC states @@ -1320,8 +1339,12 @@ func (c *Conn) closeNotify() error { // Handshake runs the client or server handshake // protocol if it has not yet been run. -// Most uses of this package need not call Handshake -// explicitly: the first Read or Write will call it automatically. +// +// Most uses of this package need not call Handshake explicitly: the +// first Read or Write will call it automatically. +// +// For control over canceling or setting a timeout on a handshake, use +// the Dialer's DialContext method. func (c *Conn) Handshake() error { c.handshakeMutex.Lock() defer c.handshakeMutex.Unlock() @@ -1336,11 +1359,7 @@ func (c *Conn) Handshake() error { c.in.Lock() defer c.in.Unlock() - if c.isClient { - c.handshakeErr = c.clientHandshake() - } else { - c.handshakeErr = c.serverHandshake() - } + c.handshakeErr = c.handshakeFn() if c.handshakeErr == nil { c.handshakes++ } else { @@ -1360,35 +1379,34 @@ func (c *Conn) Handshake() error { func (c *Conn) ConnectionState() ConnectionState { c.handshakeMutex.Lock() defer c.handshakeMutex.Unlock() + return c.connectionStateLocked() +} +func (c *Conn) connectionStateLocked() ConnectionState { var state ConnectionState state.HandshakeComplete = c.handshakeComplete() + state.Version = c.vers + state.NegotiatedProtocol = c.clientProtocol + state.DidResume = c.didResume + state.NegotiatedProtocolIsMutual = !c.clientProtocolFallback state.ServerName = c.serverName - - if state.HandshakeComplete { - state.Version = c.vers - state.NegotiatedProtocol = c.clientProtocol - state.DidResume = c.didResume - state.NegotiatedProtocolIsMutual = !c.clientProtocolFallback - state.CipherSuite = c.cipherSuite - state.PeerCertificates = c.peerCertificates - state.VerifiedChains = c.verifiedChains - state.SignedCertificateTimestamps = c.scts - state.OCSPResponse = c.ocspResponse - if !c.didResume && c.vers != VersionTLS13 { - if c.clientFinishedIsFirst { - state.TLSUnique = c.clientFinished[:] - } else { - state.TLSUnique = c.serverFinished[:] - } - } - if c.config.Renegotiation != RenegotiateNever { - state.ekm = noExportedKeyingMaterial + state.CipherSuite = c.cipherSuite + state.PeerCertificates = c.peerCertificates + state.VerifiedChains = c.verifiedChains + state.SignedCertificateTimestamps = c.scts + state.OCSPResponse = c.ocspResponse + if !c.didResume && c.vers != VersionTLS13 { + if c.clientFinishedIsFirst { + state.TLSUnique = c.clientFinished[:] } else { - state.ekm = c.ekm + state.TLSUnique = c.serverFinished[:] } } - + if c.config.Renegotiation != RenegotiateNever { + state.ekm = noExportedKeyingMaterial + } else { + state.ekm = c.ekm + } return state } diff --git a/libgo/go/crypto/tls/example_test.go b/libgo/go/crypto/tls/example_test.go index c88f8add090..6389fd7fedc 100644 --- a/libgo/go/crypto/tls/example_test.go +++ b/libgo/go/crypto/tls/example_test.go @@ -7,7 +7,6 @@ package tls_test import ( "crypto/tls" "crypto/x509" - "errors" "log" "net/http" "net/http/httptest" @@ -30,29 +29,28 @@ func ExampleDial() { // Connecting with a custom root-certificate set. const rootPEM = ` +-- GlobalSign Root R2, valid until Dec 15, 2021 -----BEGIN CERTIFICATE----- -MIIEBDCCAuygAwIBAgIDAjppMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT -MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i -YWwgQ0EwHhcNMTMwNDA1MTUxNTU1WhcNMTUwNDA0MTUxNTU1WjBJMQswCQYDVQQG -EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy -bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP -VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv -h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE -ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ -EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC -DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB+zCB+DAfBgNVHSMEGDAWgBTAephojYn7 -qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wEgYD -VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMwMTAvoC2g -K4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9ndGdsb2JhbC5jcmwwPQYI -KwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwOi8vZ3RnbG9iYWwtb2NzcC5n -ZW90cnVzdC5jb20wFwYDVR0gBBAwDjAMBgorBgEEAdZ5AgUBMA0GCSqGSIb3DQEB -BQUAA4IBAQA21waAESetKhSbOHezI6B1WLuxfoNCunLaHtiONgaX4PCVOzf9G0JY -/iLIa704XtE7JW4S615ndkZAkNoUyHgN7ZVm2o6Gb4ChulYylYbc3GrKBIxbf/a/ -zG+FA1jDaFETzf3I93k9mTXwVqO94FntT0QJo544evZG0R0SnU++0ED8Vf4GXjza -HFa9llF7b1cq26KqltyMdMKVvvBulRP/F/A8rLIQjcxz++iPAsbw+zOzlTvjwsto -WHPbqCRiOwY1nQ2pM714A5AuTHhdUDqB1O6gyHA43LL5Z/qHQF1hwFGPa4NrzQU6 -yuGnBXj8ytqU0CwIPX4WecigUCAkVDNx +MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 +MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL +v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 +eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq +tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd +C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa +zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB +mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH +V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n +bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG +3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs +J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO +291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS +ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd +AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 +TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== -----END CERTIFICATE-----` // First, create the set of root certificates. For this example we only @@ -185,54 +183,50 @@ EKTcWGekdmdDPsHloRNtsiCa697B2O9IFA== log.Fatal(srv.ListenAndServeTLS("", "")) } -func ExampleConfig_verifyPeerCertificate() { - // VerifyPeerCertificate can be used to replace and customize certificate - // verification. This example shows a VerifyPeerCertificate implementation - // that will be approximately equivalent to what crypto/tls does normally. +func ExampleConfig_verifyConnection() { + // VerifyConnection can be used to replace and customize connection + // verification. This example shows a VerifyConnection implementation that + // will be approximately equivalent to what crypto/tls does normally to + // verify the peer's certificate. - config := &tls.Config{ + // Client side configuration. + _ = &tls.Config{ // Set InsecureSkipVerify to skip the default validation we are - // replacing. This will not disable VerifyPeerCertificate. + // replacing. This will not disable VerifyConnection. InsecureSkipVerify: true, - - // While packages like net/http will implicitly set ServerName, the - // VerifyPeerCertificate callback can't access that value, so it has to be set - // explicitly here or in VerifyPeerCertificate on the client side. If in - // an http.Transport DialTLS callback, this can be obtained by passing - // the addr argument to net.SplitHostPort. - ServerName: "example.com", - - // On the server side, set ClientAuth to require client certificates (or - // VerifyPeerCertificate will run anyway and panic accessing certs[0]) - // but not verify them with the default verifier. - // ClientAuth: tls.RequireAnyClientCert, + VerifyConnection: func(cs tls.ConnectionState) error { + opts := x509.VerifyOptions{ + DNSName: cs.ServerName, + Intermediates: x509.NewCertPool(), + } + for _, cert := range cs.PeerCertificates[1:] { + opts.Intermediates.AddCert(cert) + } + _, err := cs.PeerCertificates[0].Verify(opts) + return err + }, } - config.VerifyPeerCertificate = func(certificates [][]byte, _ [][]*x509.Certificate) error { - certs := make([]*x509.Certificate, len(certificates)) - for i, asn1Data := range certificates { - cert, err := x509.ParseCertificate(asn1Data) - if err != nil { - return errors.New("tls: failed to parse certificate from server: " + err.Error()) + // Server side configuration. + _ = &tls.Config{ + // Require client certificates (or VerifyConnection will run anyway and + // panic accessing cs.PeerCertificates[0]) but don't verify them with the + // default verifier. This will not disable VerifyConnection. + ClientAuth: tls.RequireAnyClientCert, + VerifyConnection: func(cs tls.ConnectionState) error { + opts := x509.VerifyOptions{ + DNSName: cs.ServerName, + Intermediates: x509.NewCertPool(), + KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, + } + for _, cert := range cs.PeerCertificates[1:] { + opts.Intermediates.AddCert(cert) } - certs[i] = cert - } - - opts := x509.VerifyOptions{ - Roots: config.RootCAs, // On the server side, use config.ClientCAs. - DNSName: config.ServerName, - Intermediates: x509.NewCertPool(), - // On the server side, set KeyUsages to ExtKeyUsageClientAuth. The - // default value is appropriate for clients side verification. - // KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, - } - for _, cert := range certs[1:] { - opts.Intermediates.AddCert(cert) - } - _, err := certs[0].Verify(opts) - return err + _, err := cs.PeerCertificates[0].Verify(opts) + return err + }, } - // Note that when InsecureSkipVerify and VerifyPeerCertificate are in use, + // Note that when certificates are not handled by the default verifier // ConnectionState.VerifiedChains will be nil. } diff --git a/libgo/go/crypto/tls/generate_cert.go b/libgo/go/crypto/tls/generate_cert.go index f1d69c401ab..1857185fe4d 100644 --- a/libgo/go/crypto/tls/generate_cert.go +++ b/libgo/go/crypto/tls/generate_cert.go @@ -81,6 +81,16 @@ func main() { log.Fatalf("Failed to generate private key: %v", err) } + // ECDSA, ED25519 and RSA subject keys should have the DigitalSignature + // KeyUsage bits set in the x509.Certificate template + keyUsage := x509.KeyUsageDigitalSignature + // Only RSA subject keys should have the KeyEncipherment KeyUsage bits set. In + // the context of TLS this KeyUsage is particular to RSA key exchange and + // authentication. + if _, isRSA := priv.(*rsa.PrivateKey); isRSA { + keyUsage |= x509.KeyUsageKeyEncipherment + } + var notBefore time.Time if len(*validFrom) == 0 { notBefore = time.Now() @@ -107,7 +117,7 @@ func main() { NotBefore: notBefore, NotAfter: notAfter, - KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + KeyUsage: keyUsage, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } diff --git a/libgo/go/crypto/tls/handshake_client.go b/libgo/go/crypto/tls/handshake_client.go index 4fb528cc9bf..46b0a770d53 100644 --- a/libgo/go/crypto/tls/handshake_client.go +++ b/libgo/go/crypto/tls/handshake_client.go @@ -54,7 +54,7 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) { return nil, nil, errors.New("tls: no supported versions satisfy MinVersion and MaxVersion") } - clientHelloVersion := supportedVersions[0] + clientHelloVersion := config.maxSupportedVersion() // The version at the beginning of the ClientHello was capped at TLS 1.2 // for compatibility reasons. The supported_versions extension is used // to negotiate versions now. See RFC 8446, Section 4.2.1. @@ -146,6 +146,7 @@ func (c *Conn) clientHandshake() (err error) { if err != nil { return err } + c.serverName = hello.serverName cacheKey, session, earlySecret, binderKey := c.loadSession(hello) if cacheKey != "" && session != nil { @@ -181,6 +182,18 @@ func (c *Conn) clientHandshake() (err error) { return err } + // If we are negotiating a protocol version that's lower than what we + // support, check for the server downgrade canaries. + // See RFC 8446, Section 4.1.3. + maxVers := c.config.maxSupportedVersion() + tls12Downgrade := string(serverHello.random[24:]) == downgradeCanaryTLS12 + tls11Downgrade := string(serverHello.random[24:]) == downgradeCanaryTLS11 + if maxVers == VersionTLS13 && c.vers <= VersionTLS12 && (tls12Downgrade || tls11Downgrade) || + maxVers == VersionTLS12 && c.vers <= VersionTLS11 && tls11Downgrade { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: downgrade attempt detected, possibly due to a MitM attack or a broken middlebox") + } + if c.vers == VersionTLS13 { hs := &clientHandshakeStateTLS13{ c: c, @@ -376,6 +389,7 @@ func (hs *clientHandshakeState) handshake() error { hs.finishedHash.Write(hs.serverHello.marshal()) c.buffering = true + c.didResume = isResume if isResume { if err := hs.establishKeys(); err != nil { return err @@ -387,6 +401,15 @@ func (hs *clientHandshakeState) handshake() error { return err } c.clientFinishedIsFirst = false + // Make sure the connection is still being verified whether or not this + // is a resumption. Resumptions currently don't reverify certificates so + // they don't call verifyServerCertificate. See Issue 31641. + if c.config.VerifyConnection != nil { + if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { + c.sendAlert(alertBadCertificate) + return err + } + } if err := hs.sendFinished(c.clientFinished[:]); err != nil { return err } @@ -416,7 +439,6 @@ func (hs *clientHandshakeState) handshake() error { } c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random) - c.didResume = isResume atomic.StoreUint32(&c.handshakeStatus, 1) return nil @@ -446,25 +468,6 @@ func (hs *clientHandshakeState) doFullHandshake() error { } hs.finishedHash.Write(certMsg.marshal()) - if c.handshakes == 0 { - // If this is the first handshake on a connection, process and - // (optionally) verify the server's certificates. - if err := c.verifyServerCertificate(certMsg.certificates); err != nil { - return err - } - } else { - // This is a renegotiation handshake. We require that the - // server's identity (i.e. leaf certificate) is unchanged and - // thus any previous trust decision is still valid. - // - // See https://mitls.org/pages/attacks/3SHAKE for the - // motivation behind this requirement. - if !bytes.Equal(c.peerCertificates[0].Raw, certMsg.certificates[0]) { - c.sendAlert(alertBadCertificate) - return errors.New("tls: server's identity changed during renegotiation") - } - } - msg, err = c.readHandshake() if err != nil { return err @@ -493,6 +496,25 @@ func (hs *clientHandshakeState) doFullHandshake() error { } } + if c.handshakes == 0 { + // If this is the first handshake on a connection, process and + // (optionally) verify the server's certificates. + if err := c.verifyServerCertificate(certMsg.certificates); err != nil { + return err + } + } else { + // This is a renegotiation handshake. We require that the + // server's identity (i.e. leaf certificate) is unchanged and + // thus any previous trust decision is still valid. + // + // See https://mitls.org/pages/attacks/3SHAKE for the + // motivation behind this requirement. + if !bytes.Equal(c.peerCertificates[0].Raw, certMsg.certificates[0]) { + c.sendAlert(alertBadCertificate) + return errors.New("tls: server's identity changed during renegotiation") + } + } + keyAgreement := hs.suite.ka(c.vers) skx, ok := msg.(*serverKeyExchangeMsg) @@ -706,10 +728,17 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) { return false, errors.New("tls: server resumed a session with a different cipher suite") } - // Restore masterSecret and peerCerts from previous state + // Restore masterSecret, peerCerts, and ocspResponse from previous state hs.masterSecret = hs.session.masterSecret c.peerCertificates = hs.session.serverCertificates c.verifiedChains = hs.session.verifiedChains + c.ocspResponse = hs.session.ocspResponse + // Let the ServerHello SCTs override the session SCTs from the original + // connection, if any are provided + if len(c.scts) == 0 && len(hs.session.scts) != 0 { + c.scts = hs.session.scts + } + return true, nil } @@ -766,6 +795,8 @@ func (hs *clientHandshakeState) readSessionTicket() error { serverCertificates: c.peerCertificates, verifiedChains: c.verifiedChains, receivedAt: c.config.time(), + ocspResponse: c.ocspResponse, + scts: c.scts, } return nil @@ -819,13 +850,6 @@ func (c *Conn) verifyServerCertificate(certificates [][]byte) error { } } - if c.config.VerifyPeerCertificate != nil { - if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - switch certs[0].PublicKey.(type) { case *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey: break @@ -836,17 +860,23 @@ func (c *Conn) verifyServerCertificate(certificates [][]byte) error { c.peerCertificates = certs + if c.config.VerifyPeerCertificate != nil { + if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil { + c.sendAlert(alertBadCertificate) + return err + } + } + + if c.config.VerifyConnection != nil { + if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { + c.sendAlert(alertBadCertificate) + return err + } + } + return nil } -// tls11SignatureSchemes contains the signature schemes that we synthesise for -// a TLS <= 1.1 connection, based on the supported certificate types. -var ( - tls11SignatureSchemes = []SignatureScheme{ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1} - tls11SignatureSchemesECDSA = tls11SignatureSchemes[:3] - tls11SignatureSchemesRSA = tls11SignatureSchemes[3:] -) - // certificateRequestInfoFromMsg generates a CertificateRequestInfo from a TLS // <= 1.2 CertificateRequest, making an effort to fill in missing information. func certificateRequestInfoFromMsg(vers uint16, certReq *certificateRequestMsg) *CertificateRequestInfo { @@ -866,17 +896,25 @@ func certificateRequestInfoFromMsg(vers uint16, certReq *certificateRequestMsg) } if !certReq.hasSignatureAlgorithm { - // Prior to TLS 1.2, the signature schemes were not - // included in the certificate request message. In this - // case we use a plausible list based on the acceptable - // certificate types. + // Prior to TLS 1.2, signature schemes did not exist. In this case we + // make up a list based on the acceptable certificate types, to help + // GetClientCertificate and SupportsCertificate select the right certificate. + // The hash part of the SignatureScheme is a lie here, because + // TLS 1.0 and 1.1 always use MD5+SHA1 for RSA and SHA1 for ECDSA. switch { case rsaAvail && ecAvail: - cri.SignatureSchemes = tls11SignatureSchemes + cri.SignatureSchemes = []SignatureScheme{ + ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512, + PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1, + } case rsaAvail: - cri.SignatureSchemes = tls11SignatureSchemesRSA + cri.SignatureSchemes = []SignatureScheme{ + PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1, + } case ecAvail: - cri.SignatureSchemes = tls11SignatureSchemesECDSA + cri.SignatureSchemes = []SignatureScheme{ + ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512, + } } return cri } diff --git a/libgo/go/crypto/tls/handshake_client_test.go b/libgo/go/crypto/tls/handshake_client_test.go index 6bd3c374ce2..12b0254123e 100644 --- a/libgo/go/crypto/tls/handshake_client_test.go +++ b/libgo/go/crypto/tls/handshake_client_test.go @@ -19,6 +19,7 @@ import ( "os" "os/exec" "path/filepath" + "reflect" "strconv" "strings" "testing" @@ -907,6 +908,9 @@ func testResumption(t *testing.T, version uint16) { if didResume && (hs.PeerCertificates == nil || hs.VerifiedChains == nil) { t.Fatalf("expected non-nil certificates after resumption. Got peerCertificates: %#v, verifiedCertificates: %#v", hs.PeerCertificates, hs.VerifiedChains) } + if got, want := hs.ServerName, clientConfig.ServerName; got != want { + t.Errorf("%s: server name %s, want %s", test, got, want) + } } getTicket := func() []byte { @@ -937,6 +941,21 @@ func testResumption(t *testing.T, version uint16) { t.Fatal("ticket didn't change after resumption") } + // An old session ticket can resume, but the server will provide a ticket encrypted with a fresh key. + serverConfig.Time = func() time.Time { return time.Now().Add(24*time.Hour + time.Minute) } + testResumeState("ResumeWithOldTicket", true) + if bytes.Equal(ticket[:ticketKeyNameLen], getTicket()[:ticketKeyNameLen]) { + t.Fatal("old first ticket matches the fresh one") + } + + // Now the session tickey key is expired, so a full handshake should occur. + serverConfig.Time = func() time.Time { return time.Now().Add(24*8*time.Hour + time.Minute) } + testResumeState("ResumeWithExpiredTicket", false) + if bytes.Equal(ticket, getTicket()) { + t.Fatal("expired first ticket matches the fresh one") + } + + serverConfig.Time = func() time.Time { return time.Now() } // reset the time back key1 := randomKey() serverConfig.SetSessionTicketKeys([][32]byte{key1}) @@ -952,6 +971,39 @@ func testResumption(t *testing.T, version uint16) { } testResumeState("KeyChangeFinish", true) + // Age the session ticket a bit, but not yet expired. + serverConfig.Time = func() time.Time { return time.Now().Add(24*time.Hour + time.Minute) } + testResumeState("OldSessionTicket", true) + ticket = getTicket() + // Expire the session ticket, which would force a full handshake. + serverConfig.Time = func() time.Time { return time.Now().Add(24*8*time.Hour + time.Minute) } + testResumeState("ExpiredSessionTicket", false) + if bytes.Equal(ticket, getTicket()) { + t.Fatal("new ticket wasn't provided after old ticket expired") + } + + // Age the session ticket a bit at a time, but don't expire it. + d := 0 * time.Hour + for i := 0; i < 13; i++ { + d += 12 * time.Hour + serverConfig.Time = func() time.Time { return time.Now().Add(d) } + testResumeState("OldSessionTicket", true) + } + // Expire it (now a little more than 7 days) and make sure a full + // handshake occurs for TLS 1.2. Resumption should still occur for + // TLS 1.3 since the client should be using a fresh ticket sent over + // by the server. + d += 12 * time.Hour + serverConfig.Time = func() time.Time { return time.Now().Add(d) } + if version == VersionTLS13 { + testResumeState("ExpiredSessionTicket", true) + } else { + testResumeState("ExpiredSessionTicket", false) + } + if bytes.Equal(ticket, getTicket()) { + t.Fatal("new ticket wasn't provided after old ticket expired") + } + // Reset serverConfig to ensure that calling SetSessionTicketKeys // before the serverConfig is used works. serverConfig = &Config{ @@ -1413,6 +1465,228 @@ func TestServerSelectingUnconfiguredCipherSuite(t *testing.T) { } } +func TestVerifyConnection(t *testing.T) { + t.Run("TLSv12", func(t *testing.T) { testVerifyConnection(t, VersionTLS12) }) + t.Run("TLSv13", func(t *testing.T) { testVerifyConnection(t, VersionTLS13) }) +} + +func testVerifyConnection(t *testing.T, version uint16) { + checkFields := func(c ConnectionState, called *int, errorType string) error { + if c.Version != version { + return fmt.Errorf("%s: got Version %v, want %v", errorType, c.Version, version) + } + if c.HandshakeComplete { + return fmt.Errorf("%s: got HandshakeComplete, want false", errorType) + } + if c.ServerName != "example.golang" { + return fmt.Errorf("%s: got ServerName %s, want %s", errorType, c.ServerName, "example.golang") + } + if c.NegotiatedProtocol != "protocol1" { + return fmt.Errorf("%s: got NegotiatedProtocol %s, want %s", errorType, c.NegotiatedProtocol, "protocol1") + } + if c.CipherSuite == 0 { + return fmt.Errorf("%s: got CipherSuite 0, want non-zero", errorType) + } + wantDidResume := false + if *called == 2 { // if this is the second time, then it should be a resumption + wantDidResume = true + } + if c.DidResume != wantDidResume { + return fmt.Errorf("%s: got DidResume %t, want %t", errorType, c.DidResume, wantDidResume) + } + return nil + } + + tests := []struct { + name string + configureServer func(*Config, *int) + configureClient func(*Config, *int) + }{ + { + name: "RequireAndVerifyClientCert", + configureServer: func(config *Config, called *int) { + config.ClientAuth = RequireAndVerifyClientCert + config.VerifyConnection = func(c ConnectionState) error { + *called++ + if l := len(c.PeerCertificates); l != 1 { + return fmt.Errorf("server: got len(PeerCertificates) = %d, wanted 1", l) + } + if len(c.VerifiedChains) == 0 { + return fmt.Errorf("server: got len(VerifiedChains) = 0, wanted non-zero") + } + return checkFields(c, called, "server") + } + }, + configureClient: func(config *Config, called *int) { + config.VerifyConnection = func(c ConnectionState) error { + *called++ + if l := len(c.PeerCertificates); l != 1 { + return fmt.Errorf("client: got len(PeerCertificates) = %d, wanted 1", l) + } + if len(c.VerifiedChains) == 0 { + return fmt.Errorf("client: got len(VerifiedChains) = 0, wanted non-zero") + } + if c.DidResume { + return nil + // The SCTs and OCSP Responce are dropped on resumption. + // See http://golang.org/issue/39075. + } + if len(c.OCSPResponse) == 0 { + return fmt.Errorf("client: got len(OCSPResponse) = 0, wanted non-zero") + } + if len(c.SignedCertificateTimestamps) == 0 { + return fmt.Errorf("client: got len(SignedCertificateTimestamps) = 0, wanted non-zero") + } + return checkFields(c, called, "client") + } + }, + }, + { + name: "InsecureSkipVerify", + configureServer: func(config *Config, called *int) { + config.ClientAuth = RequireAnyClientCert + config.InsecureSkipVerify = true + config.VerifyConnection = func(c ConnectionState) error { + *called++ + if l := len(c.PeerCertificates); l != 1 { + return fmt.Errorf("server: got len(PeerCertificates) = %d, wanted 1", l) + } + if c.VerifiedChains != nil { + return fmt.Errorf("server: got Verified Chains %v, want nil", c.VerifiedChains) + } + return checkFields(c, called, "server") + } + }, + configureClient: func(config *Config, called *int) { + config.InsecureSkipVerify = true + config.VerifyConnection = func(c ConnectionState) error { + *called++ + if l := len(c.PeerCertificates); l != 1 { + return fmt.Errorf("client: got len(PeerCertificates) = %d, wanted 1", l) + } + if c.VerifiedChains != nil { + return fmt.Errorf("server: got Verified Chains %v, want nil", c.VerifiedChains) + } + if c.DidResume { + return nil + // The SCTs and OCSP Responce are dropped on resumption. + // See http://golang.org/issue/39075. + } + if len(c.OCSPResponse) == 0 { + return fmt.Errorf("client: got len(OCSPResponse) = 0, wanted non-zero") + } + if len(c.SignedCertificateTimestamps) == 0 { + return fmt.Errorf("client: got len(SignedCertificateTimestamps) = 0, wanted non-zero") + } + return checkFields(c, called, "client") + } + }, + }, + { + name: "NoClientCert", + configureServer: func(config *Config, called *int) { + config.ClientAuth = NoClientCert + config.VerifyConnection = func(c ConnectionState) error { + *called++ + return checkFields(c, called, "server") + } + }, + configureClient: func(config *Config, called *int) { + config.VerifyConnection = func(c ConnectionState) error { + *called++ + return checkFields(c, called, "client") + } + }, + }, + { + name: "RequestClientCert", + configureServer: func(config *Config, called *int) { + config.ClientAuth = RequestClientCert + config.VerifyConnection = func(c ConnectionState) error { + *called++ + return checkFields(c, called, "server") + } + }, + configureClient: func(config *Config, called *int) { + config.Certificates = nil // clear the client cert + config.VerifyConnection = func(c ConnectionState) error { + *called++ + if l := len(c.PeerCertificates); l != 1 { + return fmt.Errorf("client: got len(PeerCertificates) = %d, wanted 1", l) + } + if len(c.VerifiedChains) == 0 { + return fmt.Errorf("client: got len(VerifiedChains) = 0, wanted non-zero") + } + if c.DidResume { + return nil + // The SCTs and OCSP Responce are dropped on resumption. + // See http://golang.org/issue/39075. + } + if len(c.OCSPResponse) == 0 { + return fmt.Errorf("client: got len(OCSPResponse) = 0, wanted non-zero") + } + if len(c.SignedCertificateTimestamps) == 0 { + return fmt.Errorf("client: got len(SignedCertificateTimestamps) = 0, wanted non-zero") + } + return checkFields(c, called, "client") + } + }, + }, + } + for _, test := range tests { + issuer, err := x509.ParseCertificate(testRSACertificateIssuer) + if err != nil { + panic(err) + } + rootCAs := x509.NewCertPool() + rootCAs.AddCert(issuer) + + var serverCalled, clientCalled int + + serverConfig := &Config{ + MaxVersion: version, + Certificates: []Certificate{testConfig.Certificates[0]}, + ClientCAs: rootCAs, + NextProtos: []string{"protocol1"}, + } + serverConfig.Certificates[0].SignedCertificateTimestamps = [][]byte{[]byte("dummy sct 1"), []byte("dummy sct 2")} + serverConfig.Certificates[0].OCSPStaple = []byte("dummy ocsp") + test.configureServer(serverConfig, &serverCalled) + + clientConfig := &Config{ + MaxVersion: version, + ClientSessionCache: NewLRUClientSessionCache(32), + RootCAs: rootCAs, + ServerName: "example.golang", + Certificates: []Certificate{testConfig.Certificates[0]}, + NextProtos: []string{"protocol1"}, + } + test.configureClient(clientConfig, &clientCalled) + + testHandshakeState := func(name string, didResume bool) { + _, hs, err := testHandshake(t, clientConfig, serverConfig) + if err != nil { + t.Fatalf("%s: handshake failed: %s", name, err) + } + if hs.DidResume != didResume { + t.Errorf("%s: resumed: %v, expected: %v", name, hs.DidResume, didResume) + } + wantCalled := 1 + if didResume { + wantCalled = 2 // resumption would mean this is the second time it was called in this test + } + if clientCalled != wantCalled { + t.Errorf("%s: expected client VerifyConnection called %d times, did %d times", name, wantCalled, clientCalled) + } + if serverCalled != wantCalled { + t.Errorf("%s: expected server VerifyConnection called %d times, did %d times", name, wantCalled, serverCalled) + } + } + testHandshakeState(fmt.Sprintf("%s-FullHandshake", test.name), false) + testHandshakeState(fmt.Sprintf("%s-Resumption", test.name), true) + } +} + func TestVerifyPeerCertificate(t *testing.T) { t.Run("TLSv12", func(t *testing.T) { testVerifyPeerCertificate(t, VersionTLS12) }) t.Run("TLSv13", func(t *testing.T) { testVerifyPeerCertificate(t, VersionTLS13) }) @@ -1431,7 +1705,7 @@ func testVerifyPeerCertificate(t *testing.T, version uint16) { sentinelErr := errors.New("TestVerifyPeerCertificate") - verifyCallback := func(called *bool, rawCerts [][]byte, validatedChains [][]*x509.Certificate) error { + verifyPeerCertificateCallback := func(called *bool, rawCerts [][]byte, validatedChains [][]*x509.Certificate) error { if l := len(rawCerts); l != 1 { return fmt.Errorf("got len(rawCerts) = %d, wanted 1", l) } @@ -1441,6 +1715,19 @@ func testVerifyPeerCertificate(t *testing.T, version uint16) { *called = true return nil } + verifyConnectionCallback := func(called *bool, isClient bool, c ConnectionState) error { + if l := len(c.PeerCertificates); l != 1 { + return fmt.Errorf("got len(PeerCertificates) = %d, wanted 1", l) + } + if len(c.VerifiedChains) == 0 { + return fmt.Errorf("got len(VerifiedChains) = 0, wanted non-zero") + } + if isClient && len(c.OCSPResponse) == 0 { + return fmt.Errorf("got len(OCSPResponse) = 0, wanted non-zero") + } + *called = true + return nil + } tests := []struct { configureServer func(*Config, *bool) @@ -1451,13 +1738,13 @@ func testVerifyPeerCertificate(t *testing.T, version uint16) { configureServer: func(config *Config, called *bool) { config.InsecureSkipVerify = false config.VerifyPeerCertificate = func(rawCerts [][]byte, validatedChains [][]*x509.Certificate) error { - return verifyCallback(called, rawCerts, validatedChains) + return verifyPeerCertificateCallback(called, rawCerts, validatedChains) } }, configureClient: func(config *Config, called *bool) { config.InsecureSkipVerify = false config.VerifyPeerCertificate = func(rawCerts [][]byte, validatedChains [][]*x509.Certificate) error { - return verifyCallback(called, rawCerts, validatedChains) + return verifyPeerCertificateCallback(called, rawCerts, validatedChains) } }, validate: func(t *testing.T, testNo int, clientCalled, serverCalled bool, clientErr, serverErr error) { @@ -1538,6 +1825,116 @@ func testVerifyPeerCertificate(t *testing.T, version uint16) { } }, }, + { + configureServer: func(config *Config, called *bool) { + config.InsecureSkipVerify = false + config.VerifyConnection = func(c ConnectionState) error { + return verifyConnectionCallback(called, false, c) + } + }, + configureClient: func(config *Config, called *bool) { + config.InsecureSkipVerify = false + config.VerifyConnection = func(c ConnectionState) error { + return verifyConnectionCallback(called, true, c) + } + }, + validate: func(t *testing.T, testNo int, clientCalled, serverCalled bool, clientErr, serverErr error) { + if clientErr != nil { + t.Errorf("test[%d]: client handshake failed: %v", testNo, clientErr) + } + if serverErr != nil { + t.Errorf("test[%d]: server handshake failed: %v", testNo, serverErr) + } + if !clientCalled { + t.Errorf("test[%d]: client did not call callback", testNo) + } + if !serverCalled { + t.Errorf("test[%d]: server did not call callback", testNo) + } + }, + }, + { + configureServer: func(config *Config, called *bool) { + config.InsecureSkipVerify = false + config.VerifyConnection = func(c ConnectionState) error { + return sentinelErr + } + }, + configureClient: func(config *Config, called *bool) { + config.InsecureSkipVerify = false + config.VerifyConnection = nil + }, + validate: func(t *testing.T, testNo int, clientCalled, serverCalled bool, clientErr, serverErr error) { + if serverErr != sentinelErr { + t.Errorf("#%d: got server error %v, wanted sentinelErr", testNo, serverErr) + } + }, + }, + { + configureServer: func(config *Config, called *bool) { + config.InsecureSkipVerify = false + config.VerifyConnection = nil + }, + configureClient: func(config *Config, called *bool) { + config.InsecureSkipVerify = false + config.VerifyConnection = func(c ConnectionState) error { + return sentinelErr + } + }, + validate: func(t *testing.T, testNo int, clientCalled, serverCalled bool, clientErr, serverErr error) { + if clientErr != sentinelErr { + t.Errorf("#%d: got client error %v, wanted sentinelErr", testNo, clientErr) + } + }, + }, + { + configureServer: func(config *Config, called *bool) { + config.InsecureSkipVerify = false + config.VerifyPeerCertificate = func(rawCerts [][]byte, validatedChains [][]*x509.Certificate) error { + return verifyPeerCertificateCallback(called, rawCerts, validatedChains) + } + config.VerifyConnection = func(c ConnectionState) error { + return sentinelErr + } + }, + configureClient: func(config *Config, called *bool) { + config.InsecureSkipVerify = false + config.VerifyPeerCertificate = nil + config.VerifyConnection = nil + }, + validate: func(t *testing.T, testNo int, clientCalled, serverCalled bool, clientErr, serverErr error) { + if serverErr != sentinelErr { + t.Errorf("#%d: got server error %v, wanted sentinelErr", testNo, serverErr) + } + if !serverCalled { + t.Errorf("test[%d]: server did not call callback", testNo) + } + }, + }, + { + configureServer: func(config *Config, called *bool) { + config.InsecureSkipVerify = false + config.VerifyPeerCertificate = nil + config.VerifyConnection = nil + }, + configureClient: func(config *Config, called *bool) { + config.InsecureSkipVerify = false + config.VerifyPeerCertificate = func(rawCerts [][]byte, validatedChains [][]*x509.Certificate) error { + return verifyPeerCertificateCallback(called, rawCerts, validatedChains) + } + config.VerifyConnection = func(c ConnectionState) error { + return sentinelErr + } + }, + validate: func(t *testing.T, testNo int, clientCalled, serverCalled bool, clientErr, serverErr error) { + if clientErr != sentinelErr { + t.Errorf("#%d: got client error %v, wanted sentinelErr", testNo, clientErr) + } + if !clientCalled { + t.Errorf("test[%d]: client did not call callback", testNo) + } + }, + }, } for i, test := range tests { @@ -1553,6 +1950,11 @@ func testVerifyPeerCertificate(t *testing.T, version uint16) { config.ClientCAs = rootCAs config.Time = now config.MaxVersion = version + config.Certificates = make([]Certificate, 1) + config.Certificates[0].Certificate = [][]byte{testRSACertificate} + config.Certificates[0].PrivateKey = testRSAPrivateKey + config.Certificates[0].SignedCertificateTimestamps = [][]byte{[]byte("dummy sct 1"), []byte("dummy sct 2")} + config.Certificates[0].OCSPStaple = []byte("dummy ocsp") test.configureServer(config, &serverCalled) err = Server(s, config).Handshake() @@ -1748,7 +2150,7 @@ func TestHandshakeRace(t *testing.T) { startWrite := make(chan struct{}) startRead := make(chan struct{}) - readDone := make(chan struct{}) + readDone := make(chan struct{}, 1) client := Client(c, testConfig) go func() { @@ -1984,3 +2386,128 @@ func TestCloseClientConnectionOnIdleServer(t *testing.T) { t.Errorf("Error expected, but no error returned") } } + +func testDowngradeCanary(t *testing.T, clientVersion, serverVersion uint16) error { + defer func() { testingOnlyForceDowngradeCanary = false }() + testingOnlyForceDowngradeCanary = true + + clientConfig := testConfig.Clone() + clientConfig.MaxVersion = clientVersion + serverConfig := testConfig.Clone() + serverConfig.MaxVersion = serverVersion + _, _, err := testHandshake(t, clientConfig, serverConfig) + return err +} + +func TestDowngradeCanary(t *testing.T) { + if err := testDowngradeCanary(t, VersionTLS13, VersionTLS12); err == nil { + t.Errorf("downgrade from TLS 1.3 to TLS 1.2 was not detected") + } + if testing.Short() { + t.Skip("skipping the rest of the checks in short mode") + } + if err := testDowngradeCanary(t, VersionTLS13, VersionTLS11); err == nil { + t.Errorf("downgrade from TLS 1.3 to TLS 1.1 was not detected") + } + if err := testDowngradeCanary(t, VersionTLS13, VersionTLS10); err == nil { + t.Errorf("downgrade from TLS 1.3 to TLS 1.0 was not detected") + } + if err := testDowngradeCanary(t, VersionTLS12, VersionTLS11); err == nil { + t.Errorf("downgrade from TLS 1.2 to TLS 1.1 was not detected") + } + if err := testDowngradeCanary(t, VersionTLS12, VersionTLS10); err == nil { + t.Errorf("downgrade from TLS 1.2 to TLS 1.0 was not detected") + } + if err := testDowngradeCanary(t, VersionTLS13, VersionTLS13); err != nil { + t.Errorf("server unexpectedly sent downgrade canary for TLS 1.3") + } + if err := testDowngradeCanary(t, VersionTLS12, VersionTLS12); err != nil { + t.Errorf("client didn't ignore expected TLS 1.2 canary") + } + if err := testDowngradeCanary(t, VersionTLS11, VersionTLS11); err != nil { + t.Errorf("client unexpectedly reacted to a canary in TLS 1.1") + } + if err := testDowngradeCanary(t, VersionTLS10, VersionTLS10); err != nil { + t.Errorf("client unexpectedly reacted to a canary in TLS 1.0") + } +} + +func TestResumptionKeepsOCSPAndSCT(t *testing.T) { + t.Run("TLSv12", func(t *testing.T) { testResumptionKeepsOCSPAndSCT(t, VersionTLS12) }) + t.Run("TLSv13", func(t *testing.T) { testResumptionKeepsOCSPAndSCT(t, VersionTLS13) }) +} + +func testResumptionKeepsOCSPAndSCT(t *testing.T, ver uint16) { + issuer, err := x509.ParseCertificate(testRSACertificateIssuer) + if err != nil { + t.Fatalf("failed to parse test issuer") + } + roots := x509.NewCertPool() + roots.AddCert(issuer) + clientConfig := &Config{ + MaxVersion: ver, + ClientSessionCache: NewLRUClientSessionCache(32), + ServerName: "example.golang", + RootCAs: roots, + } + serverConfig := testConfig.Clone() + serverConfig.MaxVersion = ver + serverConfig.Certificates[0].OCSPStaple = []byte{1, 2, 3} + serverConfig.Certificates[0].SignedCertificateTimestamps = [][]byte{{4, 5, 6}} + + _, ccs, err := testHandshake(t, clientConfig, serverConfig) + if err != nil { + t.Fatalf("handshake failed: %s", err) + } + // after a new session we expect to see OCSPResponse and + // SignedCertificateTimestamps populated as usual + if !bytes.Equal(ccs.OCSPResponse, serverConfig.Certificates[0].OCSPStaple) { + t.Errorf("client ConnectionState contained unexpected OCSPResponse: wanted %v, got %v", + serverConfig.Certificates[0].OCSPStaple, ccs.OCSPResponse) + } + if !reflect.DeepEqual(ccs.SignedCertificateTimestamps, serverConfig.Certificates[0].SignedCertificateTimestamps) { + t.Errorf("client ConnectionState contained unexpected SignedCertificateTimestamps: wanted %v, got %v", + serverConfig.Certificates[0].SignedCertificateTimestamps, ccs.SignedCertificateTimestamps) + } + + // if the server doesn't send any SCTs, repopulate the old SCTs + oldSCTs := serverConfig.Certificates[0].SignedCertificateTimestamps + serverConfig.Certificates[0].SignedCertificateTimestamps = nil + _, ccs, err = testHandshake(t, clientConfig, serverConfig) + if err != nil { + t.Fatalf("handshake failed: %s", err) + } + if !ccs.DidResume { + t.Fatalf("expected session to be resumed") + } + // after a resumed session we also expect to see OCSPResponse + // and SignedCertificateTimestamps populated + if !bytes.Equal(ccs.OCSPResponse, serverConfig.Certificates[0].OCSPStaple) { + t.Errorf("client ConnectionState contained unexpected OCSPResponse after resumption: wanted %v, got %v", + serverConfig.Certificates[0].OCSPStaple, ccs.OCSPResponse) + } + if !reflect.DeepEqual(ccs.SignedCertificateTimestamps, oldSCTs) { + t.Errorf("client ConnectionState contained unexpected SignedCertificateTimestamps after resumption: wanted %v, got %v", + oldSCTs, ccs.SignedCertificateTimestamps) + } + + // Only test overriding the SCTs for TLS 1.2, since in 1.3 + // the server won't send the message containing them + if ver == VersionTLS13 { + return + } + + // if the server changes the SCTs it sends, they should override the saved SCTs + serverConfig.Certificates[0].SignedCertificateTimestamps = [][]byte{{7, 8, 9}} + _, ccs, err = testHandshake(t, clientConfig, serverConfig) + if err != nil { + t.Fatalf("handshake failed: %s", err) + } + if !ccs.DidResume { + t.Fatalf("expected session to be resumed") + } + if !reflect.DeepEqual(ccs.SignedCertificateTimestamps, serverConfig.Certificates[0].SignedCertificateTimestamps) { + t.Errorf("client ConnectionState contained unexpected SignedCertificateTimestamps after resumption: wanted %v, got %v", + serverConfig.Certificates[0].SignedCertificateTimestamps, ccs.SignedCertificateTimestamps) + } +} diff --git a/libgo/go/crypto/tls/handshake_client_tls13.go b/libgo/go/crypto/tls/handshake_client_tls13.go index 8994591ee42..9c61105cf73 100644 --- a/libgo/go/crypto/tls/handshake_client_tls13.go +++ b/libgo/go/crypto/tls/handshake_client_tls13.go @@ -176,51 +176,62 @@ func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error { c := hs.c // The first ClientHello gets double-hashed into the transcript upon a - // HelloRetryRequest. See RFC 8446, Section 4.4.1. + // HelloRetryRequest. (The idea is that the server might offload transcript + // storage to the client in the cookie.) See RFC 8446, Section 4.4.1. chHash := hs.transcript.Sum(nil) hs.transcript.Reset() hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))}) hs.transcript.Write(chHash) hs.transcript.Write(hs.serverHello.marshal()) + // The only HelloRetryRequest extensions we support are key_share and + // cookie, and clients must abort the handshake if the HRR would not result + // in any change in the ClientHello. + if hs.serverHello.selectedGroup == 0 && hs.serverHello.cookie == nil { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: server sent an unnecessary HelloRetryRequest message") + } + + if hs.serverHello.cookie != nil { + hs.hello.cookie = hs.serverHello.cookie + } + if hs.serverHello.serverShare.group != 0 { c.sendAlert(alertDecodeError) return errors.New("tls: received malformed key_share extension") } - curveID := hs.serverHello.selectedGroup - if curveID == 0 { - c.sendAlert(alertMissingExtension) - return errors.New("tls: received HelloRetryRequest without selected group") - } - curveOK := false - for _, id := range hs.hello.supportedCurves { - if id == curveID { - curveOK = true - break + // If the server sent a key_share extension selecting a group, ensure it's + // a group we advertised but did not send a key share for, and send a key + // share for it this time. + if curveID := hs.serverHello.selectedGroup; curveID != 0 { + curveOK := false + for _, id := range hs.hello.supportedCurves { + if id == curveID { + curveOK = true + break + } } + if !curveOK { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: server selected unsupported group") + } + if hs.ecdheParams.CurveID() == curveID { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: server sent an unnecessary HelloRetryRequest key_share") + } + if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok { + c.sendAlert(alertInternalError) + return errors.New("tls: CurvePreferences includes unsupported curve") + } + params, err := generateECDHEParameters(c.config.rand(), curveID) + if err != nil { + c.sendAlert(alertInternalError) + return err + } + hs.ecdheParams = params + hs.hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}} } - if !curveOK { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server selected unsupported group") - } - if hs.ecdheParams.CurveID() == curveID { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server sent an unnecessary HelloRetryRequest message") - } - if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok { - c.sendAlert(alertInternalError) - return errors.New("tls: CurvePreferences includes unsupported curve") - } - params, err := generateECDHEParameters(c.config.rand(), curveID) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - hs.ecdheParams = params - hs.hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}} - - hs.hello.cookie = hs.serverHello.cookie hs.hello.raw = nil if len(hs.hello.pskIdentities) > 0 { @@ -323,6 +334,8 @@ func (hs *clientHandshakeStateTLS13) processServerHello() error { c.didResume = true c.peerCertificates = hs.session.serverCertificates c.verifiedChains = hs.session.verifiedChains + c.ocspResponse = hs.session.ocspResponse + c.scts = hs.session.scts return nil } @@ -396,6 +409,15 @@ func (hs *clientHandshakeStateTLS13) readServerCertificate() error { // Either a PSK or a certificate is always used, but not both. // See RFC 8446, Section 4.1.1. if hs.usingPSK { + // Make sure the connection is still being verified whether or not this + // is a resumption. Resumptions currently don't reverify certificates so + // they don't call verifyServerCertificate. See Issue 31641. + if c.config.VerifyConnection != nil { + if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { + c.sendAlert(alertBadCertificate) + return err + } + } return nil } @@ -646,6 +668,8 @@ func (c *Conn) handleNewSessionTicket(msg *newSessionTicketMsgTLS13) error { nonce: msg.nonce, useBy: c.config.time().Add(lifetime), ageAdd: msg.ageAdd, + ocspResponse: c.ocspResponse, + scts: c.scts, } cacheKey := clientSessionCacheKey(c.conn.RemoteAddr(), c.config) diff --git a/libgo/go/crypto/tls/handshake_messages_test.go b/libgo/go/crypto/tls/handshake_messages_test.go index bef75705129..bb8aea86700 100644 --- a/libgo/go/crypto/tls/handshake_messages_test.go +++ b/libgo/go/crypto/tls/handshake_messages_test.go @@ -308,11 +308,10 @@ func (*sessionState) Generate(rand *rand.Rand, size int) reflect.Value { s := &sessionState{} s.vers = uint16(rand.Intn(10000)) s.cipherSuite = uint16(rand.Intn(10000)) - s.masterSecret = randomBytes(rand.Intn(100), rand) - numCerts := rand.Intn(20) - s.certificates = make([][]byte, numCerts) - for i := 0; i < numCerts; i++ { - s.certificates[i] = randomBytes(rand.Intn(10)+1, rand) + s.masterSecret = randomBytes(rand.Intn(100)+1, rand) + s.createdAt = uint64(rand.Int63()) + for i := 0; i < rand.Intn(20); i++ { + s.certificates = append(s.certificates, randomBytes(rand.Intn(500)+1, rand)) } return reflect.ValueOf(s) } diff --git a/libgo/go/crypto/tls/handshake_server.go b/libgo/go/crypto/tls/handshake_server.go index b16415a03c2..16d3e643f0b 100644 --- a/libgo/go/crypto/tls/handshake_server.go +++ b/libgo/go/crypto/tls/handshake_server.go @@ -15,6 +15,7 @@ import ( "fmt" "io" "sync/atomic" + "time" ) // serverHandshakeState contains details of a server handshake in progress. @@ -36,10 +37,6 @@ type serverHandshakeState struct { // serverHandshake performs a TLS handshake as a server. func (c *Conn) serverHandshake() error { - // If this is the first server handshake, we generate a random key to - // encrypt the tickets with. - c.config.serverInitOnce.Do(func() { c.config.serverInit(nil) }) - clientHello, err := c.readClientHello() if err != nil { return err @@ -71,19 +68,15 @@ func (hs *serverHandshakeState) handshake() error { c.buffering = true if hs.checkForResumption() { // The client has included a session ticket and so we do an abbreviated handshake. + c.didResume = true if err := hs.doResumeHandshake(); err != nil { return err } if err := hs.establishKeys(); err != nil { return err } - // ticketSupported is set in a resumption handshake if the - // ticket from the client was encrypted with an old session - // ticket key and thus a refreshed ticket should be sent. - if hs.hello.ticketSupported { - if err := hs.sendSessionTicket(); err != nil { - return err - } + if err := hs.sendSessionTicket(); err != nil { + return err } if err := hs.sendFinished(c.serverFinished[:]); err != nil { return err @@ -95,7 +88,6 @@ func (hs *serverHandshakeState) handshake() error { if err := hs.readFinished(nil); err != nil { return err } - c.didResume = true } else { // The client didn't include a session ticket, or it wasn't // valid so we do a full handshake. @@ -142,16 +134,18 @@ func (c *Conn) readClientHello() (*clientHelloMsg, error) { return nil, unexpectedMessageError(clientHello, msg) } + var configForClient *Config + originalConfig := c.config if c.config.GetConfigForClient != nil { chi := clientHelloInfo(c, clientHello) - if newConfig, err := c.config.GetConfigForClient(chi); err != nil { + if configForClient, err = c.config.GetConfigForClient(chi); err != nil { c.sendAlert(alertInternalError) return nil, err - } else if newConfig != nil { - newConfig.serverInitOnce.Do(func() { newConfig.serverInit(c.config) }) - c.config = newConfig + } else if configForClient != nil { + c.config = configForClient } } + c.ticketKeys = originalConfig.ticketKeys(configForClient) clientVersions := clientHello.supportedVersions if len(clientHello.supportedVersions) == 0 { @@ -193,7 +187,7 @@ func (hs *serverHandshakeState) processClientHello() error { serverRandom := hs.hello.random // Downgrade protection canaries. See RFC 8446, Section 4.1.3. maxVers := c.config.maxSupportedVersion() - if maxVers >= VersionTLS12 && c.vers < maxVers { + if maxVers >= VersionTLS12 && c.vers < maxVers || testingOnlyForceDowngradeCanary { if c.vers == VersionTLS12 { copy(serverRandom[24:], downgradeCanaryTLS12) } else { @@ -314,6 +308,7 @@ func (hs *serverHandshakeState) pickCipherSuite() error { c.sendAlert(alertHandshakeFailure) return errors.New("tls: no cipher suite supported by both client and server") } + c.cipherSuite = hs.suite.id for _, id := range hs.clientHello.cipherSuites { if id == TLS_FALLBACK_SCSV { @@ -368,6 +363,11 @@ func (hs *serverHandshakeState) checkForResumption() bool { return false } + createdAt := time.Unix(int64(hs.sessionState.createdAt), 0) + if c.config.time().Sub(createdAt) > maxSessionTicketLifetime { + return false + } + // Never resume a session for a different TLS version. if c.vers != hs.sessionState.vers { return false @@ -408,6 +408,7 @@ func (hs *serverHandshakeState) doResumeHandshake() error { c := hs.c hs.hello.cipherSuite = hs.suite.id + c.cipherSuite = hs.suite.id // We echo the client's session ID in the ServerHello to let it know // that we're doing a resumption. hs.hello.sessionId = hs.clientHello.sessionId @@ -426,6 +427,13 @@ func (hs *serverHandshakeState) doResumeHandshake() error { return err } + if c.config.VerifyConnection != nil { + if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { + c.sendAlert(alertBadCertificate) + return err + } + } + hs.masterSecret = hs.sessionState.masterSecret return nil @@ -550,6 +558,12 @@ func (hs *serverHandshakeState) doFullHandshake() error { return err } } + if c.config.VerifyConnection != nil { + if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { + c.sendAlert(alertBadCertificate) + return err + } + } // Get client key exchange ckx, ok := msg.(*clientKeyExchangeMsg) @@ -675,6 +689,9 @@ func (hs *serverHandshakeState) readFinished(out []byte) error { } func (hs *serverHandshakeState) sendSessionTicket() error { + // ticketSupported is set in a resumption handshake if the + // ticket from the client was encrypted with an old session + // ticket key and thus a refreshed ticket should be sent. if !hs.hello.ticketSupported { return nil } @@ -682,6 +699,13 @@ func (hs *serverHandshakeState) sendSessionTicket() error { c := hs.c m := new(newSessionTicketMsg) + createdAt := uint64(c.config.time().Unix()) + if hs.sessionState != nil { + // If this is re-wrapping an old key, then keep + // the original time it was created. + createdAt = hs.sessionState.createdAt + } + var certsFromClient [][]byte for _, cert := range c.peerCertificates { certsFromClient = append(certsFromClient, cert.Raw) @@ -689,6 +713,7 @@ func (hs *serverHandshakeState) sendSessionTicket() error { state := sessionState{ vers: c.vers, cipherSuite: hs.suite.id, + createdAt: createdAt, masterSecret: hs.masterSecret, certificates: certsFromClient, } @@ -720,7 +745,6 @@ func (hs *serverHandshakeState) sendFinished(out []byte) error { return err } - c.cipherSuite = hs.suite.id copy(out, finished.verifyData) return nil @@ -766,6 +790,19 @@ func (c *Conn) processCertsFromClient(certificate Certificate) error { c.verifiedChains = chains } + c.peerCertificates = certs + c.ocspResponse = certificate.OCSPStaple + c.scts = certificate.SignedCertificateTimestamps + + if len(certs) > 0 { + switch certs[0].PublicKey.(type) { + case *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey: + default: + c.sendAlert(alertUnsupportedCertificate) + return fmt.Errorf("tls: client certificate contains an unsupported public key of type %T", certs[0].PublicKey) + } + } + if c.config.VerifyPeerCertificate != nil { if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil { c.sendAlert(alertBadCertificate) @@ -773,20 +810,6 @@ func (c *Conn) processCertsFromClient(certificate Certificate) error { } } - if len(certs) == 0 { - return nil - } - - switch certs[0].PublicKey.(type) { - case *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey: - default: - c.sendAlert(alertUnsupportedCertificate) - return fmt.Errorf("tls: client certificate contains an unsupported public key of type %T", certs[0].PublicKey) - } - - c.peerCertificates = certs - c.ocspResponse = certificate.OCSPStaple - c.scts = certificate.SignedCertificateTimestamps return nil } diff --git a/libgo/go/crypto/tls/handshake_server_test.go b/libgo/go/crypto/tls/handshake_server_test.go index 1e5da1e12e1..a7a53243129 100644 --- a/libgo/go/crypto/tls/handshake_server_test.go +++ b/libgo/go/crypto/tls/handshake_server_test.go @@ -182,7 +182,7 @@ func TestRenegotiationExtension(t *testing.T) { cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA}, } - bufChan := make(chan []byte) + bufChan := make(chan []byte, 1) c, s := localPipe(t) go func() { @@ -355,7 +355,8 @@ func TestAlertForwarding(t *testing.T) { err := Server(s, testConfig).Handshake() s.Close() - if e, ok := err.(*net.OpError); !ok || e.Err != error(alertUnknownCA) { + var opErr *net.OpError + if !errors.As(err, &opErr) || opErr.Err != error(alertUnknownCA) { t.Errorf("Got error: %s; expected: %s", err, error(alertUnknownCA)) } } @@ -575,11 +576,12 @@ func (test *serverTest) connFromCommand() (conn *recordingConn, child *exec.Cmd, return nil, nil, err } - connChan := make(chan interface{}) + connChan := make(chan interface{}, 1) go func() { tcpConn, err := l.Accept() if err != nil { connChan <- err + return } connChan <- tcpConn }() @@ -1494,12 +1496,8 @@ var getConfigForClientTests = []struct { }, "", func(config *Config) error { - // The value of SessionTicketKey should have been - // duplicated into the per-connection Config. - for i := range config.SessionTicketKey { - if b := config.SessionTicketKey[i]; b != byte(i) { - return fmt.Errorf("SessionTicketKey was not duplicated from original Config: byte %d has value %d", i, b) - } + if config.SessionTicketKey == [32]byte{} { + return fmt.Errorf("expected SessionTicketKey to be set") } return nil }, @@ -1520,10 +1518,8 @@ var getConfigForClientTests = []struct { }, "", func(config *Config) error { - // The session ticket keys should have been duplicated - // into the per-connection Config. - if l := len(config.sessionTicketKeys); l != 1 { - return fmt.Errorf("got len(sessionTicketKeys) == %d, wanted 1", l) + if config.SessionTicketKey == [32]byte{} { + return fmt.Errorf("expected SessionTicketKey to be set") } return nil }, diff --git a/libgo/go/crypto/tls/handshake_server_tls13.go b/libgo/go/crypto/tls/handshake_server_tls13.go index 5432145de46..92d55e0293a 100644 --- a/libgo/go/crypto/tls/handshake_server_tls13.go +++ b/libgo/go/crypto/tls/handshake_server_tls13.go @@ -306,6 +306,7 @@ func (hs *serverHandshakeStateTLS13) checkForResumption() error { return errors.New("tls: invalid PSK binder") } + c.didResume = true if err := c.processCertsFromClient(sessionState.certificate); err != nil { return err } @@ -313,7 +314,6 @@ func (hs *serverHandshakeStateTLS13) checkForResumption() error { hs.hello.selectedIdentityPresent = true hs.hello.selectedIdentity = uint16(i) hs.usingPSK = true - c.didResume = true return nil } @@ -753,6 +753,14 @@ func (hs *serverHandshakeStateTLS13) readClientCertificate() error { c := hs.c if !hs.requestClientCert() { + // Make sure the connection is still being verified whether or not + // the server requested a client certificate. + if c.config.VerifyConnection != nil { + if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { + c.sendAlert(alertBadCertificate) + return err + } + } return nil } @@ -775,6 +783,13 @@ func (hs *serverHandshakeStateTLS13) readClientCertificate() error { return err } + if c.config.VerifyConnection != nil { + if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { + c.sendAlert(alertBadCertificate) + return err + } + } + if len(certMsg.certificate.Certificate) != 0 { msg, err = c.readHandshake() if err != nil { diff --git a/libgo/go/crypto/tls/key_agreement.go b/libgo/go/crypto/tls/key_agreement.go index 03aa861a1d8..7e6534bd465 100644 --- a/libgo/go/crypto/tls/key_agreement.go +++ b/libgo/go/crypto/tls/key_agreement.go @@ -40,7 +40,7 @@ func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certifi if !ok { return nil, errors.New("tls: certificate private key does not implement crypto.Decrypter") } - // Perform constant time RSA PKCS#1 v1.5 decryption + // Perform constant time RSA PKCS #1 v1.5 decryption preMasterSecret, err := priv.Decrypt(config.rand(), ciphertext, &rsa.PKCS1v15DecryptOptions{SessionKeyLen: 48}) if err != nil { return nil, err diff --git a/libgo/go/crypto/tls/key_schedule.go b/libgo/go/crypto/tls/key_schedule.go index 2aab323202f..314016979af 100644 --- a/libgo/go/crypto/tls/key_schedule.go +++ b/libgo/go/crypto/tls/key_schedule.go @@ -173,11 +173,8 @@ func (p *nistParameters) SharedKey(peerPublicKey []byte) []byte { } xShared, _ := curve.ScalarMult(x, y, p.privateKey) - sharedKey := make([]byte, (curve.Params().BitSize+7)>>3) - xBytes := xShared.Bytes() - copy(sharedKey[len(sharedKey)-len(xBytes):], xBytes) - - return sharedKey + sharedKey := make([]byte, (curve.Params().BitSize+7)/8) + return xShared.FillBytes(sharedKey) } type x25519Parameters struct { diff --git a/libgo/go/crypto/tls/link_test.go b/libgo/go/crypto/tls/link_test.go new file mode 100644 index 00000000000..c1fb57e70e2 --- /dev/null +++ b/libgo/go/crypto/tls/link_test.go @@ -0,0 +1,121 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tls + +import ( + "bytes" + "internal/testenv" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "testing" +) + +// Tests that the linker is able to remove references to the Client or Server if unused. +func TestLinkerGC(t *testing.T) { + if testing.Short() { + t.Skip("skipping in short mode") + } + t.Parallel() + goBin := testenv.GoToolPath(t) + testenv.MustHaveGoBuild(t) + + tests := []struct { + name string + program string + want []string + bad []string + }{ + { + name: "empty_import", + program: `package main +import _ "crypto/tls" +func main() {} +`, + bad: []string{ + "tls.(*Conn)", + "type.crypto/tls.clientHandshakeState", + "type.crypto/tls.serverHandshakeState", + }, + }, + { + name: "only_conn", + program: `package main +import "crypto/tls" +var c = new(tls.Conn) +func main() {} +`, + want: []string{"tls.(*Conn)"}, + bad: []string{ + "type.crypto/tls.clientHandshakeState", + "type.crypto/tls.serverHandshakeState", + }, + }, + { + name: "client_and_server", + program: `package main +import "crypto/tls" +func main() { + tls.Dial("", "", nil) + tls.Server(nil, nil) +} +`, + want: []string{ + "crypto/tls.(*Conn).clientHandshake", + "crypto/tls.(*Conn).serverHandshake", + }, + }, + { + name: "only_client", + program: `package main +import "crypto/tls" +func main() { tls.Dial("", "", nil) } +`, + want: []string{ + "crypto/tls.(*Conn).clientHandshake", + }, + bad: []string{ + "crypto/tls.(*Conn).serverHandshake", + }, + }, + // TODO: add only_server like func main() { tls.Server(nil, nil) } + // That currently brings in the client via Conn.handleRenegotiation. + + } + tmpDir := t.TempDir() + goFile := filepath.Join(tmpDir, "x.go") + exeFile := filepath.Join(tmpDir, "x.exe") + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := ioutil.WriteFile(goFile, []byte(tt.program), 0644); err != nil { + t.Fatal(err) + } + os.Remove(exeFile) + cmd := exec.Command(goBin, "build", "-o", "x.exe", "x.go") + cmd.Dir = tmpDir + if out, err := cmd.CombinedOutput(); err != nil { + t.Fatalf("compile: %v, %s", err, out) + } + + cmd = exec.Command(goBin, "tool", "nm", "x.exe") + cmd.Dir = tmpDir + nm, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("nm: %v, %s", err, nm) + } + for _, sym := range tt.want { + if !bytes.Contains(nm, []byte(sym)) { + t.Errorf("expected symbol %q not found", sym) + } + } + for _, sym := range tt.bad { + if bytes.Contains(nm, []byte(sym)) { + t.Errorf("unexpected symbol %q found", sym) + } + } + }) + } +} diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial b/libgo/go/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial index 5f80cb35950..a5d9ee4cdbd 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial +++ b/libgo/go/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial @@ -1,12 +1,11 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 75 01 00 00 71 03 01 a0 fd 51 a6 77 |....u...q....Q.w| -00000010 69 ee 39 14 8d 0f be a6 9c f7 95 aa 63 14 d2 90 |i.9.........c...| -00000020 1e 39 34 2c df d8 e4 92 2b a0 36 00 00 12 c0 0a |.94,....+.6.....| +00000000 16 03 01 00 63 01 00 00 5f 03 01 7a df fa af 20 |....c..._..z... | +00000010 74 5a 83 3b 91 95 b4 9b 57 d8 6b f2 88 2a 68 e8 |tZ.;....W.k..*h.| +00000020 b8 9e e7 88 a6 c5 e7 59 08 ff 9b 00 00 12 c0 0a |.......Y........| 00000030 c0 14 00 39 c0 09 c0 13 00 33 00 35 00 2f 00 ff |...9.....3.5./..| -00000040 01 00 00 36 00 00 00 0e 00 0c 00 00 09 31 32 37 |...6.........127| -00000050 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 00 0a |.0.0.1..........| -00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#| -00000070 00 00 00 16 00 00 00 17 00 00 |..........| +00000040 01 00 00 24 00 0b 00 04 03 00 01 02 00 0a 00 0c |...$............| +00000050 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 00 00 |.............#..| +00000060 00 16 00 00 00 17 00 00 |........| >>> Flow 2 (server to client) 00000000 16 03 01 00 3b 02 00 00 37 03 01 00 00 00 00 00 |....;...7.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| @@ -52,43 +51,43 @@ 00000290 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 |...=.`.\!.;.....| 000002a0 01 00 aa 0c 00 00 a6 03 00 1d 20 2f e5 7d a3 47 |.......... /.}.G| 000002b0 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af |.bC.(.._.).0....| -000002c0 c4 cf c2 ed 90 99 5f 58 cb 3b 74 00 80 00 9f b3 |......_X.;t.....| -000002d0 fa c1 71 14 e3 1a 6c 3f b6 61 15 e2 7b 99 c5 4c |..q...l?.a..{..L| -000002e0 39 e0 45 f8 9d d3 84 1a c4 fc 7c 51 32 3d 67 0b |9.E.......|Q2=g.| -000002f0 28 b8 8c 6d 66 7e ab 82 c9 f6 d0 49 62 96 2c af |(..mf~.....Ib.,.| -00000300 4f 0a d1 21 54 b8 3e ae 09 fd d8 85 10 cb da c4 |O..!T.>.........| -00000310 6f 42 16 cd 70 cd 33 b0 a5 e5 a1 c7 9a 35 41 3f |oB..p.3......5A?| -00000320 59 db a1 b3 f4 ae f6 72 9c a8 db f5 86 99 43 b3 |Y......r......C.| -00000330 8f bc 0f d9 0a 50 49 58 3b 17 fa 51 27 11 e9 95 |.....PIX;..Q'...| -00000340 8c bb 1a 31 11 bc a2 fa 2c 6b c2 6a 40 16 03 01 |...1....,k.j@...| +000002c0 c4 cf c2 ed 90 99 5f 58 cb 3b 74 00 80 bb 96 fe |......_X.;t.....| +000002d0 bf a0 81 24 bc 40 b4 e2 37 b1 c9 66 2d c3 c1 bb |...$.@..7..f-...| +000002e0 89 fb 28 23 60 76 b1 e6 2c c1 e9 06 d0 95 c5 10 |..(#`v..,.......| +000002f0 17 ce 79 36 c2 14 e0 1d 1d 0d 0e 49 3e b9 7f 00 |..y6.......I>...| +00000300 ad e3 1d 37 ab ce 2c 37 dc eb be aa 6c 28 33 05 |...7..,7....l(3.| +00000310 53 fd 06 17 b4 85 b9 b8 35 1c a7 3c bb 07 3f 4b |S.......5..<..?K| +00000320 53 98 00 4d 8e 49 bd 35 55 64 92 d0 a0 db 05 80 |S..M.I.5Ud......| +00000330 57 24 78 cd 10 ed ae f0 6a 83 bc b4 4d 77 79 ba |W$x.....j...Mwy.| +00000340 6e e7 2e 8f ac 9e 98 34 36 9d a9 27 f0 16 03 01 |n......46..'....| 00000350 00 04 0e 00 00 00 |......| >>> Flow 3 (client to server) -00000000 16 03 01 00 25 10 00 00 21 20 bf 0c 33 f5 6a 06 |....%...! ..3.j.| -00000010 18 0a 74 ad 8b bd ef 9c 00 a3 c0 03 20 5b ea 69 |..t......... [.i| -00000020 09 18 b8 4a 30 13 c7 10 30 3a 14 03 01 00 01 01 |...J0...0:......| -00000030 16 03 01 00 30 04 6d f7 66 e9 7f 72 80 32 24 93 |....0.m.f..r.2$.| -00000040 2f 74 5e 34 c5 fb 19 a0 64 31 1e cb 63 03 fb 51 |/t^4....d1..c..Q| -00000050 5c d9 17 a8 b0 8a b6 74 e8 84 86 a5 33 d2 75 4a |\......t....3.uJ| -00000060 c0 bb 6a bb f3 |..j..| +00000000 16 03 01 00 25 10 00 00 21 20 00 ad c5 2b 21 7f |....%...! ...+!.| +00000010 8e 44 f2 f5 32 22 c8 c2 c6 de 2c 0b 7a a9 24 b6 |.D..2"....,.z.$.| +00000020 03 20 c0 cc 79 2e 11 2f d3 43 14 03 01 00 01 01 |. ..y../.C......| +00000030 16 03 01 00 30 78 5c 32 72 a1 c8 3b 9c 7b 77 0b |....0x\2r..;.{w.| +00000040 a0 28 52 55 17 16 d5 39 89 d0 43 bf 67 29 85 6f |.(RU...9..C.g).o| +00000050 b5 1e 83 fa 22 96 78 e3 5c 45 5a 3d fe 2b d5 b7 |....".x.\EZ=.+..| +00000060 3d 64 44 8c a8 |=dD..| >>> Flow 4 (server to client) -00000000 16 03 01 00 82 04 00 00 7e 00 00 00 00 00 78 50 |........~.....xP| +00000000 16 03 01 00 8b 04 00 00 87 00 00 00 00 00 81 50 |...............P| 00000010 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 |F....8.{+....B>.| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................| -00000030 6d ec a4 83 61 28 8e b8 1b 0e dd 7d 71 4a 36 c3 |m...a(.....}qJ6.| -00000040 6d cb c7 88 ed 19 c5 08 72 b9 25 fb 6c 29 b8 b2 |m.......r.%.l)..| -00000050 72 f8 27 c0 1e f2 86 16 54 0f 72 a9 6e 15 69 9e |r.'.....T.r.n.i.| -00000060 66 fe d1 05 20 33 94 32 40 82 bb e3 61 47 3a 8e |f... 3.2@...aG:.| -00000070 b7 45 92 8a 5c 84 64 eb 6c 1a 3c bb 2f be ce b2 |.E..\.d.l.<./...| -00000080 5f cb c9 be c4 ff d6 14 03 01 00 01 01 16 03 01 |_...............| -00000090 00 30 5e ff 91 82 d5 30 a4 fb cd 20 90 c1 2d 08 |.0^....0... ..-.| -000000a0 aa 19 d6 72 fa 74 07 95 df 14 eb 59 bb 0c 81 3f |...r.t.....Y...?| -000000b0 75 77 45 96 d8 3e 45 a7 42 1c f1 82 c0 04 4d 2e |uwE..>E.B.....M.| -000000c0 3f 07 17 03 01 00 20 54 90 60 76 16 5f 6b d0 3e |?..... T.`v._k.>| -000000d0 f6 bf f3 0a 5c b9 3b 19 cb df a6 94 28 04 24 ea |....\.;.....(.$.| -000000e0 73 1f 49 5e 23 f6 91 17 03 01 00 30 b5 97 eb 85 |s.I^#......0....| -000000f0 cc 17 86 b0 0d 24 bf 64 6d 4f 16 55 b0 f3 64 7c |.....$.dmO.U..d|| -00000100 75 3f e4 16 94 41 56 64 12 50 0e 7c 0c 1c e7 58 |u?...AVd.P.|...X| -00000110 4d 9c 82 d8 f5 5a 61 a3 d8 3c f5 04 15 03 01 00 |M....Za..<......| -00000120 20 59 6c e6 9e 4e 14 94 5d 61 94 b2 ba 0f eb 18 | Yl..N..]a......| -00000130 cf 10 5b f6 90 27 58 8e 10 54 36 d4 c7 52 37 2e |..[..'X..T6..R7.| -00000140 a0 |.| +00000030 6d ec a4 83 51 ed 14 ef 68 ca 42 c5 4c 5f bb 3b |m...Q...h.B.L_.;| +00000040 9c c8 3c 7e 1c cf dc da e4 35 83 03 13 95 82 5f |..<~.....5....._| +00000050 32 77 8a cf dc e9 10 65 9b 97 d4 5d ff 43 57 14 |2w.....e...].CW.| +00000060 a3 25 e0 fa c8 26 0c ff 71 67 9b 32 2f 49 38 16 |.%...&..qg.2/I8.| +00000070 aa ea b9 fa 99 86 4c b9 db 7a ef bc 87 43 e8 db |......L..z...C..| +00000080 26 27 73 76 80 77 59 c4 fb 7d 56 e9 7e 23 03 75 |&'sv.wY..}V.~#.u| +00000090 14 03 01 00 01 01 16 03 01 00 30 80 8f 8e 11 b5 |..........0.....| +000000a0 f4 a0 8c 4a ae 3f 25 17 66 93 1c c5 a5 10 57 e3 |...J.?%.f.....W.| +000000b0 24 7a c1 a9 72 74 4f fd 20 5e 5b 58 4d bd 5d f0 |$z..rtO. ^[XM.].| +000000c0 05 8e 06 61 0a 98 19 a0 a8 73 02 17 03 01 00 20 |...a.....s..... | +000000d0 d9 dd 86 e6 55 55 df 2c 0d 1e 5f 0e 9e 1e 76 51 |....UU.,.._...vQ| +000000e0 98 e0 2b 09 f9 44 4d 4d 22 97 0d 1e 95 7b b9 41 |..+..DMM"....{.A| +000000f0 17 03 01 00 30 74 82 1c 35 9b 87 cd 5e 29 95 e1 |....0t..5...^)..| +00000100 18 e3 76 32 94 b5 1b d0 06 d2 ec 49 40 24 73 d3 |..v2.......I@$s.| +00000110 fc 5d 1a 26 59 5b 33 d8 5a 30 d5 92 30 bc 80 e0 |.].&Y[3.Z0..0...| +00000120 ed 85 e8 14 01 15 03 01 00 20 ec 69 2f 9d 29 4f |......... .i/.)O| +00000130 1f 8e e6 34 f0 87 66 40 e8 13 14 02 74 c4 1d aa |...4..f@....t...| +00000140 65 72 43 50 6e 71 9c 2e b6 3a |erCPnq...:| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN b/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN index f6ddb972f6d..d9e7e837664 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN @@ -1,19 +1,18 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 e3 01 00 00 df 03 03 e7 33 0d 6a 2d |............3.j-| -00000010 87 bc b4 a1 11 ee 1a 4e 91 f5 fb ad 29 70 d4 6d |.......N....)p.m| -00000020 05 be ec f3 e2 b1 0d 4e da a4 b5 00 00 38 c0 2c |.......N.....8.,| +00000000 16 03 01 00 d1 01 00 00 cd 03 03 50 99 a9 e9 80 |...........P....| +00000010 87 f1 0a 5a bc 9d a6 53 6d 08 36 4a 79 f8 48 c3 |...Z...Sm.6Jy.H.| +00000020 fe c1 b4 02 d9 66 b2 cc f9 8d d4 00 00 38 c0 2c |.....f.......8.,| 00000030 c0 30 00 9f cc a9 cc a8 cc aa c0 2b c0 2f 00 9e |.0.........+./..| 00000040 c0 24 c0 28 00 6b c0 23 c0 27 00 67 c0 0a c0 14 |.$.(.k.#.'.g....| 00000050 00 39 c0 09 c0 13 00 33 00 9d 00 9c 00 3d 00 3c |.9.....3.....=.<| -00000060 00 35 00 2f 00 ff 01 00 00 7e 00 00 00 0e 00 0c |.5./.....~......| -00000070 00 00 09 31 32 37 2e 30 2e 30 2e 31 00 0b 00 04 |...127.0.0.1....| -00000080 03 00 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e |................| -00000090 00 19 00 18 00 23 00 00 00 10 00 10 00 0e 06 70 |.....#.........p| -000000a0 72 6f 74 6f 32 06 70 72 6f 74 6f 31 00 16 00 00 |roto2.proto1....| -000000b0 00 17 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 |.......0........| -000000c0 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 |................| -000000d0 04 01 05 01 06 01 03 03 02 03 03 01 02 01 03 02 |................| -000000e0 02 02 04 02 05 02 06 02 |........| +00000060 00 35 00 2f 00 ff 01 00 00 6c 00 0b 00 04 03 00 |.5./.....l......| +00000070 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 |................| +00000080 00 18 00 23 00 00 00 10 00 10 00 0e 06 70 72 6f |...#.........pro| +00000090 74 6f 32 06 70 72 6f 74 6f 31 00 16 00 00 00 17 |to2.proto1......| +000000a0 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 |.....0..........| +000000b0 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 |................| +000000c0 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 02 |................| +000000d0 04 02 05 02 06 02 |......| >>> Flow 2 (server to client) 00000000 16 03 03 00 48 02 00 00 44 03 03 00 00 00 00 00 |....H...D.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| @@ -60,38 +59,38 @@ 000002a0 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 ac |=.`.\!.;........| 000002b0 0c 00 00 a8 03 00 1d 20 2f e5 7d a3 47 cd 62 43 |....... /.}.G.bC| 000002c0 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 |.(.._.).0.......| -000002d0 ed 90 99 5f 58 cb 3b 74 08 04 00 80 b6 a2 61 f9 |..._X.;t......a.| -000002e0 30 40 0b 5c 2c 92 b4 7b e3 42 79 00 11 4d 6b 85 |0@.\,..{.By..Mk.| -000002f0 df 2e 19 c2 fc a8 bc 16 0b c0 8d 02 55 99 a7 06 |............U...| -00000300 fa 4c 4d 4c 27 de 6d 3d 1e 7a 6f 2c fc eb 9e 15 |.LML'.m=.zo,....| -00000310 40 6f 0c 81 b3 e1 4d 78 b7 38 c6 50 8f 5b 63 ac |@o....Mx.8.P.[c.| -00000320 20 4f a6 06 aa 00 84 f5 01 f4 68 7a 5a 16 c5 da | O........hzZ...| -00000330 71 b2 4f 04 6e 59 88 14 8c 81 01 91 a8 e8 c1 18 |q.O.nY..........| -00000340 a8 07 e8 7a f4 dc b9 e7 7f c5 ce 2c 32 8d fe d6 |...z.......,2...| -00000350 1f 0e a5 f0 f4 c7 dd 39 13 a1 ca 6d 16 03 03 00 |.......9...m....| +000002d0 ed 90 99 5f 58 cb 3b 74 08 04 00 80 cb 03 45 70 |..._X.;t......Ep| +000002e0 f5 51 af d7 cf db 26 79 d1 57 c2 06 4c 49 e6 ea |.Q....&y.W..LI..| +000002f0 e7 f4 b8 2c 23 52 8a 1f bd 8e a3 9e 79 d4 8e 66 |...,#R......y..f| +00000300 ee 92 39 97 cc ec 46 03 76 f9 59 b7 2e 6f e4 88 |..9...F.v.Y..o..| +00000310 fd 39 65 59 88 c2 7e 7a bc de 86 49 98 45 a6 44 |.9eY..~z...I.E.D| +00000320 82 41 19 94 53 3d 34 4b 73 52 5a af b2 3d 92 5e |.A..S=4KsRZ..=.^| +00000330 f3 5b e8 fa 23 a7 71 5c 64 1b 43 bb bd 8e 01 2a |.[..#.q\d.C....*| +00000340 59 2d 3b 73 0f b9 3d 02 9a 09 4a fc 0e 4b 65 07 |Y-;s..=...J..Ke.| +00000350 82 f9 e1 ad ec 64 27 a4 07 60 c7 32 16 03 03 00 |.....d'..`.2....| 00000360 04 0e 00 00 00 |.....| >>> Flow 3 (client to server) -00000000 16 03 03 00 25 10 00 00 21 20 d7 fa 22 66 b4 c8 |....%...! .."f..| -00000010 67 2c 45 93 bf 38 3a 13 21 45 d5 29 95 5b 0d 5c |g,E..8:.!E.).[.\| -00000020 79 d2 d6 9b ef bd 7d eb a9 21 14 03 03 00 01 01 |y.....}..!......| -00000030 16 03 03 00 28 a2 81 84 32 29 01 69 28 f9 56 cc |....(...2).i(.V.| -00000040 c9 72 51 5c 22 38 51 12 e1 55 a1 d6 8c cf 66 75 |.rQ\"8Q..U....fu| -00000050 b4 bd 49 60 d0 e4 7e 9e fe 56 d1 62 36 |..I`..~..V.b6| +00000000 16 03 03 00 25 10 00 00 21 20 f6 5d 24 8e fc 1c |....%...! .]$...| +00000010 39 bb 01 fc 23 ef f4 86 8b aa 2c 39 2a a1 4d e6 |9...#.....,9*.M.| +00000020 7c 21 74 cc ed 2c 9b 4b f2 01 14 03 03 00 01 01 ||!t..,.K........| +00000030 16 03 03 00 28 96 9c a6 78 4b 94 24 e2 31 5a 25 |....(...xK.$.1Z%| +00000040 68 5e 6a 51 03 5d 9d cf 45 b1 78 17 0b bf ff c6 |h^jQ.]..E.x.....| +00000050 72 5b e9 f0 a1 b1 46 ab a5 e1 3f 4d 67 |r[....F...?Mg| >>> Flow 4 (server to client) -00000000 16 03 03 00 82 04 00 00 7e 00 00 00 00 00 78 50 |........~.....xP| +00000000 16 03 03 00 8b 04 00 00 87 00 00 00 00 00 81 50 |...............P| 00000010 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 |F....8.{+....B>.| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................| -00000030 6f ec 80 83 61 cf 87 48 45 0d 9d a5 bf 38 b4 9f |o...a..HE....8..| -00000040 19 a9 cd ca 63 79 2d c3 ae 70 74 56 44 99 fb cc |....cy-..ptVD...| -00000050 7d 31 c2 67 75 fe 57 1b fd 6b 2f cd df ec fa 5b |}1.gu.W..k/....[| -00000060 23 47 19 7e 84 33 94 d7 de e2 b9 ff 75 7d dc 80 |#G.~.3......u}..| -00000070 9e 55 94 8e 15 94 70 8f b5 21 0e 4e f7 4c e6 44 |.U....p..!.N.L.D| -00000080 01 a3 9d 67 5f 05 73 14 03 03 00 01 01 16 03 03 |...g_.s.........| -00000090 00 28 00 00 00 00 00 00 00 00 3a 49 dc e2 aa ce |.(........:I....| -000000a0 a8 43 27 08 a8 6b 7c ae 3f 07 18 e1 04 a9 e6 24 |.C'..k|.?......$| -000000b0 0e 9e 0a 0f af a4 c3 6e 90 2d 17 03 03 00 25 00 |.......n.-....%.| -000000c0 00 00 00 00 00 00 01 41 e1 9b 4c 8a 1a e8 10 bf |.......A..L.....| -000000d0 9f fd 76 e4 43 c2 cf 04 ee 68 6a 02 3c 97 fc ec |..v.C....hj.<...| -000000e0 c4 0a 74 1d 15 03 03 00 1a 00 00 00 00 00 00 00 |..t.............| -000000f0 02 1c 9b b1 b6 07 fa 33 a8 70 03 d9 27 29 ea 61 |.......3.p..').a| -00000100 96 c2 48 |..H| +00000030 6f ec 80 83 51 ed 14 ef 68 ca 42 c5 4c 4a f5 b1 |o...Q...h.B.LJ..| +00000040 56 86 3e f2 10 79 9e f3 a0 ed 07 6d 09 fc 77 63 |V.>..y.....m..wc| +00000050 86 68 42 99 7b 13 c3 35 cf 5b a6 3a fa aa c2 ec |.hB.{..5.[.:....| +00000060 80 a2 27 e4 97 24 07 48 2c 70 30 fc d6 49 38 16 |..'..$.H,p0..I8.| +00000070 60 d5 b0 4c ec 4b 74 48 03 2a 5e fb 14 43 6c 5f |`..L.KtH.*^..Cl_| +00000080 35 9c 1b a8 7d 62 f8 42 68 27 cb 6d 15 38 e7 8e |5...}b.Bh'.m.8..| +00000090 14 03 03 00 01 01 16 03 03 00 28 00 00 00 00 00 |..........(.....| +000000a0 00 00 00 8d 7a 5a 66 3b c9 fe 51 c2 71 ef a5 8b |....zZf;..Q.q...| +000000b0 42 7d 79 33 4e 6d 66 12 cc e7 46 4f c3 30 12 8f |B}y3Nmf...FO.0..| +000000c0 0c 57 60 17 03 03 00 25 00 00 00 00 00 00 00 01 |.W`....%........| +000000d0 83 aa 62 fe a3 73 ed 67 87 c0 19 1c fa f0 2c 26 |..b..s.g......,&| +000000e0 4b 16 44 9c a7 f8 c3 e1 ba 6a 85 8f 84 15 03 03 |K.D......j......| +000000f0 00 1a 00 00 00 00 00 00 00 02 a8 b3 b2 dd 4b a6 |..............K.| +00000100 ba 05 dc 8f ac 98 ae 01 10 60 9a 62 |.........`.b| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch b/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch index f8b88a63d78..589189ca844 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch @@ -1,19 +1,18 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 e3 01 00 00 df 03 03 ed dd 7f 68 1d |..............h.| -00000010 9e 83 bc 08 01 39 8e 97 76 91 cb cb 24 73 15 f5 |.....9..v...$s..| -00000020 17 17 db 78 69 ca e1 ed 0f fc bc 00 00 38 c0 2c |...xi........8.,| +00000000 16 03 01 00 d1 01 00 00 cd 03 03 44 a5 b9 48 dd |...........D..H.| +00000010 ca 91 9a c6 72 06 b3 dd a7 95 18 c6 95 0b f2 32 |....r..........2| +00000020 84 37 78 12 0f 66 c7 6e e6 61 81 00 00 38 c0 2c |.7x..f.n.a...8.,| 00000030 c0 30 00 9f cc a9 cc a8 cc aa c0 2b c0 2f 00 9e |.0.........+./..| 00000040 c0 24 c0 28 00 6b c0 23 c0 27 00 67 c0 0a c0 14 |.$.(.k.#.'.g....| 00000050 00 39 c0 09 c0 13 00 33 00 9d 00 9c 00 3d 00 3c |.9.....3.....=.<| -00000060 00 35 00 2f 00 ff 01 00 00 7e 00 00 00 0e 00 0c |.5./.....~......| -00000070 00 00 09 31 32 37 2e 30 2e 30 2e 31 00 0b 00 04 |...127.0.0.1....| -00000080 03 00 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e |................| -00000090 00 19 00 18 00 23 00 00 00 10 00 10 00 0e 06 70 |.....#.........p| -000000a0 72 6f 74 6f 32 06 70 72 6f 74 6f 31 00 16 00 00 |roto2.proto1....| -000000b0 00 17 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 |.......0........| -000000c0 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 |................| -000000d0 04 01 05 01 06 01 03 03 02 03 03 01 02 01 03 02 |................| -000000e0 02 02 04 02 05 02 06 02 |........| +00000060 00 35 00 2f 00 ff 01 00 00 6c 00 0b 00 04 03 00 |.5./.....l......| +00000070 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 |................| +00000080 00 18 00 23 00 00 00 10 00 10 00 0e 06 70 72 6f |...#.........pro| +00000090 74 6f 32 06 70 72 6f 74 6f 31 00 16 00 00 00 17 |to2.proto1......| +000000a0 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 |.....0..........| +000000b0 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 |................| +000000c0 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 02 |................| +000000d0 04 02 05 02 06 02 |......| >>> Flow 2 (server to client) 00000000 16 03 03 00 3b 02 00 00 37 03 03 00 00 00 00 00 |....;...7.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| @@ -59,38 +58,38 @@ 00000290 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 |...=.`.\!.;.....| 000002a0 03 00 ac 0c 00 00 a8 03 00 1d 20 2f e5 7d a3 47 |.......... /.}.G| 000002b0 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af |.bC.(.._.).0....| -000002c0 c4 cf c2 ed 90 99 5f 58 cb 3b 74 08 04 00 80 59 |......_X.;t....Y| -000002d0 85 20 dc b1 4c d2 17 4d 20 73 1a a7 f7 ab 40 52 |. ..L..M s....@R| -000002e0 73 e7 02 21 eb 55 e2 c9 73 c0 c2 8a ed a3 fd 07 |s..!.U..s.......| -000002f0 0b 5b 30 c2 1e 63 a1 c2 27 41 6c 5a ca 6e 12 d3 |.[0..c..'AlZ.n..| -00000300 4a 87 15 29 7f 44 06 3d 14 76 98 45 e5 27 84 09 |J..).D.=.v.E.'..| -00000310 44 be f3 c4 ce 79 31 e9 92 06 b6 d2 d9 19 d1 24 |D....y1........$| -00000320 7d 44 6a 57 ea 9d 12 e3 e7 a1 16 86 10 fc 7a 66 |}DjW..........zf| -00000330 00 3a f0 f0 ed e7 7c 20 82 0a 26 5d 92 79 8a 5b |.:....| ..&].y.[| -00000340 55 98 fc 1a c1 2f c0 07 ce b8 03 3a 01 da 62 16 |U..../.....:..b.| +000002c0 c4 cf c2 ed 90 99 5f 58 cb 3b 74 08 04 00 80 1d |......_X.;t.....| +000002d0 ae 16 b9 7e 58 bb d5 1b 9e 51 09 a2 d1 a8 3f 1d |...~X....Q....?.| +000002e0 f4 09 72 a5 c6 cc 9a 53 46 1c 9f 58 36 cd 91 39 |..r....SF..X6..9| +000002f0 44 ca 56 da 50 77 d5 56 10 14 45 ad 98 b8 2f 44 |D.V.Pw.V..E.../D| +00000300 33 ae a9 b1 b6 a6 2a ab 0a 0a 39 75 2c 4d 4c 51 |3.....*...9u,MLQ| +00000310 71 07 83 bf ad 8b 37 c5 59 dd 8f d7 b8 85 2e 04 |q.....7.Y.......| +00000320 9e 39 e6 e5 a5 48 9a 24 63 b3 a7 46 73 b2 5c 10 |.9...H.$c..Fs.\.| +00000330 cc 4c e5 55 dd 97 b0 42 4e 8b fb 0d cd 47 e9 09 |.L.U...BN....G..| +00000340 20 88 96 5e 76 0d 9b b1 91 3f 27 a1 f3 0d 77 16 | ..^v....?'...w.| 00000350 03 03 00 04 0e 00 00 00 |........| >>> Flow 3 (client to server) -00000000 16 03 03 00 25 10 00 00 21 20 d9 f2 e4 c5 cf 38 |....%...! .....8| -00000010 23 30 2e b6 d9 0f 3b a2 d7 2f eb d5 74 a8 29 12 |#0....;../..t.).| -00000020 5f 27 bc 81 96 6b 12 5a bb 2f 14 03 03 00 01 01 |_'...k.Z./......| -00000030 16 03 03 00 28 4b a1 12 ce 11 2a 0f 79 7c 56 eb |....(K....*.y|V.| -00000040 bb 9f 7d 91 c7 53 25 d6 ae 0b 98 f1 b5 ea ef 51 |..}..S%........Q| -00000050 8b 3a fb d1 6c ae 3d bb b7 67 d9 ba 36 |.:..l.=..g..6| +00000000 16 03 03 00 25 10 00 00 21 20 89 8e 03 11 92 ab |....%...! ......| +00000010 51 f5 d7 dc 27 87 fd 38 eb 45 3d cc 75 1a 1e 07 |Q...'..8.E=.u...| +00000020 d6 0f 2b 92 df 5a 7c 24 30 56 14 03 03 00 01 01 |..+..Z|$0V......| +00000030 16 03 03 00 28 fa 24 69 6d 65 2f 34 35 47 9b 83 |....(.$ime/45G..| +00000040 65 0f fd c1 33 61 1d 47 cf ec 87 6f 48 71 63 7d |e...3a.G...oHqc}| +00000050 e8 aa bc 2e cd 7d 2e 4b d5 0f 4f 66 14 |.....}.K..Of.| >>> Flow 4 (server to client) -00000000 16 03 03 00 82 04 00 00 7e 00 00 00 00 00 78 50 |........~.....xP| +00000000 16 03 03 00 8b 04 00 00 87 00 00 00 00 00 81 50 |...............P| 00000010 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 |F....8.{+....B>.| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................| -00000030 6f ec 80 83 61 40 f9 2b 9e a7 30 60 fb 46 36 c4 |o...a@.+..0`.F6.| -00000040 0e b3 2a c4 73 64 2e 12 6c 0d f5 b9 6f 05 ae 27 |..*.sd..l...o..'| -00000050 d7 a3 47 c5 67 31 3e 95 84 bf 42 e1 b9 0d 90 40 |..G.g1>...B....@| -00000060 01 50 0d 32 4b 33 94 5c a3 1d b9 db e5 c5 24 02 |.P.2K3.\......$.| -00000070 48 31 ad 70 8e c7 e9 60 a5 7e ea 91 7b 01 79 06 |H1.p...`.~..{.y.| -00000080 66 f9 c4 9d bd 65 a5 14 03 03 00 01 01 16 03 03 |f....e..........| -00000090 00 28 00 00 00 00 00 00 00 00 32 be b5 c5 4d 83 |.(........2...M.| -000000a0 41 97 f6 26 0f aa 06 35 d5 9e f8 12 1c 04 f7 b6 |A..&...5........| -000000b0 16 9f f9 a4 43 b8 56 ea 4a 82 17 03 03 00 25 00 |....C.V.J.....%.| -000000c0 00 00 00 00 00 00 01 1a 8e 6b 4a 69 02 56 46 eb |.........kJi.VF.| -000000d0 26 12 47 a3 9d 9a 8a 09 20 4a 6c b2 d0 6a 14 48 |&.G..... Jl..j.H| -000000e0 be d5 f0 48 15 03 03 00 1a 00 00 00 00 00 00 00 |...H............| -000000f0 02 0e 01 9d 60 90 01 60 99 a0 f5 df 6d 38 e5 76 |....`..`....m8.v| -00000100 4d d7 d7 |M..| +00000030 6f ec 80 83 51 ed 14 ef 68 ca 42 c5 4c 60 05 16 |o...Q...h.B.L`..| +00000040 33 5b f7 bd 83 9c 69 80 c2 fe 5c 73 32 05 67 97 |3[....i...\s2.g.| +00000050 fd 6b 3a d3 b4 6d a5 5e 18 c0 1e ba d5 2c 44 ad |.k:..m.^.....,D.| +00000060 54 24 65 be 14 90 ab 6d a1 de d1 98 1e 49 38 16 |T$e....m.....I8.| +00000070 f0 fe 8d 49 6d e1 5a 6d 10 30 26 64 5f 10 ad ab |...Im.Zm.0&d_...| +00000080 d7 c9 3a bc 6a 3f 32 78 4b fe f1 38 08 2c 15 e7 |..:.j?2xK..8.,..| +00000090 14 03 03 00 01 01 16 03 03 00 28 00 00 00 00 00 |..........(.....| +000000a0 00 00 00 e9 3d 4c 8b 59 78 8c 49 77 08 3b c1 de |....=L.Yx.Iw.;..| +000000b0 4c 78 9a d7 c6 1a 66 fb 43 de bd cb 8b ca a2 32 |Lx....f.C......2| +000000c0 a2 26 1e 17 03 03 00 25 00 00 00 00 00 00 00 01 |.&.....%........| +000000d0 47 c9 3a 0d 8d 8b d1 b7 66 17 8e 83 31 02 ed 51 |G.:.....f...1..Q| +000000e0 e8 cb 1d 4a 42 d6 f9 ee b8 6d fd d0 4b 15 03 03 |...JB....m..K...| +000000f0 00 1a 00 00 00 00 00 00 00 02 f3 00 56 6d fc 23 |............Vm.#| +00000100 49 bb 65 00 b0 ae cd c7 62 ac 47 1f |I.e.....b.G.| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial b/libgo/go/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial index ecf765be7da..c9f0c5c0fc6 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial @@ -1,18 +1,17 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 cf 01 00 00 cb 03 03 62 4c 73 03 fd |...........bLs..| -00000010 24 98 d0 f6 41 49 83 94 04 c8 17 51 3e 18 5d 6d |$...AI.....Q>.]m| -00000020 8a b8 52 c0 cf 0b 60 1e 02 53 d2 00 00 38 c0 2c |..R...`..S...8.,| +00000000 16 03 01 00 bd 01 00 00 b9 03 03 7e 75 ea 1f ec |...........~u...| +00000010 47 ee de 51 9d 11 00 77 5b 1b fb 7e 05 22 0a 7a |G..Q...w[..~.".z| +00000020 74 bc 6a d1 8a 67 03 a1 ae c9 23 00 00 38 c0 2c |t.j..g....#..8.,| 00000030 c0 30 00 9f cc a9 cc a8 cc aa c0 2b c0 2f 00 9e |.0.........+./..| 00000040 c0 24 c0 28 00 6b c0 23 c0 27 00 67 c0 0a c0 14 |.$.(.k.#.'.g....| 00000050 00 39 c0 09 c0 13 00 33 00 9d 00 9c 00 3d 00 3c |.9.....3.....=.<| -00000060 00 35 00 2f 00 ff 01 00 00 6a 00 00 00 0e 00 0c |.5./.....j......| -00000070 00 00 09 31 32 37 2e 30 2e 30 2e 31 00 0b 00 04 |...127.0.0.1....| -00000080 03 00 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e |................| -00000090 00 19 00 18 00 23 00 00 00 16 00 00 00 17 00 00 |.....#..........| -000000a0 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 |...0............| -000000b0 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 |................| -000000c0 06 01 03 03 02 03 03 01 02 01 03 02 02 02 04 02 |................| -000000d0 05 02 06 02 |....| +00000060 00 35 00 2f 00 ff 01 00 00 58 00 0b 00 04 03 00 |.5./.....X......| +00000070 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 |................| +00000080 00 18 00 23 00 00 00 16 00 00 00 17 00 00 00 0d |...#............| +00000090 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............| +000000a0 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................| +000000b0 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................| +000000c0 06 02 |..| >>> Flow 2 (server to client) 00000000 16 03 03 00 3b 02 00 00 37 03 03 00 00 00 00 00 |....;...7.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| @@ -58,38 +57,38 @@ 00000290 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 |...=.`.\!.;.....| 000002a0 03 00 ac 0c 00 00 a8 03 00 1d 20 2f e5 7d a3 47 |.......... /.}.G| 000002b0 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af |.bC.(.._.).0....| -000002c0 c4 cf c2 ed 90 99 5f 58 cb 3b 74 08 04 00 80 2d |......_X.;t....-| -000002d0 54 87 fa c9 e5 97 ad a0 6d 54 89 b1 37 24 af df |T.......mT..7$..| -000002e0 0f 3e ef 34 f7 6a 5f 1b 06 a5 b9 b4 6d 46 7f b1 |.>.4.j_.....mF..| -000002f0 ab e4 5c dd c1 3f 98 93 61 e5 81 8a 6c 3d 2f b3 |..\..?..a...l=/.| -00000300 3c 59 b9 78 45 ba bd 02 b1 a0 72 cb c3 59 b1 55 |>> Flow 3 (client to server) -00000000 16 03 03 00 25 10 00 00 21 20 37 47 1b 8d ef 6c |....%...! 7G...l| -00000010 dc 59 b2 a5 a2 f6 8e 1b f6 1b ab da ec 9c a7 ff |.Y..............| -00000020 4a f9 0e 9b 02 b0 8f bc a1 55 14 03 03 00 01 01 |J........U......| -00000030 16 03 03 00 28 a2 53 52 8b df 86 63 d9 f8 a8 7e |....(.SR...c...~| -00000040 f5 b4 19 1a 5d 02 9a 48 94 68 6d a2 90 13 93 42 |....]..H.hm....B| -00000050 87 52 92 50 7c 45 91 b9 91 49 83 66 a6 |.R.P|E...I.f.| +00000000 16 03 03 00 25 10 00 00 21 20 d5 13 c6 90 e0 4a |....%...! .....J| +00000010 25 2f 5d cd 02 d8 fd 14 61 78 dd fc 42 57 ce bd |%/].....ax..BW..| +00000020 e0 47 b8 cf 42 59 1c 7f 1f 1e 14 03 03 00 01 01 |.G..BY..........| +00000030 16 03 03 00 28 96 2c 78 25 ee 20 88 53 69 57 96 |....(.,x%. .SiW.| +00000040 d9 d2 53 6c 5b 5b e9 db 7d 0a 7c f9 16 27 43 df |..Sl[[..}.|..'C.| +00000050 a9 e2 a6 e5 be c5 e9 d5 ff df 66 6b 81 |..........fk.| >>> Flow 4 (server to client) -00000000 16 03 03 00 82 04 00 00 7e 00 00 00 00 00 78 50 |........~.....xP| +00000000 16 03 03 00 8b 04 00 00 87 00 00 00 00 00 81 50 |...............P| 00000010 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 |F....8.{+....B>.| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................| -00000030 6f ec 80 83 61 a2 90 f4 4c 03 c8 09 b9 a6 c6 6f |o...a...L......o| -00000040 c7 52 57 3f 3f 92 71 f3 f8 02 43 69 19 f0 bf 78 |.RW??.q...Ci...x| -00000050 6a 00 cc 0a 96 6f 80 5d 62 42 9b 6b 7c 00 e0 26 |j....o.]bB.k|..&| -00000060 90 ef d9 26 f1 33 94 6e 13 9a ec be 91 00 1e 64 |...&.3.n.......d| -00000070 eb 12 ae b9 74 f9 85 d1 b7 91 bd e1 e2 da ac b0 |....t...........| -00000080 71 ca 1b 65 1a e7 83 14 03 03 00 01 01 16 03 03 |q..e............| -00000090 00 28 00 00 00 00 00 00 00 00 fa e4 1b 3b 28 9b |.(...........;(.| -000000a0 f8 28 d7 26 d7 6a 67 33 1f 4a 39 d9 ac 59 6f fc |.(.&.jg3.J9..Yo.| -000000b0 2b 84 6c b9 73 70 9b 30 8c d0 17 03 03 00 25 00 |+.l.sp.0......%.| -000000c0 00 00 00 00 00 00 01 0c 6e 13 cf 3d 10 65 2f e5 |........n..=.e/.| -000000d0 4f fd f9 b6 34 11 c2 05 60 d5 16 66 68 65 29 fa |O...4...`..fhe).| -000000e0 e6 97 e4 dc 15 03 03 00 1a 00 00 00 00 00 00 00 |................| -000000f0 02 58 9a 0d 41 6f 0f 72 c7 43 16 46 83 dd 26 5f |.X..Ao.r.C.F..&_| -00000100 3a ee 1a |:..| +00000030 6f ec 80 83 51 ed 14 ef 68 ca 42 c5 4c c7 ea d3 |o...Q...h.B.L...| +00000040 9f e6 77 db 30 96 5c e3 bc f8 b7 c7 74 9d 0e 97 |..w.0.\.....t...| +00000050 cf 3c ec 76 c8 9e ad 0c 49 86 9e 4f 4d 56 ce 95 |.<.v....I..OMV..| +00000060 7f 75 79 aa dd 8e 66 8f 1f d8 01 2d c1 49 38 16 |.uy...f....-.I8.| +00000070 b3 7a 6b 8d 3d ba 2b 81 4c 1c 75 c3 06 bb 8c 1e |.zk.=.+.L.u.....| +00000080 df 59 35 29 5b d1 54 cc 5c 6b 37 74 29 19 0f 8b |.Y5)[.T.\k7t)...| +00000090 14 03 03 00 01 01 16 03 03 00 28 00 00 00 00 00 |..........(.....| +000000a0 00 00 00 c7 19 9a c9 cc 16 3b 8f b7 52 de 4c ab |.........;..R.L.| +000000b0 90 83 b1 b5 60 0d c0 49 c4 28 f7 1d 1f e9 e0 b1 |....`..I.(......| +000000c0 21 a1 49 17 03 03 00 25 00 00 00 00 00 00 00 01 |!.I....%........| +000000d0 46 fe 03 14 ad 32 d5 ff 89 1f 08 15 6b 44 4f 2d |F....2......kDO-| +000000e0 5e d6 f1 35 d9 c4 c4 cc bf 5a 26 df a6 15 03 03 |^..5.....Z&.....| +000000f0 00 1a 00 00 00 00 00 00 00 02 4f 7b 8e 22 3c 85 |..........O{."<.| +00000100 5c 41 f5 17 0d dd c8 41 b5 ef 5a 4c |\A.....A..ZL| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicket b/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicket index 42cbc3420dd..73d01585eb6 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicket +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicket @@ -1,92 +1,91 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 9b 01 00 00 97 03 03 22 89 61 60 36 |...........".a`6| -00000010 06 c6 00 3f af 09 28 13 d8 7e ae 18 55 40 4a 4e |...?..(..~..U@JN| -00000020 40 13 e2 f8 43 5f be e5 f6 51 04 00 00 04 00 2f |@...C_...Q...../| -00000030 00 ff 01 00 00 6a 00 00 00 0e 00 0c 00 00 09 31 |.....j.........1| -00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| -00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| -00000060 00 23 00 00 00 16 00 00 00 17 00 00 00 0d 00 30 |.#.............0| -00000070 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 08 0a |................| -00000080 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 03 03 |................| -00000090 02 03 03 01 02 01 03 02 02 02 04 02 05 02 06 02 |................| +00000000 16 03 01 00 71 01 00 00 6d 03 03 60 fd 9b 74 aa |....q...m..`..t.| +00000010 16 9f 07 32 7e 57 d0 91 86 ea 59 b7 f3 38 bb 4f |...2~W....Y..8.O| +00000020 7f 2c 36 eb 67 21 57 f2 12 2b 38 00 00 04 00 2f |.,6.g!W..+8..../| +00000030 00 ff 01 00 00 40 00 23 00 00 00 16 00 00 00 17 |.....@.#........| +00000040 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 |.....0..........| +00000050 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 |................| +00000060 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 02 |................| +00000070 04 02 05 02 06 02 |......| >>> Flow 2 (server to client) -00000000 16 03 03 00 3b 02 00 00 37 03 03 00 00 00 00 00 |....;...7.......| +00000000 16 03 03 00 35 02 00 00 31 03 03 00 00 00 00 00 |....5...1.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..| -00000030 0f 00 23 00 00 ff 01 00 01 00 00 0b 00 02 01 00 |..#.............| -00000040 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 |....Y...U..R..O0| -00000050 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 |..K0............| -00000060 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 |..?.[..0...*.H..| -00000070 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 |......0.1.0...U.| -00000080 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 |...Go1.0...U....| -00000090 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 |Go Root0...16010| -000000a0 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 |1000000Z..250101| -000000b0 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 |000000Z0.1.0...U| -000000c0 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 |....Go1.0...U...| -000000d0 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d |.Go0..0...*.H...| -000000e0 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 |.........0......| -000000f0 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 |.F}...'.H..(!.~.| -00000100 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 |..]..RE.z6G....B| -00000110 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 |[.....y.@.Om..+.| -00000120 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 |....g....."8.J.t| -00000130 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c |s+.4......t{.X.l| -00000140 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd |a<..A..++$#w[.;.| -00000150 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a |u]. T..c...$....| -00000160 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 |P....C...ub...R.| -00000170 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 |........0..0...U| -00000180 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 |...........0...U| -00000190 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......| -000001a0 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d |..+.......0...U.| -000001b0 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 |......0.0...U...| -000001c0 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 |.......CC>I..m..| -000001d0 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 |..`0...U.#..0...| -000001e0 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b |H.IM.~.1......n{| -000001f0 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 |0...U....0...exa| -00000200 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a |mple.golang0...*| -00000210 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 |.H.............0| -00000220 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 |.@+[P.a...SX...(| -00000230 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 |.X..8....1Z..f=C| -00000240 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc |.-...... d8.$:..| -00000250 cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd |..}.@ ._...a..v.| -00000260 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb |.....\.....l..s.| -00000270 b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 |.Cw.......@.a.Lr| -00000280 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 |+...F..M...>...B| -00000290 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 |...=.`.\!.;.....| -000002a0 03 00 04 0e 00 00 00 |.......| +00000030 09 00 23 00 00 ff 01 00 01 00 16 03 03 02 59 0b |..#...........Y.| +00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..| +00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.| +00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........| +00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1| +00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo| +00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000| +000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000| +000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go| +000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..| +000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........| +000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...| +000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R| +00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....| +00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.| +00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..| +00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.| +00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.| +00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C| +00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......| +00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......| +00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.| +00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...| +000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......| +000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........| +000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..| +000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~| +000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.| +000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g| +00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....| +00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.| +00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.| +00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....| +00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ | +00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\| +00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...| +00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.| +00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`| +00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e 00 00 |.\!.;...........| +000002a0 00 |.| >>> Flow 3 (client to server) -00000000 16 03 03 00 86 10 00 00 82 00 80 d0 71 60 6a 92 |............q`j.| -00000010 9b 01 87 1b d3 7d 28 a8 50 aa b9 c3 0e a3 b0 2d |.....}(.P......-| -00000020 2f 29 1d f1 42 39 6f 65 bb 1a 0e bc 82 43 e9 c6 |/)..B9oe.....C..| -00000030 c6 cc df 4e c6 f2 2b 85 26 cb 63 12 f7 a1 84 a1 |...N..+.&.c.....| -00000040 25 8b 8f 02 f2 c1 fe 09 79 89 ba da b7 b1 32 4c |%.......y.....2L| -00000050 56 4e d6 02 14 1a ed 03 87 ad d1 3e f1 5d 41 c5 |VN.........>.]A.| -00000060 c0 fe 8e ce 6c c2 ce 2e 4a f6 4f a0 f9 d7 a9 2d |....l...J.O....-| -00000070 22 62 78 5a a6 cb bb 62 98 20 fe f6 3d d3 b6 f8 |"bxZ...b. ..=...| -00000080 7f 1a 5a e5 59 32 93 bd f0 82 e5 14 03 03 00 01 |..Z.Y2..........| -00000090 01 16 03 03 00 40 96 3c c7 3f 87 d7 2e fb fb 2f |.....@.<.?...../| -000000a0 a0 0f 60 fc a9 9c 27 c2 0d e0 a6 f9 76 8c 94 59 |..`...'.....v..Y| -000000b0 02 ae 5c a3 b2 20 6f c7 a5 a3 ad 98 87 cf 29 02 |..\.. o.......).| -000000c0 87 ce db 09 ee b7 eb f4 81 59 37 13 15 5b 91 fe |.........Y7..[..| -000000d0 e7 b3 6f 69 fd d2 |..oi..| +00000000 16 03 03 00 86 10 00 00 82 00 80 2c d6 6d 84 0c |...........,.m..| +00000010 d9 ef 52 bb cc 0b 41 47 d7 64 c7 a6 b0 fa 3c 6f |..R...AG.d....>> Flow 4 (server to client) -00000000 16 03 03 00 82 04 00 00 7e 00 00 00 00 00 78 50 |........~.....xP| +00000000 16 03 03 00 8b 04 00 00 87 00 00 00 00 00 81 50 |...............P| 00000010 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 |F....8.{+....B>.| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................| -00000030 6f 2c 9f 83 61 5c 5f 43 13 c2 76 91 3a c1 1a 8c |o,..a\_C..v.:...| -00000040 51 00 5c a0 93 a9 06 e2 0c b0 65 e3 8c 0d 4b 7b |Q.\.......e...K{| -00000050 7e 52 32 b8 3c b3 76 c5 bf 95 4d 29 71 50 81 e3 |~R2.<.v...M)qP..| -00000060 2b 6f 4a 32 dc 33 94 15 c5 fe 38 b4 0a fc 03 38 |+oJ2.3....8....8| -00000070 90 32 db c0 7f 99 62 a9 89 15 d0 f6 79 64 79 38 |.2....b.....ydy8| -00000080 b0 e2 19 07 82 82 0a 14 03 03 00 01 01 16 03 03 |................| -00000090 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |.@..............| -000000a0 00 00 69 6f c8 63 ce 7b d5 82 6e f8 5f 59 ab ad |..io.c.{..n._Y..| -000000b0 55 0c 76 8b 11 56 77 ea 33 20 fd 0b 33 9d 72 12 |U.v..Vw.3 ..3.r.| -000000c0 85 fe 99 38 2a 70 49 fe 27 35 9d 43 5b 32 2b 77 |...8*pI.'5.C[2+w| -000000d0 31 66 17 03 03 00 40 00 00 00 00 00 00 00 00 00 |1f....@.........| -000000e0 00 00 00 00 00 00 00 05 36 d1 49 58 00 4d 5c bc |........6.IX.M\.| -000000f0 a8 c4 be 76 5d f7 cc 88 c7 5a 44 8c f6 d0 30 e6 |...v]....ZD...0.| -00000100 87 03 84 77 60 6c 47 70 2a 80 51 38 a8 8a fb 9f |...w`lGp*.Q8....| -00000110 31 45 f0 ab c9 e5 94 15 03 03 00 30 00 00 00 00 |1E.........0....| -00000120 00 00 00 00 00 00 00 00 00 00 00 00 19 f0 c7 ce |................| -00000130 92 87 25 dd 5b c3 68 3b dd ec 5c 26 c6 90 36 31 |..%.[.h;..\&..61| -00000140 a5 3c 9a 89 be 49 30 37 3b a5 5f 13 |.<...I07;._.| +00000030 6f 2c 9f 83 51 ed 14 ef 68 ca 42 c5 4c 92 cc 13 |o,..Q...h.B.L...| +00000040 05 4e 15 de 98 0a 74 d5 a9 2e 80 89 98 89 72 39 |.N....t.......r9| +00000050 5f fe 49 56 66 ac 4d 73 b1 5b 4b 81 db 25 a7 5b |_.IVf.Ms.[K..%.[| +00000060 54 5b 10 13 3d 96 71 d7 b7 23 53 ea 62 49 38 16 |T[..=.q..#S.bI8.| +00000070 cc 4f 0d 9d 80 99 6e 0f 01 b3 d7 e4 8a 75 d1 b6 |.O....n......u..| +00000080 7b 74 80 b2 b8 06 a9 71 6b 31 2a fd cf 6e 44 dc |{t.....qk1*..nD.| +00000090 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....| +000000a0 00 00 00 00 00 00 00 00 00 00 00 76 c4 85 3d 05 |...........v..=.| +000000b0 60 a2 b3 ce 38 7f 1c f9 e3 19 87 b0 e1 af 08 b7 |`...8...........| +000000c0 15 90 50 b9 51 85 c4 88 90 52 cd 6d b6 69 ee b5 |..P.Q....R.m.i..| +000000d0 36 a8 0c 61 c4 78 09 6a 49 4d e9 17 03 03 00 40 |6..a.x.jIM.....@| +000000e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +000000f0 76 31 e3 05 f8 b3 05 ca e2 55 84 b9 15 85 5d 4a |v1.......U....]J| +00000100 83 a5 76 db b0 5f b9 65 b4 21 3e 00 36 9a e8 d7 |..v.._.e.!>.6...| +00000110 02 81 23 83 19 13 c8 9c cd 02 ae 10 b9 cf 75 96 |..#...........u.| +00000120 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........| +00000130 00 00 00 00 00 f9 ae b4 16 27 75 dc 72 4d 39 0e |.........'u.rM9.| +00000140 ba 1f 31 b2 39 ec 99 36 bc 41 34 03 54 9b de 7b |..1.9..6.A4.T..{| +00000150 4b 65 ef 99 a6 |Ke...| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable b/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable index cc1b6b0173b..c50fbcedf7e 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable @@ -1,92 +1,91 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 9b 01 00 00 97 03 03 55 4e 24 f5 fd |...........UN$..| -00000010 2b 70 d1 b4 9c fd eb 53 1d 2f 7e f7 59 fe 20 c6 |+p.....S./~.Y. .| -00000020 4f 47 72 0f 7a 01 71 48 8a 21 9a 00 00 04 00 2f |OGr.z.qH.!...../| -00000030 00 ff 01 00 00 6a 00 00 00 0e 00 0c 00 00 09 31 |.....j.........1| -00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| -00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| -00000060 00 23 00 00 00 16 00 00 00 17 00 00 00 0d 00 30 |.#.............0| -00000070 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 08 0a |................| -00000080 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 03 03 |................| -00000090 02 03 03 01 02 01 03 02 02 02 04 02 05 02 06 02 |................| +00000000 16 03 01 00 71 01 00 00 6d 03 03 98 eb fe 13 a7 |....q...m.......| +00000010 81 d8 8b 0b c6 78 c3 44 ce f7 7b 63 d1 7c 61 4d |.....x.D..{c.|aM| +00000020 be fe 52 5f c0 24 88 c2 85 d1 40 00 00 04 00 2f |..R_.$....@..../| +00000030 00 ff 01 00 00 40 00 23 00 00 00 16 00 00 00 17 |.....@.#........| +00000040 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 |.....0..........| +00000050 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 |................| +00000060 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 02 |................| +00000070 04 02 05 02 06 02 |......| >>> Flow 2 (server to client) -00000000 16 03 03 00 3b 02 00 00 37 03 03 00 00 00 00 00 |....;...7.......| +00000000 16 03 03 00 35 02 00 00 31 03 03 00 00 00 00 00 |....5...1.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..| -00000030 0f 00 23 00 00 ff 01 00 01 00 00 0b 00 02 01 00 |..#.............| -00000040 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 |....Y...U..R..O0| -00000050 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 |..K0............| -00000060 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 |..?.[..0...*.H..| -00000070 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 |......0.1.0...U.| -00000080 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 |...Go1.0...U....| -00000090 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 |Go Root0...16010| -000000a0 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 |1000000Z..250101| -000000b0 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 |000000Z0.1.0...U| -000000c0 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 |....Go1.0...U...| -000000d0 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d |.Go0..0...*.H...| -000000e0 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 |.........0......| -000000f0 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 |.F}...'.H..(!.~.| -00000100 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 |..]..RE.z6G....B| -00000110 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 |[.....y.@.Om..+.| -00000120 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 |....g....."8.J.t| -00000130 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c |s+.4......t{.X.l| -00000140 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd |a<..A..++$#w[.;.| -00000150 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a |u]. T..c...$....| -00000160 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 |P....C...ub...R.| -00000170 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 |........0..0...U| -00000180 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 |...........0...U| -00000190 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......| -000001a0 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d |..+.......0...U.| -000001b0 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 |......0.0...U...| -000001c0 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 |.......CC>I..m..| -000001d0 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 |..`0...U.#..0...| -000001e0 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b |H.IM.~.1......n{| -000001f0 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 |0...U....0...exa| -00000200 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a |mple.golang0...*| -00000210 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 |.H.............0| -00000220 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 |.@+[P.a...SX...(| -00000230 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 |.X..8....1Z..f=C| -00000240 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc |.-...... d8.$:..| -00000250 cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd |..}.@ ._...a..v.| -00000260 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb |.....\.....l..s.| -00000270 b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 |.Cw.......@.a.Lr| -00000280 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 |+...F..M...>...B| -00000290 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 |...=.`.\!.;.....| -000002a0 03 00 04 0e 00 00 00 |.......| +00000030 09 00 23 00 00 ff 01 00 01 00 16 03 03 02 59 0b |..#...........Y.| +00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..| +00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.| +00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........| +00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1| +00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo| +00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000| +000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000| +000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go| +000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..| +000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........| +000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...| +000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R| +00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....| +00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.| +00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..| +00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.| +00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.| +00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C| +00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......| +00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......| +00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.| +00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...| +000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......| +000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........| +000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..| +000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~| +000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.| +000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g| +00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....| +00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.| +00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.| +00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....| +00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ | +00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\| +00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...| +00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.| +00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`| +00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e 00 00 |.\!.;...........| +000002a0 00 |.| >>> Flow 3 (client to server) -00000000 16 03 03 00 86 10 00 00 82 00 80 29 31 85 e2 ce |...........)1...| -00000010 42 63 7f 16 3a 0b 67 19 64 da bb 7a bc fe c7 a9 |Bc..:.g.d..z....| -00000020 fb f1 d0 c1 7e 3d 2e 69 f8 97 43 7e 73 8a eb 9a |....~=.i..C~s...| -00000030 e4 f4 d0 e8 93 47 ec c1 89 a0 d3 93 65 47 1c 33 |.....G......eG.3| -00000040 75 af 90 07 bb 46 27 09 c6 0c 4f 43 10 87 c9 a6 |u....F'...OC....| -00000050 da 58 02 a7 61 4b 67 40 05 72 9b 07 aa 9b 04 18 |.X..aKg@.r......| -00000060 6a 35 d1 54 f8 fc 08 f5 9f 49 8d aa aa 4c 2c bf |j5.T.....I...L,.| -00000070 55 85 ed 6b ae 7e cd 77 a2 9b e3 a7 03 8d 9e d9 |U..k.~.w........| -00000080 12 12 ce 1c c4 ba 10 f3 d5 f4 c2 14 03 03 00 01 |................| -00000090 01 16 03 03 00 40 2c 57 5d 8b 73 4f 31 ed 16 e5 |.....@,W].sO1...| -000000a0 17 bd 08 a9 26 95 51 0d f6 0c 82 af f2 26 9e 5e |....&.Q......&.^| -000000b0 31 71 e5 7c dc 41 62 10 da d5 20 f1 dc 00 ea 25 |1q.|.Ab... ....%| -000000c0 5a 4b 15 e1 ba 46 c1 5f 64 a6 59 58 55 2a 01 41 |ZK...F._d.YXU*.A| -000000d0 3e 6b 22 b8 79 27 |>k".y'| +00000000 16 03 03 00 86 10 00 00 82 00 80 11 4c a1 a0 ba |............L...| +00000010 12 83 63 98 3c 1a 5d df a2 01 b6 6c 05 ec a1 1e |..c.<.]....l....| +00000020 dc a5 6b b9 97 c3 76 51 06 45 4b 74 9e 1b 61 0f |..k...vQ.EKt..a.| +00000030 9e d3 c7 db 7f d3 ee 23 1a 32 66 0f 2f 2c d3 52 |.......#.2f./,.R| +00000040 e0 ec cc 31 71 d4 e6 2b b6 95 78 0b eb c9 70 b1 |...1q..+..x...p.| +00000050 77 09 6f 8d 6d 8d 1b d7 b2 38 96 d3 f0 a2 94 37 |w.o.m....8.....7| +00000060 14 ed d8 d6 b5 1e bc 71 b2 35 68 76 5b 10 dc 8f |.......q.5hv[...| +00000070 de 9d 1d b5 59 d0 f1 04 70 9b 74 a9 af 7f b6 6b |....Y...p.t....k| +00000080 de 29 5a fd 8f 95 cd 2c d6 b9 18 14 03 03 00 01 |.)Z....,........| +00000090 01 16 03 03 00 40 02 70 cb 83 3c 42 32 58 9f 05 |.....@.p..>> Flow 4 (server to client) -00000000 16 03 03 00 82 04 00 00 7e 00 00 00 00 00 78 50 |........~.....xP| +00000000 16 03 03 00 8b 04 00 00 87 00 00 00 00 00 81 50 |...............P| 00000010 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 |F....8.{+....B>.| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................| -00000030 6f 2c 9f 83 61 31 33 93 70 cd 6a 19 a2 67 e8 7d |o,..a13.p.j..g.}| -00000040 cb a4 dc bb 80 d9 23 20 05 4d 53 1f b6 9f 48 01 |......# .MS...H.| -00000050 e4 84 75 10 25 f9 ed 98 bb 39 7e fc 8b 16 d8 bc |..u.%....9~.....| -00000060 c7 e9 88 e8 1c 33 94 10 13 6b d4 3d fa d7 73 b2 |.....3...k.=..s.| -00000070 d4 ea 89 58 ed 38 f8 f3 6a e0 5f 1e f7 49 ed f7 |...X.8..j._..I..| -00000080 5f 64 39 6b b5 6c fb 14 03 03 00 01 01 16 03 03 |_d9k.l..........| -00000090 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |.@..............| -000000a0 00 00 fa f3 aa 48 54 5f 5b 88 69 fb 01 75 2a 90 |.....HT_[.i..u*.| -000000b0 49 46 7c 6a 3a aa 72 4e 35 db 8f 38 a3 4d 05 53 |IF|j:.rN5..8.M.S| -000000c0 38 93 63 ae 0d b9 e0 b4 81 2e ee 40 d5 2b 58 2a |8.c........@.+X*| -000000d0 18 9b 17 03 03 00 40 00 00 00 00 00 00 00 00 00 |......@.........| -000000e0 00 00 00 00 00 00 00 3c 84 3f 45 03 b0 60 ed 8f |.......<.?E..`..| -000000f0 d2 e5 10 98 03 1a 00 8a aa 19 d0 e9 03 fb 42 fc |..............B.| -00000100 cd 4d 13 3e 7d 39 0b 5f cf 2d b7 87 3a bf 43 d4 |.M.>}9._.-..:.C.| -00000110 ac 71 68 29 bf f8 ac 15 03 03 00 30 00 00 00 00 |.qh).......0....| -00000120 00 00 00 00 00 00 00 00 00 00 00 00 81 49 eb 3b |.............I.;| -00000130 28 e7 88 94 8b 6a cc 67 4d c4 03 66 80 af d7 c2 |(....j.gM..f....| -00000140 07 37 36 3b f0 a4 5d 16 2b 5f 5b 27 |.76;..].+_['| +00000030 6f 2c 9f 83 51 ed 14 ef 68 ca 42 c5 4c 3e 73 fe |o,..Q...h.B.L>s.| +00000040 72 ef 06 25 96 ef 3d 89 51 22 e3 10 57 02 e5 69 |r..%..=.Q"..W..i| +00000050 aa d0 6d ad 66 b3 4c 07 fc ba a4 1e 3a ad a2 3b |..m.f.L.....:..;| +00000060 40 f7 7d 9a 11 8e a0 9e 54 c5 7c 53 7d 49 38 16 |@.}.....T.|S}I8.| +00000070 43 a6 1b 37 8e aa 02 78 25 9b 06 54 13 54 de 6a |C..7...x%..T.T.j| +00000080 ae 62 72 97 47 1d f8 0a 32 c3 86 93 0e 64 cc 04 |.br.G...2....d..| +00000090 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....| +000000a0 00 00 00 00 00 00 00 00 00 00 00 ac 24 92 7d 6c |............$.}l| +000000b0 d5 fe a8 a7 b7 45 fe 58 f6 13 02 ed de c8 ba 44 |.....E.X.......D| +000000c0 18 59 1e f9 06 82 2f 42 22 62 5a 82 4d 70 9a c3 |.Y..../B"bZ.Mp..| +000000d0 41 55 b0 66 ae e2 b1 1d d9 38 0a 17 03 03 00 40 |AU.f.....8.....@| +000000e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +000000f0 bd 16 9e 9c f2 9b 0d f8 f1 42 ba f3 38 64 69 ac |.........B..8di.| +00000100 4a c9 25 d7 03 0b ec 8f 53 14 26 68 da b7 43 34 |J.%.....S.&h..C4| +00000110 18 cd 66 dc 36 5e f5 16 ca 18 78 37 89 8a d5 9d |..f.6^....x7....| +00000120 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........| +00000130 00 00 00 00 00 64 f9 5c df db 60 b7 22 15 77 29 |.....d.\..`.".w)| +00000140 33 6f 93 22 81 c4 e5 71 af 27 60 e5 76 5f a6 f6 |3o."...q.'`.v_..| +00000150 e0 73 87 9f ed |.s...| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-Resume b/libgo/go/crypto/tls/testdata/Server-TLSv12-Resume index d1dba66d82d..e8205b743d7 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-Resume +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-Resume @@ -1,48 +1,46 @@ >>> Flow 1 (client to server) -00000000 16 03 01 01 33 01 00 01 2f 03 03 c0 ac ee 47 eb |....3.../.....G.| -00000010 75 70 12 a9 b7 d9 29 03 ba dd 0c 26 ef 07 cd c1 |up....)....&....| -00000020 ac 2b b5 14 8a 59 3a d7 58 7d 20 20 eb 74 37 f4 |.+...Y:.X} .t7.| -00000030 79 3b 34 ed e4 b1 51 00 b9 09 04 bc 48 82 07 a2 |y;4...Q.....H...| -00000040 cc 47 2d dc 16 54 a6 02 0c 5e f2 23 00 04 00 2f |.G-..T...^.#.../| -00000050 00 ff 01 00 00 e2 00 00 00 0e 00 0c 00 00 09 31 |...............1| -00000060 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| -00000070 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| -00000080 00 23 00 78 50 46 ad c1 db a8 38 86 7b 2b bb fd |.#.xPF....8.{+..| -00000090 d0 c3 42 3e 00 00 00 00 00 00 00 00 00 00 00 00 |..B>............| -000000a0 00 00 00 00 94 6f 2c 9f 83 61 5c 5f 43 13 c2 76 |.....o,..a\_C..v| -000000b0 91 3a c1 1a 8c 51 00 5c a0 93 a9 06 e2 0c b0 65 |.:...Q.\.......e| -000000c0 e3 8c 0d 4b 7b 7e 52 32 b8 3c b3 76 c5 bf 95 4d |...K{~R2.<.v...M| -000000d0 29 71 50 81 e3 2b 6f 4a 32 dc 33 94 15 c5 fe 38 |)qP..+oJ2.3....8| -000000e0 b4 0a fc 03 38 90 32 db c0 7f 99 62 a9 89 15 d0 |....8.2....b....| -000000f0 f6 79 64 79 38 b0 e2 19 07 82 82 0a 00 16 00 00 |.ydy8...........| -00000100 00 17 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 |.......0........| -00000110 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 |................| -00000120 04 01 05 01 06 01 03 03 02 03 03 01 02 01 03 02 |................| -00000130 02 02 04 02 05 02 06 02 |........| +00000000 16 03 01 01 12 01 00 01 0e 03 03 3e 4f b2 97 44 |...........>O..D| +00000010 64 a4 e1 33 32 21 98 ea c1 8c 3f 7b 5f 47 e6 54 |d..32!....?{_G.T| +00000020 bf f1 a9 fd fb 5c 1e c9 23 7a 12 20 42 f6 4f a1 |.....\..#z. B.O.| +00000030 85 90 ad 50 2b 3b 24 f7 2e 48 1f 2d 5b 0d fe 77 |...P+;$..H.-[..w| +00000040 07 2b cb e9 03 23 d9 24 04 05 4e 26 00 04 00 2f |.+...#.$..N&.../| +00000050 00 ff 01 00 00 c1 00 23 00 81 50 46 ad c1 db a8 |.......#..PF....| +00000060 38 86 7b 2b bb fd d0 c3 42 3e 00 00 00 00 00 00 |8.{+....B>......| +00000070 00 00 00 00 00 00 00 00 00 00 94 6f 2c 9f 83 51 |...........o,..Q| +00000080 ed 14 ef 68 ca 42 c5 4c 92 cc 13 05 4e 15 de 98 |...h.B.L....N...| +00000090 0a 74 d5 a9 2e 80 89 98 89 72 39 5f fe 49 56 66 |.t.......r9_.IVf| +000000a0 ac 4d 73 b1 5b 4b 81 db 25 a7 5b 54 5b 10 13 3d |.Ms.[K..%.[T[..=| +000000b0 96 71 d7 b7 23 53 ea 62 49 38 16 cc 4f 0d 9d 80 |.q..#S.bI8..O...| +000000c0 99 6e 0f 01 b3 d7 e4 8a 75 d1 b6 7b 74 80 b2 b8 |.n......u..{t...| +000000d0 06 a9 71 6b 31 2a fd cf 6e 44 dc 00 16 00 00 00 |..qk1*..nD......| +000000e0 17 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 |......0.........| +000000f0 07 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 04 |................| +00000100 01 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 |................| +00000110 02 04 02 05 02 06 02 |.......| >>> Flow 2 (server to client) -00000000 16 03 03 00 57 02 00 00 53 03 03 00 00 00 00 00 |....W...S.......| +00000000 16 03 03 00 51 02 00 00 4d 03 03 00 00 00 00 00 |....Q...M.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -00000020 00 00 00 44 4f 57 4e 47 52 44 01 20 eb 74 37 f4 |...DOWNGRD. .t7.| -00000030 79 3b 34 ed e4 b1 51 00 b9 09 04 bc 48 82 07 a2 |y;4...Q.....H...| -00000040 cc 47 2d dc 16 54 a6 02 0c 5e f2 23 00 2f 00 00 |.G-..T...^.#./..| -00000050 0b ff 01 00 01 00 00 0b 00 02 01 00 14 03 03 00 |................| -00000060 01 01 16 03 03 00 40 00 00 00 00 00 00 00 00 00 |......@.........| -00000070 00 00 00 00 00 00 00 a6 49 4b 9d e0 3c e1 58 b4 |........IK..<.X.| -00000080 f9 50 e6 a6 32 ce 65 74 14 95 07 05 0c ef be 7d |.P..2.et.......}| -00000090 74 8c 46 3e 2a 07 de 5f 7a 08 b9 a0 80 f0 52 90 |t.F>*.._z.....R.| -000000a0 d4 6b c5 0f c5 ae 54 |.k....T| +00000020 00 00 00 44 4f 57 4e 47 52 44 01 20 42 f6 4f a1 |...DOWNGRD. B.O.| +00000030 85 90 ad 50 2b 3b 24 f7 2e 48 1f 2d 5b 0d fe 77 |...P+;$..H.-[..w| +00000040 07 2b cb e9 03 23 d9 24 04 05 4e 26 00 2f 00 00 |.+...#.$..N&./..| +00000050 05 ff 01 00 01 00 14 03 03 00 01 01 16 03 03 00 |................| +00000060 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |@...............| +00000070 00 dc 9b ca 90 7b f0 70 bc 17 76 9c fb a7 74 49 |.....{.p..v...tI| +00000080 0c 9f 3c 31 76 77 9b af 6a e0 00 a6 54 81 4a d5 |..<1vw..j...T.J.| +00000090 de fa 75 cb d6 b4 b2 6c bc f4 30 7a a1 56 0a f5 |..u....l..0z.V..| +000000a0 5c |\| >>> Flow 3 (client to server) -00000000 14 03 03 00 01 01 16 03 03 00 40 8c 59 48 06 01 |..........@.YH..| -00000010 a4 c6 35 ad a6 f5 a9 d3 31 ea 58 64 0e 45 91 4c |..5.....1.Xd.E.L| -00000020 fb e7 c6 6e 27 e8 92 a9 9c c3 c6 29 e9 6c 55 3a |...n'......).lU:| -00000030 2a fe 0f 40 d9 aa 3e fe ab 66 e1 38 91 d1 db ac |*..@..>..f.8....| -00000040 58 13 f0 3c 5e f1 a9 9c fd 07 04 |X..<^......| +00000000 14 03 03 00 01 01 16 03 03 00 40 cb 74 dc ec f5 |..........@.t...| +00000010 ad ab c5 8e dc da 50 89 28 7b cc 0f 06 87 9a 19 |......P.({......| +00000020 dd 4e 40 38 1d 8f 95 6f 0e 62 5f cb 7c db ab 24 |.N@8...o.b_.|..$| +00000030 df 03 ef 7c 83 12 0e 3d 25 e8 de cf d0 aa 0e 91 |...|...=%.......| +00000040 20 9b 38 39 4e 39 70 3c 0a ce c8 | .89N9p<...| >>> Flow 4 (server to client) 00000000 17 03 03 00 40 00 00 00 00 00 00 00 00 00 00 00 |....@...........| -00000010 00 00 00 00 00 a6 4f 7a f8 b0 6e 25 13 fb b6 68 |......Oz..n%...h| -00000020 2d 1e 22 1b 95 93 63 e8 e1 9c 93 3e 53 78 bb aa |-."...c....>Sx..| -00000030 9f 6e 84 56 28 31 a0 ed a9 a3 06 fd e6 f9 c4 c4 |.n.V(1..........| -00000040 56 5f 5f c2 fb 15 03 03 00 30 00 00 00 00 00 00 |V__......0......| -00000050 00 00 00 00 00 00 00 00 00 00 c9 98 24 06 26 73 |............$.&s| -00000060 87 27 73 bd 7a 30 b5 85 28 f7 c4 b6 7a b0 96 9f |.'s.z0..(...z...| -00000070 a8 d4 43 1d 8e f5 a5 9f f3 f3 |..C.......| +00000010 00 00 00 00 00 d1 5b 42 2c 10 9b 48 97 cf 8e 69 |......[B,..H...i| +00000020 a4 b4 62 65 d9 f1 1f 86 07 f1 6c cd 5b 18 6e c7 |..be......l.[.n.| +00000030 8d 57 20 3d f9 3f 68 1b 12 7b 29 13 b9 8d fe 7b |.W =.?h..{)....{| +00000040 ad 52 22 c4 94 15 03 03 00 30 00 00 00 00 00 00 |.R"......0......| +00000050 00 00 00 00 00 00 00 00 00 00 31 ae ae 06 b7 2c |..........1....,| +00000060 5f a4 fc 8f a6 33 2b 42 1a f5 d5 b9 ad a4 fc a0 |_....3+B........| +00000070 bc e9 c8 5d 4d 26 83 38 ca 57 |...]M&.8.W| diff --git a/libgo/go/crypto/tls/ticket.go b/libgo/go/crypto/tls/ticket.go index c873e43a70b..6c1d20da206 100644 --- a/libgo/go/crypto/tls/ticket.go +++ b/libgo/go/crypto/tls/ticket.go @@ -12,8 +12,9 @@ import ( "crypto/sha256" "crypto/subtle" "errors" - "golang.org/x/crypto/cryptobyte" "io" + + "golang.org/x/crypto/cryptobyte" ) // sessionState contains the information that is serialized into a session @@ -21,88 +22,56 @@ import ( type sessionState struct { vers uint16 cipherSuite uint16 - masterSecret []byte - certificates [][]byte + createdAt uint64 + masterSecret []byte // opaque master_secret<1..2^16-1>; + // struct { opaque certificate<1..2^24-1> } Certificate; + certificates [][]byte // Certificate certificate_list<0..2^24-1>; + // usedOldKey is true if the ticket from which this session came from // was encrypted with an older key and thus should be refreshed. usedOldKey bool } -func (s *sessionState) marshal() []byte { - length := 2 + 2 + 2 + len(s.masterSecret) + 2 - for _, cert := range s.certificates { - length += 4 + len(cert) - } - - ret := make([]byte, length) - x := ret - x[0] = byte(s.vers >> 8) - x[1] = byte(s.vers) - x[2] = byte(s.cipherSuite >> 8) - x[3] = byte(s.cipherSuite) - x[4] = byte(len(s.masterSecret) >> 8) - x[5] = byte(len(s.masterSecret)) - x = x[6:] - copy(x, s.masterSecret) - x = x[len(s.masterSecret):] - - x[0] = byte(len(s.certificates) >> 8) - x[1] = byte(len(s.certificates)) - x = x[2:] - - for _, cert := range s.certificates { - x[0] = byte(len(cert) >> 24) - x[1] = byte(len(cert) >> 16) - x[2] = byte(len(cert) >> 8) - x[3] = byte(len(cert)) - copy(x[4:], cert) - x = x[4+len(cert):] - } - - return ret +func (m *sessionState) marshal() []byte { + var b cryptobyte.Builder + b.AddUint16(m.vers) + b.AddUint16(m.cipherSuite) + addUint64(&b, m.createdAt) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(m.masterSecret) + }) + b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { + for _, cert := range m.certificates { + b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(cert) + }) + } + }) + return b.BytesOrPanic() } -func (s *sessionState) unmarshal(data []byte) bool { - if len(data) < 8 { - return false - } - - s.vers = uint16(data[0])<<8 | uint16(data[1]) - s.cipherSuite = uint16(data[2])<<8 | uint16(data[3]) - masterSecretLen := int(data[4])<<8 | int(data[5]) - data = data[6:] - if len(data) < masterSecretLen { +func (m *sessionState) unmarshal(data []byte) bool { + *m = sessionState{usedOldKey: m.usedOldKey} + s := cryptobyte.String(data) + if ok := s.ReadUint16(&m.vers) && + s.ReadUint16(&m.cipherSuite) && + readUint64(&s, &m.createdAt) && + readUint16LengthPrefixed(&s, &m.masterSecret) && + len(m.masterSecret) != 0; !ok { return false } - - s.masterSecret = data[:masterSecretLen] - data = data[masterSecretLen:] - - if len(data) < 2 { + var certList cryptobyte.String + if !s.ReadUint24LengthPrefixed(&certList) { return false } - - numCerts := int(data[0])<<8 | int(data[1]) - data = data[2:] - - s.certificates = make([][]byte, numCerts) - for i := range s.certificates { - if len(data) < 4 { + for !certList.Empty() { + var cert []byte + if !readUint24LengthPrefixed(&certList, &cert) { return false } - certLen := int(data[0])<<24 | int(data[1])<<16 | int(data[2])<<8 | int(data[3]) - data = data[4:] - if certLen < 0 { - return false - } - if len(data) < certLen { - return false - } - s.certificates[i] = data[:certLen] - data = data[certLen:] + m.certificates = append(m.certificates, cert) } - - return len(data) == 0 + return s.Empty() } // sessionStateTLS13 is the content of a TLS 1.3 session ticket. Its first @@ -148,6 +117,10 @@ func (m *sessionStateTLS13) unmarshal(data []byte) bool { } func (c *Conn) encryptTicket(state []byte) ([]byte, error) { + if len(c.ticketKeys) == 0 { + return nil, errors.New("tls: internal error: session ticket keys unavailable") + } + encrypted := make([]byte, ticketKeyNameLen+aes.BlockSize+len(state)+sha256.Size) keyName := encrypted[:ticketKeyNameLen] iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize] @@ -156,7 +129,7 @@ func (c *Conn) encryptTicket(state []byte) ([]byte, error) { if _, err := io.ReadFull(c.config.rand(), iv); err != nil { return nil, err } - key := c.config.ticketKeys()[0] + key := c.ticketKeys[0] copy(keyName, key.keyName[:]) block, err := aes.NewCipher(key.aesKey[:]) if err != nil { @@ -181,19 +154,17 @@ func (c *Conn) decryptTicket(encrypted []byte) (plaintext []byte, usedOldKey boo macBytes := encrypted[len(encrypted)-sha256.Size:] ciphertext := encrypted[ticketKeyNameLen+aes.BlockSize : len(encrypted)-sha256.Size] - keys := c.config.ticketKeys() keyIndex := -1 - for i, candidateKey := range keys { + for i, candidateKey := range c.ticketKeys { if bytes.Equal(keyName, candidateKey.keyName[:]) { keyIndex = i break } } - if keyIndex == -1 { return nil, false } - key := &keys[keyIndex] + key := &c.ticketKeys[keyIndex] mac := hmac.New(sha256.New, key.hmacKey[:]) mac.Write(encrypted[:len(encrypted)-sha256.Size]) diff --git a/libgo/go/crypto/tls/tls.go b/libgo/go/crypto/tls/tls.go index af44485f44e..454aa0bbbc0 100644 --- a/libgo/go/crypto/tls/tls.go +++ b/libgo/go/crypto/tls/tls.go @@ -13,6 +13,7 @@ package tls import ( "bytes" + "context" "crypto" "crypto/ecdsa" "crypto/ed25519" @@ -32,7 +33,12 @@ import ( // The configuration config must be non-nil and must include // at least one certificate or else set GetCertificate. func Server(conn net.Conn, config *Config) *Conn { - return &Conn{conn: conn, config: config} + c := &Conn{ + conn: conn, + config: config, + } + c.handshakeFn = c.serverHandshake + return c } // Client returns a new TLS client side connection @@ -40,7 +46,13 @@ func Server(conn net.Conn, config *Config) *Conn { // The config cannot be nil: users must set either ServerName or // InsecureSkipVerify in the config. func Client(conn net.Conn, config *Config) *Conn { - return &Conn{conn: conn, config: config, isClient: true} + c := &Conn{ + conn: conn, + config: config, + isClient: true, + } + c.handshakeFn = c.clientHandshake + return c } // A listener implements a network listener (net.Listener) for TLS connections. @@ -100,29 +112,35 @@ func (timeoutError) Temporary() bool { return true } // DialWithDialer interprets a nil configuration as equivalent to the zero // configuration; see the documentation of Config for the defaults. func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*Conn, error) { + return dial(context.Background(), dialer, network, addr, config) +} + +func dial(ctx context.Context, netDialer *net.Dialer, network, addr string, config *Config) (*Conn, error) { // We want the Timeout and Deadline values from dialer to cover the // whole process: TCP connection and TLS handshake. This means that we // also need to start our own timers now. - timeout := dialer.Timeout + timeout := netDialer.Timeout - if !dialer.Deadline.IsZero() { - deadlineTimeout := time.Until(dialer.Deadline) + if !netDialer.Deadline.IsZero() { + deadlineTimeout := time.Until(netDialer.Deadline) if timeout == 0 || deadlineTimeout < timeout { timeout = deadlineTimeout } } - var errChannel chan error - + // hsErrCh is non-nil if we might not wait for Handshake to complete. + var hsErrCh chan error + if timeout != 0 || ctx.Done() != nil { + hsErrCh = make(chan error, 2) + } if timeout != 0 { - errChannel = make(chan error, 2) timer := time.AfterFunc(timeout, func() { - errChannel <- timeoutError{} + hsErrCh <- timeoutError{} }) defer timer.Stop() } - rawConn, err := dialer.Dial(network, addr) + rawConn, err := netDialer.DialContext(ctx, network, addr) if err != nil { return nil, err } @@ -147,14 +165,26 @@ func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (* conn := Client(rawConn, config) - if timeout == 0 { + if hsErrCh == nil { err = conn.Handshake() } else { go func() { - errChannel <- conn.Handshake() + hsErrCh <- conn.Handshake() }() - err = <-errChannel + select { + case <-ctx.Done(): + err = ctx.Err() + case err = <-hsErrCh: + if err != nil { + // If the error was due to the context + // closing, prefer the context's error, rather + // than some random network teardown error. + if e := ctx.Err(); e != nil { + err = e + } + } + } } if err != nil { @@ -175,6 +205,54 @@ func Dial(network, addr string, config *Config) (*Conn, error) { return DialWithDialer(new(net.Dialer), network, addr, config) } +// Dialer dials TLS connections given a configuration and a Dialer for the +// underlying connection. +type Dialer struct { + // NetDialer is the optional dialer to use for the TLS connections' + // underlying TCP connections. + // A nil NetDialer is equivalent to the net.Dialer zero value. + NetDialer *net.Dialer + + // Config is the TLS configuration to use for new connections. + // A nil configuration is equivalent to the zero + // configuration; see the documentation of Config for the + // defaults. + Config *Config +} + +// Dial connects to the given network address and initiates a TLS +// handshake, returning the resulting TLS connection. +// +// The returned Conn, if any, will always be of type *Conn. +func (d *Dialer) Dial(network, addr string) (net.Conn, error) { + return d.DialContext(context.Background(), network, addr) +} + +func (d *Dialer) netDialer() *net.Dialer { + if d.NetDialer != nil { + return d.NetDialer + } + return new(net.Dialer) +} + +// DialContext connects to the given network address and initiates a TLS +// handshake, returning the resulting TLS connection. +// +// The provided Context must be non-nil. If the context expires before +// the connection is complete, an error is returned. Once successfully +// connected, any expiration of the context will not affect the +// connection. +// +// The returned Conn, if any, will always be of type *Conn. +func (d *Dialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error) { + c, err := dial(ctx, d.netDialer(), network, addr, d.Config) + if err != nil { + // Don't return c (a typed nil) in an interface. + return nil, err + } + return c, nil +} + // LoadX509KeyPair reads and parses a public/private key pair from a pair // of files. The files must contain PEM encoded data. The certificate file // may contain intermediate certificates following the leaf certificate to @@ -287,7 +365,7 @@ func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) { } // Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates -// PKCS#1 private keys by default, while OpenSSL 1.0.0 generates PKCS#8 keys. +// PKCS #1 private keys by default, while OpenSSL 1.0.0 generates PKCS #8 keys. // OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three. func parsePrivateKey(der []byte) (crypto.PrivateKey, error) { if key, err := x509.ParsePKCS1PrivateKey(der); err == nil { diff --git a/libgo/go/crypto/tls/tls_test.go b/libgo/go/crypto/tls/tls_test.go index 178b519f1cc..198423414b9 100644 --- a/libgo/go/crypto/tls/tls_test.go +++ b/libgo/go/crypto/tls/tls_test.go @@ -6,6 +6,7 @@ package tls import ( "bytes" + "context" "crypto" "crypto/x509" "encoding/json" @@ -201,6 +202,118 @@ func TestDialTimeout(t *testing.T) { } } +func TestDeadlineOnWrite(t *testing.T) { + if testing.Short() { + t.Skip("skipping in short mode") + } + + ln := newLocalListener(t) + defer ln.Close() + + srvCh := make(chan *Conn, 1) + + go func() { + sconn, err := ln.Accept() + if err != nil { + srvCh <- nil + return + } + srv := Server(sconn, testConfig.Clone()) + if err := srv.Handshake(); err != nil { + srvCh <- nil + return + } + srvCh <- srv + }() + + clientConfig := testConfig.Clone() + clientConfig.MaxVersion = VersionTLS12 + conn, err := Dial("tcp", ln.Addr().String(), clientConfig) + if err != nil { + t.Fatal(err) + } + defer conn.Close() + + srv := <-srvCh + if srv == nil { + t.Error(err) + } + + // Make sure the client/server is setup correctly and is able to do a typical Write/Read + buf := make([]byte, 6) + if _, err := srv.Write([]byte("foobar")); err != nil { + t.Errorf("Write err: %v", err) + } + if n, err := conn.Read(buf); n != 6 || err != nil || string(buf) != "foobar" { + t.Errorf("Read = %d, %v, data %q; want 6, nil, foobar", n, err, buf) + } + + // Set a deadline which should cause Write to timeout + if err = srv.SetDeadline(time.Now()); err != nil { + t.Fatalf("SetDeadline(time.Now()) err: %v", err) + } + if _, err = srv.Write([]byte("should fail")); err == nil { + t.Fatal("Write should have timed out") + } + + // Clear deadline and make sure it still times out + if err = srv.SetDeadline(time.Time{}); err != nil { + t.Fatalf("SetDeadline(time.Time{}) err: %v", err) + } + if _, err = srv.Write([]byte("This connection is permanently broken")); err == nil { + t.Fatal("Write which previously failed should still time out") + } + + // Verify the error + if ne := err.(net.Error); ne.Temporary() != false { + t.Error("Write timed out but incorrectly classified the error as Temporary") + } + if !isTimeoutError(err) { + t.Error("Write timed out but did not classify the error as a Timeout") + } +} + +type readerFunc func([]byte) (int, error) + +func (f readerFunc) Read(b []byte) (int, error) { return f(b) } + +// TestDialer tests that tls.Dialer.DialContext can abort in the middle of a handshake. +// (The other cases are all handled by the existing dial tests in this package, which +// all also flow through the same code shared code paths) +func TestDialer(t *testing.T) { + ln := newLocalListener(t) + defer ln.Close() + + unblockServer := make(chan struct{}) // close-only + defer close(unblockServer) + go func() { + conn, err := ln.Accept() + if err != nil { + return + } + defer conn.Close() + <-unblockServer + }() + + ctx, cancel := context.WithCancel(context.Background()) + d := Dialer{Config: &Config{ + Rand: readerFunc(func(b []byte) (n int, err error) { + // By the time crypto/tls wants randomness, that means it has a TCP + // connection, so we're past the Dialer's dial and now blocked + // in a handshake. Cancel our context and see if we get unstuck. + // (Our TCP listener above never reads or writes, so the Handshake + // would otherwise be stuck forever) + cancel() + return len(b), nil + }), + ServerName: "foo", + }} + _, err := d.DialContext(ctx, "tcp", ln.Addr().String()) + if err != context.Canceled { + t.Errorf("err = %v; want context.Canceled", err) + } +} + func isTimeoutError(err error) bool { if ne, ok := err.(net.Error); ok { return ne.Timeout() @@ -294,7 +407,11 @@ func TestTLSUniqueMatches(t *testing.T) { defer ln.Close() serverTLSUniques := make(chan []byte) + parentDone := make(chan struct{}) + childDone := make(chan struct{}) + defer close(parentDone) go func() { + defer close(childDone) for i := 0; i < 2; i++ { sconn, err := ln.Accept() if err != nil { @@ -308,7 +425,11 @@ func TestTLSUniqueMatches(t *testing.T) { t.Error(err) return } - serverTLSUniques <- srv.ConnectionState().TLSUnique + select { + case <-parentDone: + return + case serverTLSUniques <- srv.ConnectionState().TLSUnique: + } } }() @@ -318,7 +439,15 @@ func TestTLSUniqueMatches(t *testing.T) { if err != nil { t.Fatal(err) } - if !bytes.Equal(conn.ConnectionState().TLSUnique, <-serverTLSUniques) { + + var serverTLSUniquesValue []byte + select { + case <-childDone: + return + case serverTLSUniquesValue = <-serverTLSUniques: + } + + if !bytes.Equal(conn.ConnectionState().TLSUnique, serverTLSUniquesValue) { t.Error("client and server channel bindings differ") } conn.Close() @@ -331,7 +460,14 @@ func TestTLSUniqueMatches(t *testing.T) { if !conn.ConnectionState().DidResume { t.Error("second session did not use resumption") } - if !bytes.Equal(conn.ConnectionState().TLSUnique, <-serverTLSUniques) { + + select { + case <-childDone: + return + case serverTLSUniquesValue = <-serverTLSUniques: + } + + if !bytes.Equal(conn.ConnectionState().TLSUnique, serverTLSUniquesValue) { t.Error("client and server channel bindings differ when session resumption is used") } } @@ -598,7 +734,7 @@ func TestWarningAlertFlood(t *testing.T) { } func TestCloneFuncFields(t *testing.T) { - const expectedCount = 5 + const expectedCount = 6 called := 0 c1 := Config{ @@ -622,6 +758,10 @@ func TestCloneFuncFields(t *testing.T) { called |= 1 << 4 return nil }, + VerifyConnection: func(ConnectionState) error { + called |= 1 << 5 + return nil + }, } c2 := c1.Clone() @@ -631,6 +771,7 @@ func TestCloneFuncFields(t *testing.T) { c2.GetClientCertificate(nil) c2.GetConfigForClient(nil) c2.VerifyPeerCertificate(nil, nil) + c2.VerifyConnection(ConnectionState{}) if called != (1< -#include - -#include -#include - -static Boolean isSSLPolicy(SecPolicyRef policyRef) { - if (!policyRef) { - return false; - } - CFDictionaryRef properties = SecPolicyCopyProperties(policyRef); - if (properties == NULL) { - return false; - } - Boolean isSSL = false; - CFTypeRef value = NULL; - if (CFDictionaryGetValueIfPresent(properties, kSecPolicyOid, (const void **)&value)) { - isSSL = CFEqual(value, kSecPolicyAppleSSL); - } - CFRelease(properties); - return isSSL; -} - -// sslTrustSettingsResult obtains the final kSecTrustSettingsResult value -// for a certificate in the user or admin domain, combining usage constraints -// for the SSL SecTrustSettingsPolicy, ignoring SecTrustSettingsKeyUsage and -// kSecTrustSettingsAllowedError. -// https://developer.apple.com/documentation/security/1400261-sectrustsettingscopytrustsetting -static SInt32 sslTrustSettingsResult(SecCertificateRef cert) { - CFArrayRef trustSettings = NULL; - OSStatus err = SecTrustSettingsCopyTrustSettings(cert, kSecTrustSettingsDomainUser, &trustSettings); - - // According to Apple's SecTrustServer.c, "user trust settings overrule admin trust settings", - // but the rules of the override are unclear. Let's assume admin trust settings are applicable - // if and only if user trust settings fail to load or are NULL. - if (err != errSecSuccess || trustSettings == NULL) { - if (trustSettings != NULL) CFRelease(trustSettings); - err = SecTrustSettingsCopyTrustSettings(cert, kSecTrustSettingsDomainAdmin, &trustSettings); - } - - // > no trust settings [...] means "this certificate must be verified to a known trusted certificate” - // (Should this cause a fallback from user to admin domain? It's unclear.) - if (err != errSecSuccess || trustSettings == NULL) { - if (trustSettings != NULL) CFRelease(trustSettings); - return kSecTrustSettingsResultUnspecified; - } - - // > An empty trust settings array means "always trust this certificate” with an - // > overall trust setting for the certificate of kSecTrustSettingsResultTrustRoot. - if (CFArrayGetCount(trustSettings) == 0) { - CFRelease(trustSettings); - return kSecTrustSettingsResultTrustRoot; - } - - // kSecTrustSettingsResult is defined as CFSTR("kSecTrustSettingsResult"), - // but the Go linker's internal linking mode can't handle CFSTR relocations. - // Create our own dynamic string instead and release it below. - CFStringRef _kSecTrustSettingsResult = CFStringCreateWithCString( - NULL, "kSecTrustSettingsResult", kCFStringEncodingUTF8); - CFStringRef _kSecTrustSettingsPolicy = CFStringCreateWithCString( - NULL, "kSecTrustSettingsPolicy", kCFStringEncodingUTF8); - CFStringRef _kSecTrustSettingsPolicyString = CFStringCreateWithCString( - NULL, "kSecTrustSettingsPolicyString", kCFStringEncodingUTF8); - - CFIndex m; SInt32 result = 0; - for (m = 0; m < CFArrayGetCount(trustSettings); m++) { - CFDictionaryRef tSetting = (CFDictionaryRef)CFArrayGetValueAtIndex(trustSettings, m); - - // First, check if this trust setting is constrained to a non-SSL policy. - SecPolicyRef policyRef; - if (CFDictionaryGetValueIfPresent(tSetting, _kSecTrustSettingsPolicy, (const void**)&policyRef)) { - if (!isSSLPolicy(policyRef)) { - continue; - } - } - - if (CFDictionaryContainsKey(tSetting, _kSecTrustSettingsPolicyString)) { - // Restricted to a hostname, not a root. - continue; - } - - CFNumberRef cfNum; - if (CFDictionaryGetValueIfPresent(tSetting, _kSecTrustSettingsResult, (const void**)&cfNum)) { - CFNumberGetValue(cfNum, kCFNumberSInt32Type, &result); - } else { - // > If this key is not present, a default value of - // > kSecTrustSettingsResultTrustRoot is assumed. - result = kSecTrustSettingsResultTrustRoot; - } - - // If multiple dictionaries match, we are supposed to "OR" them, - // the semantics of which are not clear. Since TrustRoot and TrustAsRoot - // are mutually exclusive, Deny should probably override, and Invalid and - // Unspecified be overridden, approximate this by stopping at the first - // TrustRoot, TrustAsRoot or Deny. - if (result == kSecTrustSettingsResultTrustRoot) { - break; - } else if (result == kSecTrustSettingsResultTrustAsRoot) { - break; - } else if (result == kSecTrustSettingsResultDeny) { - break; - } - } - - // If trust settings are present, but none of them match the policy... - // the docs don't tell us what to do. - // - // "Trust settings for a given use apply if any of the dictionaries in the - // certificate’s trust settings array satisfies the specified use." suggests - // that it's as if there were no trust settings at all, so we should probably - // fallback to the admin trust settings. TODO. - if (result == 0) { - result = kSecTrustSettingsResultUnspecified; - } - - CFRelease(_kSecTrustSettingsPolicy); - CFRelease(_kSecTrustSettingsPolicyString); - CFRelease(_kSecTrustSettingsResult); - CFRelease(trustSettings); - - return result; -} - -// isRootCertificate reports whether Subject and Issuer match. -static Boolean isRootCertificate(SecCertificateRef cert, CFErrorRef *errRef) { - CFDataRef subjectName = SecCertificateCopyNormalizedSubjectContent(cert, errRef); - if (*errRef != NULL) { - return false; - } - CFDataRef issuerName = SecCertificateCopyNormalizedIssuerContent(cert, errRef); - if (*errRef != NULL) { - CFRelease(subjectName); - return false; - } - Boolean equal = CFEqual(subjectName, issuerName); - CFRelease(subjectName); - CFRelease(issuerName); - return equal; -} - -// CopyPEMRoots fetches the system's list of trusted X.509 root certificates -// for the kSecTrustSettingsPolicy SSL. -// -// On success it returns 0 and fills pemRoots with a CFDataRef that contains the extracted root -// certificates of the system. On failure, the function returns -1. -// Additionally, it fills untrustedPemRoots with certs that must be removed from pemRoots. -// -// Note: The CFDataRef returned in pemRoots and untrustedPemRoots must -// be released (using CFRelease) after we've consumed its content. -static int CopyPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots, bool debugDarwinRoots) { - int i; - - if (debugDarwinRoots) { - fprintf(stderr, "crypto/x509: kSecTrustSettingsResultInvalid = %d\n", kSecTrustSettingsResultInvalid); - fprintf(stderr, "crypto/x509: kSecTrustSettingsResultTrustRoot = %d\n", kSecTrustSettingsResultTrustRoot); - fprintf(stderr, "crypto/x509: kSecTrustSettingsResultTrustAsRoot = %d\n", kSecTrustSettingsResultTrustAsRoot); - fprintf(stderr, "crypto/x509: kSecTrustSettingsResultDeny = %d\n", kSecTrustSettingsResultDeny); - fprintf(stderr, "crypto/x509: kSecTrustSettingsResultUnspecified = %d\n", kSecTrustSettingsResultUnspecified); - } - - // Get certificates from all domains, not just System, this lets - // the user add CAs to their "login" keychain, and Admins to add - // to the "System" keychain - SecTrustSettingsDomain domains[] = { kSecTrustSettingsDomainSystem, - kSecTrustSettingsDomainAdmin, kSecTrustSettingsDomainUser }; - - int numDomains = sizeof(domains)/sizeof(SecTrustSettingsDomain); - if (pemRoots == NULL || untrustedPemRoots == NULL) { - return -1; - } - - CFMutableDataRef combinedData = CFDataCreateMutable(kCFAllocatorDefault, 0); - CFMutableDataRef combinedUntrustedData = CFDataCreateMutable(kCFAllocatorDefault, 0); - for (i = 0; i < numDomains; i++) { - int j; - CFArrayRef certs = NULL; - OSStatus err = SecTrustSettingsCopyCertificates(domains[i], &certs); - if (err != noErr) { - continue; - } - - CFIndex numCerts = CFArrayGetCount(certs); - for (j = 0; j < numCerts; j++) { - SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs, j); - if (cert == NULL) { - continue; - } - - SInt32 result; - if (domains[i] == kSecTrustSettingsDomainSystem) { - // Certs found in the system domain are always trusted. If the user - // configures "Never Trust" on such a cert, it will also be found in the - // admin or user domain, causing it to be added to untrustedPemRoots. The - // Go code will then clean this up. - result = kSecTrustSettingsResultTrustRoot; - } else { - result = sslTrustSettingsResult(cert); - if (debugDarwinRoots) { - CFErrorRef errRef = NULL; - CFStringRef summary = SecCertificateCopyShortDescription(NULL, cert, &errRef); - if (errRef != NULL) { - fprintf(stderr, "crypto/x509: SecCertificateCopyShortDescription failed\n"); - CFRelease(errRef); - continue; - } - - CFIndex length = CFStringGetLength(summary); - CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1; - char *buffer = malloc(maxSize); - if (CFStringGetCString(summary, buffer, maxSize, kCFStringEncodingUTF8)) { - fprintf(stderr, "crypto/x509: %s returned %d\n", buffer, (int)result); - } - free(buffer); - CFRelease(summary); - } - } - - CFMutableDataRef appendTo; - // > Note the distinction between the results kSecTrustSettingsResultTrustRoot - // > and kSecTrustSettingsResultTrustAsRoot: The former can only be applied to - // > root (self-signed) certificates; the latter can only be applied to - // > non-root certificates. - if (result == kSecTrustSettingsResultTrustRoot) { - CFErrorRef errRef = NULL; - if (!isRootCertificate(cert, &errRef) || errRef != NULL) { - if (errRef != NULL) CFRelease(errRef); - continue; - } - - appendTo = combinedData; - } else if (result == kSecTrustSettingsResultTrustAsRoot) { - CFErrorRef errRef = NULL; - if (isRootCertificate(cert, &errRef) || errRef != NULL) { - if (errRef != NULL) CFRelease(errRef); - continue; - } - - appendTo = combinedData; - } else if (result == kSecTrustSettingsResultDeny) { - appendTo = combinedUntrustedData; - } else if (result == kSecTrustSettingsResultUnspecified) { - // Certificates with unspecified trust should probably be added to a pool of - // intermediates for chain building, or checked for transitive trust and - // added to the root pool (which is an imprecise approximation because it - // cuts chains short) but we don't support either at the moment. TODO. - continue; - } else { - continue; - } - - CFDataRef data = NULL; - err = SecItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data); - if (err != noErr) { - continue; - } - if (data != NULL) { - CFDataAppendBytes(appendTo, CFDataGetBytePtr(data), CFDataGetLength(data)); - CFRelease(data); - } - } - CFRelease(certs); - } - *pemRoots = combinedData; - *untrustedPemRoots = combinedUntrustedData; - return 0; -} -*/ -import "C" -import ( - "errors" - "unsafe" -) - -func loadSystemRoots() (*CertPool, error) { - var data, untrustedData C.CFDataRef - err := C.CopyPEMRoots(&data, &untrustedData, C.bool(debugDarwinRoots)) - if err == -1 { - return nil, errors.New("crypto/x509: failed to load darwin system roots with cgo") - } - defer C.CFRelease(C.CFTypeRef(data)) - defer C.CFRelease(C.CFTypeRef(untrustedData)) - - buf := C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(data)), C.int(C.CFDataGetLength(data))) - roots := NewCertPool() - roots.AppendCertsFromPEM(buf) - - if C.CFDataGetLength(untrustedData) == 0 { - return roots, nil - } - - buf = C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(untrustedData)), C.int(C.CFDataGetLength(untrustedData))) - untrustedRoots := NewCertPool() - untrustedRoots.AppendCertsFromPEM(buf) - - trustedRoots := NewCertPool() - for _, c := range roots.certs { - if !untrustedRoots.contains(c) { - trustedRoots.AddCert(c) - } - } - return trustedRoots, nil -} diff --git a/libgo/go/crypto/x509/root_cgo_darwin_amd64.go b/libgo/go/crypto/x509/root_cgo_darwin_amd64.go new file mode 100644 index 00000000000..15c72cc0c83 --- /dev/null +++ b/libgo/go/crypto/x509/root_cgo_darwin_amd64.go @@ -0,0 +1,322 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !ios + +package x509 + +// This cgo implementation exists only to support side-by-side testing by +// TestSystemRoots. It can be removed once we are confident in the no-cgo +// implementation. + +/* +#cgo CFLAGS: -mmacosx-version-min=10.11 +#cgo LDFLAGS: -framework CoreFoundation -framework Security + +#include +#include + +#include +#include + +static Boolean isSSLPolicy(SecPolicyRef policyRef) { + if (!policyRef) { + return false; + } + CFDictionaryRef properties = SecPolicyCopyProperties(policyRef); + if (properties == NULL) { + return false; + } + Boolean isSSL = false; + CFTypeRef value = NULL; + if (CFDictionaryGetValueIfPresent(properties, kSecPolicyOid, (const void **)&value)) { + isSSL = CFEqual(value, kSecPolicyAppleSSL); + } + CFRelease(properties); + return isSSL; +} + +// sslTrustSettingsResult obtains the final kSecTrustSettingsResult value +// for a certificate in the user or admin domain, combining usage constraints +// for the SSL SecTrustSettingsPolicy, ignoring SecTrustSettingsKeyUsage and +// kSecTrustSettingsAllowedError. +// https://developer.apple.com/documentation/security/1400261-sectrustsettingscopytrustsetting +static SInt32 sslTrustSettingsResult(SecCertificateRef cert) { + CFArrayRef trustSettings = NULL; + OSStatus err = SecTrustSettingsCopyTrustSettings(cert, kSecTrustSettingsDomainUser, &trustSettings); + + // According to Apple's SecTrustServer.c, "user trust settings overrule admin trust settings", + // but the rules of the override are unclear. Let's assume admin trust settings are applicable + // if and only if user trust settings fail to load or are NULL. + if (err != errSecSuccess || trustSettings == NULL) { + if (trustSettings != NULL) CFRelease(trustSettings); + err = SecTrustSettingsCopyTrustSettings(cert, kSecTrustSettingsDomainAdmin, &trustSettings); + } + + // > no trust settings [...] means "this certificate must be verified to a known trusted certificate” + // (Should this cause a fallback from user to admin domain? It's unclear.) + if (err != errSecSuccess || trustSettings == NULL) { + if (trustSettings != NULL) CFRelease(trustSettings); + return kSecTrustSettingsResultUnspecified; + } + + // > An empty trust settings array means "always trust this certificate” with an + // > overall trust setting for the certificate of kSecTrustSettingsResultTrustRoot. + if (CFArrayGetCount(trustSettings) == 0) { + CFRelease(trustSettings); + return kSecTrustSettingsResultTrustRoot; + } + + // kSecTrustSettingsResult is defined as CFSTR("kSecTrustSettingsResult"), + // but the Go linker's internal linking mode can't handle CFSTR relocations. + // Create our own dynamic string instead and release it below. + CFStringRef _kSecTrustSettingsResult = CFStringCreateWithCString( + NULL, "kSecTrustSettingsResult", kCFStringEncodingUTF8); + CFStringRef _kSecTrustSettingsPolicy = CFStringCreateWithCString( + NULL, "kSecTrustSettingsPolicy", kCFStringEncodingUTF8); + CFStringRef _kSecTrustSettingsPolicyString = CFStringCreateWithCString( + NULL, "kSecTrustSettingsPolicyString", kCFStringEncodingUTF8); + + CFIndex m; SInt32 result = 0; + for (m = 0; m < CFArrayGetCount(trustSettings); m++) { + CFDictionaryRef tSetting = (CFDictionaryRef)CFArrayGetValueAtIndex(trustSettings, m); + + // First, check if this trust setting is constrained to a non-SSL policy. + SecPolicyRef policyRef; + if (CFDictionaryGetValueIfPresent(tSetting, _kSecTrustSettingsPolicy, (const void**)&policyRef)) { + if (!isSSLPolicy(policyRef)) { + continue; + } + } + + if (CFDictionaryContainsKey(tSetting, _kSecTrustSettingsPolicyString)) { + // Restricted to a hostname, not a root. + continue; + } + + CFNumberRef cfNum; + if (CFDictionaryGetValueIfPresent(tSetting, _kSecTrustSettingsResult, (const void**)&cfNum)) { + CFNumberGetValue(cfNum, kCFNumberSInt32Type, &result); + } else { + // > If this key is not present, a default value of + // > kSecTrustSettingsResultTrustRoot is assumed. + result = kSecTrustSettingsResultTrustRoot; + } + + // If multiple dictionaries match, we are supposed to "OR" them, + // the semantics of which are not clear. Since TrustRoot and TrustAsRoot + // are mutually exclusive, Deny should probably override, and Invalid and + // Unspecified be overridden, approximate this by stopping at the first + // TrustRoot, TrustAsRoot or Deny. + if (result == kSecTrustSettingsResultTrustRoot) { + break; + } else if (result == kSecTrustSettingsResultTrustAsRoot) { + break; + } else if (result == kSecTrustSettingsResultDeny) { + break; + } + } + + // If trust settings are present, but none of them match the policy... + // the docs don't tell us what to do. + // + // "Trust settings for a given use apply if any of the dictionaries in the + // certificate’s trust settings array satisfies the specified use." suggests + // that it's as if there were no trust settings at all, so we should probably + // fallback to the admin trust settings. TODO. + if (result == 0) { + result = kSecTrustSettingsResultUnspecified; + } + + CFRelease(_kSecTrustSettingsPolicy); + CFRelease(_kSecTrustSettingsPolicyString); + CFRelease(_kSecTrustSettingsResult); + CFRelease(trustSettings); + + return result; +} + +// isRootCertificate reports whether Subject and Issuer match. +static Boolean isRootCertificate(SecCertificateRef cert, CFErrorRef *errRef) { + CFDataRef subjectName = SecCertificateCopyNormalizedSubjectContent(cert, errRef); + if (*errRef != NULL) { + return false; + } + CFDataRef issuerName = SecCertificateCopyNormalizedIssuerContent(cert, errRef); + if (*errRef != NULL) { + CFRelease(subjectName); + return false; + } + Boolean equal = CFEqual(subjectName, issuerName); + CFRelease(subjectName); + CFRelease(issuerName); + return equal; +} + +// CopyPEMRoots fetches the system's list of trusted X.509 root certificates +// for the kSecTrustSettingsPolicy SSL. +// +// On success it returns 0 and fills pemRoots with a CFDataRef that contains the extracted root +// certificates of the system. On failure, the function returns -1. +// Additionally, it fills untrustedPemRoots with certs that must be removed from pemRoots. +// +// Note: The CFDataRef returned in pemRoots and untrustedPemRoots must +// be released (using CFRelease) after we've consumed its content. +static int CopyPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots, bool debugDarwinRoots) { + int i; + + if (debugDarwinRoots) { + fprintf(stderr, "crypto/x509: kSecTrustSettingsResultInvalid = %d\n", kSecTrustSettingsResultInvalid); + fprintf(stderr, "crypto/x509: kSecTrustSettingsResultTrustRoot = %d\n", kSecTrustSettingsResultTrustRoot); + fprintf(stderr, "crypto/x509: kSecTrustSettingsResultTrustAsRoot = %d\n", kSecTrustSettingsResultTrustAsRoot); + fprintf(stderr, "crypto/x509: kSecTrustSettingsResultDeny = %d\n", kSecTrustSettingsResultDeny); + fprintf(stderr, "crypto/x509: kSecTrustSettingsResultUnspecified = %d\n", kSecTrustSettingsResultUnspecified); + } + + // Get certificates from all domains, not just System, this lets + // the user add CAs to their "login" keychain, and Admins to add + // to the "System" keychain + SecTrustSettingsDomain domains[] = { kSecTrustSettingsDomainSystem, + kSecTrustSettingsDomainAdmin, kSecTrustSettingsDomainUser }; + + int numDomains = sizeof(domains)/sizeof(SecTrustSettingsDomain); + if (pemRoots == NULL || untrustedPemRoots == NULL) { + return -1; + } + + CFMutableDataRef combinedData = CFDataCreateMutable(kCFAllocatorDefault, 0); + CFMutableDataRef combinedUntrustedData = CFDataCreateMutable(kCFAllocatorDefault, 0); + for (i = 0; i < numDomains; i++) { + int j; + CFArrayRef certs = NULL; + OSStatus err = SecTrustSettingsCopyCertificates(domains[i], &certs); + if (err != noErr) { + continue; + } + + CFIndex numCerts = CFArrayGetCount(certs); + for (j = 0; j < numCerts; j++) { + SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs, j); + if (cert == NULL) { + continue; + } + + SInt32 result; + if (domains[i] == kSecTrustSettingsDomainSystem) { + // Certs found in the system domain are always trusted. If the user + // configures "Never Trust" on such a cert, it will also be found in the + // admin or user domain, causing it to be added to untrustedPemRoots. The + // Go code will then clean this up. + result = kSecTrustSettingsResultTrustRoot; + } else { + result = sslTrustSettingsResult(cert); + if (debugDarwinRoots) { + CFErrorRef errRef = NULL; + CFStringRef summary = SecCertificateCopyShortDescription(NULL, cert, &errRef); + if (errRef != NULL) { + fprintf(stderr, "crypto/x509: SecCertificateCopyShortDescription failed\n"); + CFRelease(errRef); + continue; + } + + CFIndex length = CFStringGetLength(summary); + CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1; + char *buffer = malloc(maxSize); + if (CFStringGetCString(summary, buffer, maxSize, kCFStringEncodingUTF8)) { + fprintf(stderr, "crypto/x509: %s returned %d\n", buffer, (int)result); + } + free(buffer); + CFRelease(summary); + } + } + + CFMutableDataRef appendTo; + // > Note the distinction between the results kSecTrustSettingsResultTrustRoot + // > and kSecTrustSettingsResultTrustAsRoot: The former can only be applied to + // > root (self-signed) certificates; the latter can only be applied to + // > non-root certificates. + if (result == kSecTrustSettingsResultTrustRoot) { + CFErrorRef errRef = NULL; + if (!isRootCertificate(cert, &errRef) || errRef != NULL) { + if (errRef != NULL) CFRelease(errRef); + continue; + } + + appendTo = combinedData; + } else if (result == kSecTrustSettingsResultTrustAsRoot) { + CFErrorRef errRef = NULL; + if (isRootCertificate(cert, &errRef) || errRef != NULL) { + if (errRef != NULL) CFRelease(errRef); + continue; + } + + appendTo = combinedData; + } else if (result == kSecTrustSettingsResultDeny) { + appendTo = combinedUntrustedData; + } else if (result == kSecTrustSettingsResultUnspecified) { + // Certificates with unspecified trust should probably be added to a pool of + // intermediates for chain building, or checked for transitive trust and + // added to the root pool (which is an imprecise approximation because it + // cuts chains short) but we don't support either at the moment. TODO. + continue; + } else { + continue; + } + + CFDataRef data = NULL; + err = SecItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data); + if (err != noErr) { + continue; + } + if (data != NULL) { + CFDataAppendBytes(appendTo, CFDataGetBytePtr(data), CFDataGetLength(data)); + CFRelease(data); + } + } + CFRelease(certs); + } + *pemRoots = combinedData; + *untrustedPemRoots = combinedUntrustedData; + return 0; +} +*/ +import "C" +import ( + "errors" + "unsafe" +) + +func init() { + loadSystemRootsWithCgo = _loadSystemRootsWithCgo +} + +func _loadSystemRootsWithCgo() (*CertPool, error) { + var data, untrustedData C.CFDataRef + err := C.CopyPEMRoots(&data, &untrustedData, C.bool(debugDarwinRoots)) + if err == -1 { + return nil, errors.New("crypto/x509: failed to load darwin system roots with cgo") + } + defer C.CFRelease(C.CFTypeRef(data)) + defer C.CFRelease(C.CFTypeRef(untrustedData)) + + buf := C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(data)), C.int(C.CFDataGetLength(data))) + roots := NewCertPool() + roots.AppendCertsFromPEM(buf) + + if C.CFDataGetLength(untrustedData) == 0 { + return roots, nil + } + + buf = C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(untrustedData)), C.int(C.CFDataGetLength(untrustedData))) + untrustedRoots := NewCertPool() + untrustedRoots.AppendCertsFromPEM(buf) + + trustedRoots := NewCertPool() + for _, c := range roots.certs { + if !untrustedRoots.contains(c) { + trustedRoots.AddCert(c) + } + } + return trustedRoots, nil +} diff --git a/libgo/go/crypto/x509/root_darwin.go b/libgo/go/crypto/x509/root_darwin.go deleted file mode 100644 index 2f6a8b8d607..00000000000 --- a/libgo/go/crypto/x509/root_darwin.go +++ /dev/null @@ -1,288 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:generate go run root_darwin_arm_gen.go -output root_darwin_armx.go - -package x509 - -import ( - "bufio" - "bytes" - "crypto/sha1" - "encoding/pem" - "fmt" - "io" - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "strings" - "sync" -) - -var debugDarwinRoots = strings.Contains(os.Getenv("GODEBUG"), "x509roots=1") - -func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) { - return nil, nil -} - -// This code is only used when compiling without cgo. -// It is here, instead of root_nocgo_darwin.go, so that tests can check it -// even if the tests are run with cgo enabled. -// The linker will not include these unused functions in binaries built with cgo enabled. - -// execSecurityRoots finds the macOS list of trusted root certificates -// using only command-line tools. This is our fallback path when cgo isn't available. -// -// The strategy is as follows: -// -// 1. Run "security trust-settings-export" and "security -// trust-settings-export -d" to discover the set of certs with some -// user-tweaked trust policy. We're too lazy to parse the XML -// (Issue 26830) to understand what the trust -// policy actually is. We just learn that there is _some_ policy. -// -// 2. Run "security find-certificate" to dump the list of system root -// CAs in PEM format. -// -// 3. For each dumped cert, conditionally verify it with "security -// verify-cert" if that cert was in the set discovered in Step 1. -// Without the Step 1 optimization, running "security verify-cert" -// 150-200 times takes 3.5 seconds. With the optimization, the -// whole process takes about 180 milliseconds with 1 untrusted root -// CA. (Compared to 110ms in the cgo path) -func execSecurityRoots() (*CertPool, error) { - hasPolicy, err := getCertsWithTrustPolicy() - if err != nil { - return nil, err - } - if debugDarwinRoots { - fmt.Fprintf(os.Stderr, "crypto/x509: %d certs have a trust policy\n", len(hasPolicy)) - } - - keychains := []string{"/Library/Keychains/System.keychain"} - - // Note that this results in trusting roots from $HOME/... (the environment - // variable), which might not be expected. - home, err := os.UserHomeDir() - if err != nil { - if debugDarwinRoots { - fmt.Fprintf(os.Stderr, "crypto/x509: can't get user home directory: %v\n", err) - } - } else { - keychains = append(keychains, - filepath.Join(home, "/Library/Keychains/login.keychain"), - - // Fresh installs of Sierra use a slightly different path for the login keychain - filepath.Join(home, "/Library/Keychains/login.keychain-db"), - ) - } - - type rootCandidate struct { - c *Certificate - system bool - } - - var ( - mu sync.Mutex - roots = NewCertPool() - numVerified int // number of execs of 'security verify-cert', for debug stats - wg sync.WaitGroup - verifyCh = make(chan rootCandidate) - ) - - // Using 4 goroutines to pipe into verify-cert seems to be - // about the best we can do. The verify-cert binary seems to - // just RPC to another server with coarse locking anyway, so - // running 16 at a time for instance doesn't help at all. Due - // to the "if hasPolicy" check below, though, we will rarely - // (or never) call verify-cert on stock macOS systems, though. - // The hope is that we only call verify-cert when the user has - // tweaked their trust policy. These 4 goroutines are only - // defensive in the pathological case of many trust edits. - for i := 0; i < 4; i++ { - wg.Add(1) - go func() { - defer wg.Done() - for cert := range verifyCh { - sha1CapHex := fmt.Sprintf("%X", sha1.Sum(cert.c.Raw)) - - var valid bool - verifyChecks := 0 - if hasPolicy[sha1CapHex] { - verifyChecks++ - valid = verifyCertWithSystem(cert.c) - } else { - // Certificates not in SystemRootCertificates without user - // or admin trust settings are not trusted. - valid = cert.system - } - - mu.Lock() - numVerified += verifyChecks - if valid { - roots.AddCert(cert.c) - } - mu.Unlock() - } - }() - } - err = forEachCertInKeychains(keychains, func(cert *Certificate) { - verifyCh <- rootCandidate{c: cert, system: false} - }) - if err != nil { - close(verifyCh) - return nil, err - } - err = forEachCertInKeychains([]string{ - "/System/Library/Keychains/SystemRootCertificates.keychain", - }, func(cert *Certificate) { - verifyCh <- rootCandidate{c: cert, system: true} - }) - if err != nil { - close(verifyCh) - return nil, err - } - close(verifyCh) - wg.Wait() - - if debugDarwinRoots { - fmt.Fprintf(os.Stderr, "crypto/x509: ran security verify-cert %d times\n", numVerified) - } - - return roots, nil -} - -func forEachCertInKeychains(paths []string, f func(*Certificate)) error { - args := append([]string{"find-certificate", "-a", "-p"}, paths...) - cmd := exec.Command("/usr/bin/security", args...) - data, err := cmd.Output() - if err != nil { - return err - } - for len(data) > 0 { - var block *pem.Block - block, data = pem.Decode(data) - if block == nil { - break - } - if block.Type != "CERTIFICATE" || len(block.Headers) != 0 { - continue - } - cert, err := ParseCertificate(block.Bytes) - if err != nil { - continue - } - f(cert) - } - return nil -} - -func verifyCertWithSystem(cert *Certificate) bool { - data := pem.EncodeToMemory(&pem.Block{ - Type: "CERTIFICATE", Bytes: cert.Raw, - }) - - f, err := ioutil.TempFile("", "cert") - if err != nil { - fmt.Fprintf(os.Stderr, "can't create temporary file for cert: %v", err) - return false - } - defer os.Remove(f.Name()) - if _, err := f.Write(data); err != nil { - fmt.Fprintf(os.Stderr, "can't write temporary file for cert: %v", err) - return false - } - if err := f.Close(); err != nil { - fmt.Fprintf(os.Stderr, "can't write temporary file for cert: %v", err) - return false - } - cmd := exec.Command("/usr/bin/security", "verify-cert", "-p", "ssl", "-c", f.Name(), "-l", "-L") - var stderr bytes.Buffer - if debugDarwinRoots { - cmd.Stderr = &stderr - } - if err := cmd.Run(); err != nil { - if debugDarwinRoots { - fmt.Fprintf(os.Stderr, "crypto/x509: verify-cert rejected %s: %q\n", cert.Subject, bytes.TrimSpace(stderr.Bytes())) - } - return false - } - if debugDarwinRoots { - fmt.Fprintf(os.Stderr, "crypto/x509: verify-cert approved %s\n", cert.Subject) - } - return true -} - -// getCertsWithTrustPolicy returns the set of certs that have a -// possibly-altered trust policy. The keys of the map are capitalized -// sha1 hex of the raw cert. -// They are the certs that should be checked against `security -// verify-cert` to see whether the user altered the default trust -// settings. This code is only used for cgo-disabled builds. -func getCertsWithTrustPolicy() (map[string]bool, error) { - set := map[string]bool{} - td, err := ioutil.TempDir("", "x509trustpolicy") - if err != nil { - return nil, err - } - defer os.RemoveAll(td) - run := func(file string, args ...string) error { - file = filepath.Join(td, file) - args = append(args, file) - cmd := exec.Command("/usr/bin/security", args...) - var stderr bytes.Buffer - cmd.Stderr = &stderr - if err := cmd.Run(); err != nil { - // If there are no trust settings, the - // `security trust-settings-export` command - // fails with: - // exit status 1, SecTrustSettingsCreateExternalRepresentation: No Trust Settings were found. - // Rather than match on English substrings that are probably - // localized on macOS, just interpret any failure to mean that - // there are no trust settings. - if debugDarwinRoots { - fmt.Fprintf(os.Stderr, "crypto/x509: exec %q: %v, %s\n", cmd.Args, err, stderr.Bytes()) - } - return nil - } - - f, err := os.Open(file) - if err != nil { - return err - } - defer f.Close() - - // Gather all the runs of 40 capitalized hex characters. - br := bufio.NewReader(f) - var hexBuf bytes.Buffer - for { - b, err := br.ReadByte() - isHex := ('A' <= b && b <= 'F') || ('0' <= b && b <= '9') - if isHex { - hexBuf.WriteByte(b) - } else { - if hexBuf.Len() == 40 { - set[hexBuf.String()] = true - } - hexBuf.Reset() - } - if err == io.EOF { - break - } - if err != nil { - return err - } - } - - return nil - } - if err := run("user", "trust-settings-export"); err != nil { - return nil, fmt.Errorf("dump-trust-settings (user): %v", err) - } - if err := run("admin", "trust-settings-export", "-d"); err != nil { - return nil, fmt.Errorf("dump-trust-settings (admin): %v", err) - } - return set, nil -} diff --git a/libgo/go/crypto/x509/root_darwin_amd64.go b/libgo/go/crypto/x509/root_darwin_amd64.go new file mode 100644 index 00000000000..ce88de025ec --- /dev/null +++ b/libgo/go/crypto/x509/root_darwin_amd64.go @@ -0,0 +1,243 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !ios + +package x509 + +import ( + "bytes" + macOS "crypto/x509/internal/macos" + "fmt" + "os" + "strings" +) + +var debugDarwinRoots = strings.Contains(os.Getenv("GODEBUG"), "x509roots=1") + +func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) { + return nil, nil +} + +// loadSystemRootsWithCgo is set in root_cgo_darwin_amd64.go when cgo is +// available, and is only used for testing. +var loadSystemRootsWithCgo func() (*CertPool, error) + +func loadSystemRoots() (*CertPool, error) { + var trustedRoots []*Certificate + untrustedRoots := make(map[string]bool) + + // macOS has three trust domains: one for CAs added by users to their + // "login" keychain, one for CAs added by Admins to the "System" keychain, + // and one for the CAs that ship with the OS. + for _, domain := range []macOS.SecTrustSettingsDomain{ + macOS.SecTrustSettingsDomainUser, + macOS.SecTrustSettingsDomainAdmin, + macOS.SecTrustSettingsDomainSystem, + } { + certs, err := macOS.SecTrustSettingsCopyCertificates(domain) + if err == macOS.ErrNoTrustSettings { + continue + } else if err != nil { + return nil, err + } + defer macOS.CFRelease(certs) + + for i := 0; i < macOS.CFArrayGetCount(certs); i++ { + c := macOS.CFArrayGetValueAtIndex(certs, i) + cert, err := exportCertificate(c) + if err != nil { + if debugDarwinRoots { + fmt.Fprintf(os.Stderr, "crypto/x509: domain %d, certificate #%d: %v\n", domain, i, err) + } + continue + } + + var result macOS.SecTrustSettingsResult + if domain == macOS.SecTrustSettingsDomainSystem { + // Certs found in the system domain are always trusted. If the user + // configures "Never Trust" on such a cert, it will also be found in the + // admin or user domain, causing it to be added to untrustedRoots. + result = macOS.SecTrustSettingsResultTrustRoot + } else { + result, err = sslTrustSettingsResult(c) + if err != nil { + if debugDarwinRoots { + fmt.Fprintf(os.Stderr, "crypto/x509: trust settings for %v: %v\n", cert.Subject, err) + } + continue + } + if debugDarwinRoots { + fmt.Fprintf(os.Stderr, "crypto/x509: trust settings for %v: %d\n", cert.Subject, result) + } + } + + switch result { + // "Note the distinction between the results kSecTrustSettingsResultTrustRoot + // and kSecTrustSettingsResultTrustAsRoot: The former can only be applied to + // root (self-signed) certificates; the latter can only be applied to + // non-root certificates." + case macOS.SecTrustSettingsResultTrustRoot: + if isRootCertificate(cert) { + trustedRoots = append(trustedRoots, cert) + } + case macOS.SecTrustSettingsResultTrustAsRoot: + if !isRootCertificate(cert) { + trustedRoots = append(trustedRoots, cert) + } + + case macOS.SecTrustSettingsResultDeny: + // Add this certificate to untrustedRoots, which are subtracted + // from trustedRoots, so that we don't have to evaluate policies + // for every root in the system domain, but still apply user and + // admin policies that override system roots. + untrustedRoots[string(cert.Raw)] = true + + case macOS.SecTrustSettingsResultUnspecified: + // Certificates with unspecified trust should be added to a pool + // of intermediates for chain building, but we don't support it + // at the moment. This is Issue 35631. + + default: + if debugDarwinRoots { + fmt.Fprintf(os.Stderr, "crypto/x509: unknown trust setting for %v: %d\n", cert.Subject, result) + } + } + } + } + + pool := NewCertPool() + for _, cert := range trustedRoots { + if !untrustedRoots[string(cert.Raw)] { + pool.AddCert(cert) + } + } + return pool, nil +} + +// exportCertificate returns a *Certificate for a SecCertificateRef. +func exportCertificate(cert macOS.CFRef) (*Certificate, error) { + data, err := macOS.SecItemExport(cert) + if err != nil { + return nil, err + } + defer macOS.CFRelease(data) + der := macOS.CFDataToSlice(data) + + return ParseCertificate(der) +} + +// isRootCertificate reports whether Subject and Issuer match. +func isRootCertificate(cert *Certificate) bool { + return bytes.Equal(cert.RawSubject, cert.RawIssuer) +} + +// sslTrustSettingsResult obtains the final kSecTrustSettingsResult value for a +// certificate in the user or admin domain, combining usage constraints for the +// SSL SecTrustSettingsPolicy, +// +// It ignores SecTrustSettingsKeyUsage and kSecTrustSettingsAllowedError, and +// doesn't support kSecTrustSettingsDefaultRootCertSetting. +// +// https://developer.apple.com/documentation/security/1400261-sectrustsettingscopytrustsetting +func sslTrustSettingsResult(cert macOS.CFRef) (macOS.SecTrustSettingsResult, error) { + // In Apple's implementation user trust settings override admin trust settings + // (which themselves override system trust settings). If SecTrustSettingsCopyTrustSettings + // fails, or returns a NULL trust settings, when looking for the user trust + // settings then fallback to checking the admin trust settings. + // + // See Security-59306.41.2/trust/headers/SecTrustSettings.h for a description of + // the trust settings overrides, and SecLegacyAnchorSourceCopyUsageConstraints in + // Security-59306.41.2/trust/trustd/SecCertificateSource.c for a concrete example + // of how Apple applies the override in the case of NULL trust settings, or non + // success errors. + trustSettings, err := macOS.SecTrustSettingsCopyTrustSettings(cert, macOS.SecTrustSettingsDomainUser) + if err != nil || trustSettings == 0 { + if debugDarwinRoots && err != macOS.ErrNoTrustSettings { + fmt.Fprintf(os.Stderr, "crypto/x509: SecTrustSettingsCopyTrustSettings for SecTrustSettingsDomainUser failed: %s\n", err) + } + trustSettings, err = macOS.SecTrustSettingsCopyTrustSettings(cert, macOS.SecTrustSettingsDomainAdmin) + } + if err != nil || trustSettings == 0 { + // If there are neither user nor admin trust settings for a certificate returned + // from SecTrustSettingsCopyCertificates Apple returns kSecTrustSettingsResultInvalid, + // as this method is intended to return certificates _which have trust settings_. + // The most likely case for this being triggered is that the existing trust settings + // are invalid and cannot be properly parsed. In this case SecTrustSettingsCopyTrustSettings + // returns errSecInvalidTrustSettings. The existing cgo implementation returns + // kSecTrustSettingsResultUnspecified in this case, which mostly matches the Apple + // implementation because we don't do anything with certificates marked with this + // result. + // + // See SecPVCGetTrustSettingsResult in Security-59306.41.2/trust/trustd/SecPolicyServer.c + if debugDarwinRoots && err != macOS.ErrNoTrustSettings { + fmt.Fprintf(os.Stderr, "crypto/x509: SecTrustSettingsCopyTrustSettings for SecTrustSettingsDomainAdmin failed: %s\n", err) + } + return macOS.SecTrustSettingsResultUnspecified, nil + } + defer macOS.CFRelease(trustSettings) + + // "An empty trust settings array means 'always trust this certificate' with an + // overall trust setting for the certificate of kSecTrustSettingsResultTrustRoot." + if macOS.CFArrayGetCount(trustSettings) == 0 { + return macOS.SecTrustSettingsResultTrustRoot, nil + } + + isSSLPolicy := func(policyRef macOS.CFRef) bool { + properties := macOS.SecPolicyCopyProperties(policyRef) + defer macOS.CFRelease(properties) + if v, ok := macOS.CFDictionaryGetValueIfPresent(properties, macOS.SecPolicyOid); ok { + return macOS.CFEqual(v, macOS.CFRef(macOS.SecPolicyAppleSSL)) + } + return false + } + + for i := 0; i < macOS.CFArrayGetCount(trustSettings); i++ { + tSetting := macOS.CFArrayGetValueAtIndex(trustSettings, i) + + // First, check if this trust setting is constrained to a non-SSL policy. + if policyRef, ok := macOS.CFDictionaryGetValueIfPresent(tSetting, macOS.SecTrustSettingsPolicy); ok { + if !isSSLPolicy(policyRef) { + continue + } + } + + // Then check if it is restricted to a hostname, so not a root. + if _, ok := macOS.CFDictionaryGetValueIfPresent(tSetting, macOS.SecTrustSettingsPolicyString); ok { + continue + } + + cfNum, ok := macOS.CFDictionaryGetValueIfPresent(tSetting, macOS.SecTrustSettingsResultKey) + // "If this key is not present, a default value of kSecTrustSettingsResultTrustRoot is assumed." + if !ok { + return macOS.SecTrustSettingsResultTrustRoot, nil + } + result, err := macOS.CFNumberGetValue(cfNum) + if err != nil { + return 0, err + } + + // If multiple dictionaries match, we are supposed to "OR" them, + // the semantics of which are not clear. Since TrustRoot and TrustAsRoot + // are mutually exclusive, Deny should probably override, and Invalid and + // Unspecified be overridden, approximate this by stopping at the first + // TrustRoot, TrustAsRoot or Deny. + switch r := macOS.SecTrustSettingsResult(result); r { + case macOS.SecTrustSettingsResultTrustRoot, + macOS.SecTrustSettingsResultTrustAsRoot, + macOS.SecTrustSettingsResultDeny: + return r, nil + } + } + + // If trust settings are present, but none of them match the policy... + // the docs don't tell us what to do. + // + // "Trust settings for a given use apply if any of the dictionaries in the + // certificate’s trust settings array satisfies the specified use." suggests + // that it's as if there were no trust settings at all, so we should maybe + // fallback to the admin trust settings? TODO(golang.org/issue/38888). + + return macOS.SecTrustSettingsResultUnspecified, nil +} diff --git a/libgo/go/crypto/x509/root_darwin_arm_gen.go b/libgo/go/crypto/x509/root_darwin_arm_gen.go deleted file mode 100644 index bc44124a785..00000000000 --- a/libgo/go/crypto/x509/root_darwin_arm_gen.go +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -// Generates root_darwin_armx.go. -// -// As of iOS 8, there is no API for querying the system trusted X.509 root -// certificates. We could use SecTrustEvaluate to verify that a trust chain -// exists for a certificate, but the x509 API requires returning the entire -// chain. -// -// Apple publishes the list of trusted root certificates for iOS on -// support.apple.com. So we parse the list and extract the certificates from -// an OS X machine and embed them into the x509 package. -package main - -import ( - "bytes" - "crypto/sha256" - "crypto/x509" - "encoding/hex" - "encoding/pem" - "flag" - "fmt" - "go/format" - "io/ioutil" - "log" - "net/http" - "os/exec" - "regexp" - "strings" -) - -var output = flag.String("output", "root_darwin_armx.go", "file name to write") - -func main() { - certs, err := selectCerts() - if err != nil { - log.Fatal(err) - } - - buf := new(bytes.Buffer) - - fmt.Fprintf(buf, "// Code generated by root_darwin_arm_gen --output %s; DO NOT EDIT.\n", *output) - fmt.Fprintf(buf, "%s", header) - - fmt.Fprintf(buf, "const systemRootsPEM = `\n") - for _, cert := range certs { - b := &pem.Block{ - Type: "CERTIFICATE", - Bytes: cert.Raw, - } - if err := pem.Encode(buf, b); err != nil { - log.Fatal(err) - } - } - fmt.Fprintf(buf, "`") - - source, err := format.Source(buf.Bytes()) - if err != nil { - log.Fatal("source format error:", err) - } - if err := ioutil.WriteFile(*output, source, 0644); err != nil { - log.Fatal(err) - } -} - -func selectCerts() ([]*x509.Certificate, error) { - ids, err := fetchCertIDs() - if err != nil { - return nil, err - } - - scerts, err := sysCerts() - if err != nil { - return nil, err - } - - var certs []*x509.Certificate - for _, id := range ids { - if c, ok := scerts[id.fingerprint]; ok { - certs = append(certs, c) - } else { - fmt.Printf("WARNING: cannot find certificate: %s (fingerprint: %s)\n", id.name, id.fingerprint) - } - } - return certs, nil -} - -func sysCerts() (certs map[string]*x509.Certificate, err error) { - cmd := exec.Command("/usr/bin/security", "find-certificate", "-a", "-p", "/System/Library/Keychains/SystemRootCertificates.keychain") - data, err := cmd.Output() - if err != nil { - return nil, err - } - certs = make(map[string]*x509.Certificate) - for len(data) > 0 { - var block *pem.Block - block, data = pem.Decode(data) - if block == nil { - break - } - if block.Type != "CERTIFICATE" || len(block.Headers) != 0 { - continue - } - - cert, err := x509.ParseCertificate(block.Bytes) - if err != nil { - continue - } - - fingerprint := sha256.Sum256(cert.Raw) - certs[hex.EncodeToString(fingerprint[:])] = cert - } - return certs, nil -} - -type certID struct { - name string - fingerprint string -} - -// fetchCertIDs fetches IDs of iOS X509 certificates from apple.com. -func fetchCertIDs() ([]certID, error) { - // Download the iOS 11 support page. The index for all iOS versions is here: - // https://support.apple.com/en-us/HT204132 - resp, err := http.Get("https://support.apple.com/en-us/HT208125") - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - text := string(body) - text = text[strings.Index(text, "
")] - - var ids []certID - cols := make(map[string]int) - for i, rowmatch := range regexp.MustCompile("(?s)(.*?)").FindAllStringSubmatch(text, -1) { - row := rowmatch[1] - if i == 0 { - // Parse table header row to extract column names - for i, match := range regexp.MustCompile("(?s)(.*?)").FindAllStringSubmatch(row, -1) { - cols[match[1]] = i - } - continue - } - - values := regexp.MustCompile("(?s)(.*?)").FindAllStringSubmatch(row, -1) - name := values[cols["Certificate name"]][1] - fingerprint := values[cols["Fingerprint (SHA-256)"]][1] - fingerprint = strings.ReplaceAll(fingerprint, "
", "") - fingerprint = strings.ReplaceAll(fingerprint, "\n", "") - fingerprint = strings.ReplaceAll(fingerprint, " ", "") - fingerprint = strings.ToLower(fingerprint) - - ids = append(ids, certID{ - name: name, - fingerprint: fingerprint, - }) - } - return ids, nil -} - -const header = ` -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build cgo -// +build darwin -// +build arm arm64 ios - -package x509 - -func loadSystemRoots() (*CertPool, error) { - p := NewCertPool() - p.AppendCertsFromPEM([]byte(systemRootsPEM)) - return p, nil -} -` diff --git a/libgo/go/crypto/x509/root_darwin_armx.go b/libgo/go/crypto/x509/root_darwin_armx.go deleted file mode 100644 index fcbbd6b1701..00000000000 --- a/libgo/go/crypto/x509/root_darwin_armx.go +++ /dev/null @@ -1,4313 +0,0 @@ -// Code generated by root_darwin_arm_gen --output root_darwin_armx.go; DO NOT EDIT. - -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build cgo -// +build darwin -// +build arm arm64 ios - -package x509 - -func loadSystemRoots() (*CertPool, error) { - p := NewCertPool() - p.AppendCertsFromPEM([]byte(systemRootsPEM)) - return p, nil -} - -const systemRootsPEM = ` ------BEGIN CERTIFICATE----- -MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb -MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow -GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj -YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL -MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE -BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM -GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua -BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe -3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 -YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR -rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm -ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU -oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF -MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v -QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t -b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF -AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q -GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz -Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 -G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi -l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 -smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE -BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w -MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 -IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC -SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 -ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv -UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX -4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 -KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ -gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb -rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ -51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F -be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe -KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F -v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn -fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 -jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz -ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt -ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL -e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 -jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz -WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V -SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j -pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX -X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok -fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R -K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU -ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU -LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT -LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU -MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 -b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMw -MTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML -QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYD -VQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA -A4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ul -CDtbKRY654eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6n -tGO0/7Gcrjyvd7ZWxbWroulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyl -dI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJch -PXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC -+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0O -BBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8E -BTADAQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBl -MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk -ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENB -IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0MkhHma6X -7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0PhiVYrqW9yTkkz -43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY -eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJl -pz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOA -WiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU -MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs -IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 -MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux -FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h -bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v -dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt -H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 -uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX -mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX -a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN -E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 -WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD -VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 -Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU -cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx -IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN -AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH -YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 -6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC -Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX -c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a -mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFVTCCBD2gAwIBAgIEO/OB0DANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQGEwJj -aDEOMAwGA1UEChMFYWRtaW4xETAPBgNVBAsTCFNlcnZpY2VzMSIwIAYDVQQLExlD -ZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRYwFAYDVQQDEw1BZG1pbi1Sb290LUNB -MB4XDTAxMTExNTA4NTEwN1oXDTIxMTExMDA3NTEwN1owbDELMAkGA1UEBhMCY2gx -DjAMBgNVBAoTBWFkbWluMREwDwYDVQQLEwhTZXJ2aWNlczEiMCAGA1UECxMZQ2Vy -dGlmaWNhdGlvbiBBdXRob3JpdGllczEWMBQGA1UEAxMNQWRtaW4tUm9vdC1DQTCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMvgr0QUIv5qF0nyXZ3PXAJi -C4C5Wr+oVTN7oxIkXkxvO0GJToM9n7OVJjSmzBL0zJ2HXj0MDRcvhSY+KiZZc6Go -vDvr5Ua481l7ILFeQAFtumeza+vvxeL5Nd0Maga2miiacLNAKXbAcUYRa0Ov5VZB -++YcOYNNt/aisWbJqA2y8He+NsEgJzK5zNdayvYXQTZN+7tVgWOck16Da3+4FXdy -fH1NCWtZlebtMKtERtkVAaVbiWW24CjZKAiVfggjsiLo3yVMPGj3budLx5D9hEEm -vlyDOtcjebca+AcZglppWMX/iHIrx7740y0zd6cWEqiLIcZCrnpkr/KzwO135GkC -AwEAAaOCAf0wggH5MA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIASBkTCBjjCBiwYI -YIV0AREDAQAwfzArBggrBgEFBQcCAjAfGh1UaGlzIGlzIHRoZSBBZG1pbi1Sb290 -LUNBIENQUzBQBggrBgEFBQcCARZEaHR0cDovL3d3dy5pbmZvcm1hdGlrLmFkbWlu -LmNoL1BLSS9saW5rcy9DUFNfMl8xNl83NTZfMV8xN18zXzFfMC5wZGYwfwYDVR0f -BHgwdjB0oHKgcKRuMGwxFjAUBgNVBAMTDUFkbWluLVJvb3QtQ0ExIjAgBgNVBAsT -GUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxETAPBgNVBAsTCFNlcnZpY2VzMQ4w -DAYDVQQKEwVhZG1pbjELMAkGA1UEBhMCY2gwHQYDVR0OBBYEFIKf+iNzIPGXi7JM -Tb5CxX9mzWToMIGZBgNVHSMEgZEwgY6AFIKf+iNzIPGXi7JMTb5CxX9mzWTooXCk -bjBsMQswCQYDVQQGEwJjaDEOMAwGA1UEChMFYWRtaW4xETAPBgNVBAsTCFNlcnZp -Y2VzMSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRYwFAYDVQQD -Ew1BZG1pbi1Sb290LUNBggQ784HQMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0B -AQUFAAOCAQEAeE96XCYRpy6umkPKXDWCRn7INo96ZrWpMggcDORuofHIwdTkgOeM -vWOxDN/yuT7CC3FAaUajbPRbDw0hRMcqKz0aC8CgwcyIyhw/rFK29mfNTG3EviP9 -QSsEbnelFnjpm1wjz4EaBiFjatwpUbI6+Zv3XbEt9QQXBn+c6DeFLe4xvC4B+MTr -a440xTk59pSYux8OHhEvqIwHCkiijGqZhTS3KmGFeBopaR+dJVBRBMoXwzk4B3Hn -0Zib1dEYFZa84vPJZyvxCbLOnPRDJgH6V2uQqbG+6DXVaf/wORVOvF/wzzv0viM/ -RWbEtJZdvo8N3sdtCULzifnxP/V0T9+4ZQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz -dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL -MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp -cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP -Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr -ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL -MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 -yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr -VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ -nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ -KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG -XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj -vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt -Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g -N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC -nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz -dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL -MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp -cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y -YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua -kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL -QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp -6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG -yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i -QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ -KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO -tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu -QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ -Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u -olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 -x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC -VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ -cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ -BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt -VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D -0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 -ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G -A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G -A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs -aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I -flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz -dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG -A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U -cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf -qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ -JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ -+jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS -s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 -HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 -70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG -V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S -qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S -5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia -C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX -OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE -FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ -BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 -KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg -Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B -8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ -MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc -0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ -u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF -u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH -YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 -GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO -RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e -KeC2uAloGRwYQw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIIGDCCBgCgAwIBAgIGAT8vMXfmMA0GCSqGSIb3DQEBCwUAMIIBCjELMAkGA1UE -BhMCRVMxEjAQBgNVBAgMCUJhcmNlbG9uYTFYMFYGA1UEBwxPQmFyY2Vsb25hIChz -ZWUgY3VycmVudCBhZGRyZXNzIGF0IGh0dHA6Ly93d3cuYW5mLmVzL2VzL2FkZHJl -c3MtZGlyZWNjaW9uLmh0bWwgKTEnMCUGA1UECgweQU5GIEF1dG9yaWRhZCBkZSBD -ZXJ0aWZpY2FjaW9uMRcwFQYDVQQLDA5BTkYgQ2xhc2UgMSBDQTEaMBgGCSqGSIb3 -DQEJARYLaW5mb0BhbmYuZXMxEjAQBgNVBAUTCUc2MzI4NzUxMDEbMBkGA1UEAwwS -QU5GIEdsb2JhbCBSb290IENBMB4XDTEzMDYxMDE3NDUzOFoXDTMzMDYwNTE3NDUz -OFowggEKMQswCQYDVQQGEwJFUzESMBAGA1UECAwJQmFyY2Vsb25hMVgwVgYDVQQH -DE9CYXJjZWxvbmEgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgaHR0cDovL3d3dy5h -bmYuZXMvZXMvYWRkcmVzcy1kaXJlY2Npb24uaHRtbCApMScwJQYDVQQKDB5BTkYg -QXV0b3JpZGFkIGRlIENlcnRpZmljYWNpb24xFzAVBgNVBAsMDkFORiBDbGFzZSAx -IENBMRowGAYJKoZIhvcNAQkBFgtpbmZvQGFuZi5lczESMBAGA1UEBRMJRzYzMjg3 -NTEwMRswGQYDVQQDDBJBTkYgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQDHPi9xy4wynbcUbWjorVUgQKeUAVh937J7P37XmsfH -ZLOBZKIIlhhCtRwnDlg7x+BUvtJOTkIbEGMujDygUQ2s3HDYr5I41hTyM2Pl0cq2 -EuSGEbPIHb3dEX8NAguFexM0jqNjrreN3hM2/+TOkAxSdDJP2aMurlySC5zwl47K -ZLHtcVrkZnkDa0o5iN24hJT4vBDT4t2q9khQ+qb1D8KgCOb02r1PxWXu3vfd6Ha2 -mkdB97iGuEh5gO2n4yOmFS5goFlVA2UdPbbhJsb8oKVKDd+YdCKGQDCkQyG4AjmC -YiNm3UPG/qtftTH5cWri67DlLtm6fyUFOMmO6NSh0RtR745pL8GyWJUanyq/Q4bF -HQB21E+WtTsCaqjGaoFcrBunMypmCd+jUZXl27TYENRFbrwNdAh7m2UztcIyb+Sg -VJFyfvVsBQNvnp7GPimVxXZNc4VpxEXObRuPWQN1oZN/90PcZVqTia/SHzEyTryL -ckhiLG3jZiaFZ7pTZ5I9wti9Pn+4kOHvE3Y/4nEnUo4mTxPX9pOlinF+VCiybtV2 -u1KSlc+YaIM7VmuyndDZCJRXm3v0/qTE7t5A5fArZl9lvibigMbWB8fpD+c1GpGH -Eo8NRY0lkaM+DkIqQoaziIsz3IKJrfdKaq9bQMSlIfameKBZ8fNYTBZrH9KZAIhz -YwIDAQABo4IBfjCCAXowHQYDVR0OBBYEFIf6nt9SdnXsSUogb1twlo+d77sXMB8G -A1UdIwQYMBaAFIf6nt9SdnXsSUogb1twlo+d77sXMA8GA1UdEwEB/wQFMAMBAf8w -DgYDVR0PAQH/BAQDAgEGMIIBFQYDVR0RBIIBDDCCAQiCEWh0dHA6Ly93d3cuYW5m -LmVzgQtpbmZvQGFuZi5lc6SB5TCB4jE0MDIGA1UECQwrR3JhbiBWaWEgZGUgbGVz -IENvcnRzIENhdGFsYW5lcy4gOTk2LiAwODAxODESMBAGA1UEBwwJQmFyY2Vsb25h -MScwJQYDVQQKDB5BTkYgQXV0b3JpZGFkIGRlIENlcnRpZmljYWNpb24xEjAQBgNV -BAUTCUc2MzI4NzUxMDFZMFcGA1UECwxQSW5zY3JpdGEgZW4gZWwgTWluaXN0ZXJp -byBkZWwgSW50ZXJpb3IgZGUgRXNwYcOxYSBjb24gZWwgbnVtZXJvIG5hY2lvbmFs -IDE3MS40NDMwDQYJKoZIhvcNAQELBQADggIBAIgR9tFTZ9BCYg+HViMxOfF0MHN2 -Pe/eC128ARdS+GH8A4thtbqiH/SOYbWofO/0zssHhNKa5iQEj45lCAb8BANpWJMD -nWkPr6jq2+50a6d0MMgSS2l1rvjSF+3nIrEuicshHXSTi3q/vBLKr7uGKMVFaM68 -XAropIwk6ndlA0JseARSPsbetv7ALESMIZAxlHV1TcctYHd0bB3c/Jz+PLszJQqs -Cg/kBPo2D111OXZkIY8W/fJuG9veR783khAK2gUnC0zLLCNsYzEbdGt8zUmBsAsM -cGxqGm6B6vDXd65OxWqw13xdq/24+5R8Ng1PF9tvfjZkUFBF30CxjWur7P90WiKI -G7IGfr6BE1NgXlhEQQu4F+HizB1ypEPzGWltecXQ4yOzO+H0WfFTjLTYX6VSveyW -DQV18ixF8M4tHP/SwNE+yyv2b2JJ3/3RpxjtFlLk+opJ574x0gD/dMJuWTH0JqVY -3PbRfE1jIxFpk164Qz/Xp7H7w7f6xh+tQCkBs3PUYmnGIZcPwq44Q6JHlCNsKx4K -hxfggTvRCk4w79cUID45c2qDsRCqTPoOo/cbOpcfVhbH9LdMORpmuLwNogRZEUSE -fWpqR9q+0kcQf4zGSWIURIyDrogdpDgoHDxktqgMgc+qA4ZE2WQl1D8hmev53A46 -lUSrWUiWfDXtK3ux ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFkjCCA3qgAwIBAgIIAeDltYNno+AwDQYJKoZIhvcNAQEMBQAwZzEbMBkGA1UE -AwwSQXBwbGUgUm9vdCBDQSAtIEcyMSYwJAYDVQQLDB1BcHBsZSBDZXJ0aWZpY2F0 -aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMw -HhcNMTQwNDMwMTgxMDA5WhcNMzkwNDMwMTgxMDA5WjBnMRswGQYDVQQDDBJBcHBs -ZSBSb290IENBIC0gRzIxJjAkBgNVBAsMHUFwcGxlIENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5MRMwEQYDVQQKDApBcHBsZSBJbmMuMQswCQYDVQQGEwJVUzCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBANgREkhI2imKScUcx+xuM23+TfvgHN6s -XuI2pyT5f1BrTM65MFQn5bPW7SXmMLYFN14UIhHF6Kob0vuy0gmVOKTvKkmMXT5x -ZgM4+xb1hYjkWpIMBDLyyED7Ul+f9sDx47pFoFDVEovy3d6RhiPw9bZyLgHaC/Yu -OQhfGaFjQQscp5TBhsRTL3b2CtcM0YM/GlMZ81fVJ3/8E7j4ko380yhDPLVoACVd -J2LT3VXdRCCQgzWTxb+4Gftr49wIQuavbfqeQMpOhYV4SbHXw8EwOTKrfl+q04tv -ny0aIWhwZ7Oj8ZhBbZF8+NfbqOdfIRqMM78xdLe40fTgIvS/cjTf94FNcX1RoeKz -8NMoFnNvzcytN31O661A4T+B/fc9Cj6i8b0xlilZ3MIZgIxbdMYs0xBTJh0UT8TU -gWY8h2czJxQI6bR3hDRSj4n4aJgXv8O7qhOTH11UL6jHfPsNFL4VPSQ08prcdUFm -IrQB1guvkJ4M6mL4m1k8COKWNORj3rw31OsMiANDC1CvoDTdUE0V+1ok2Az6DGOe -HwOx4e7hqkP0ZmUoNwIx7wHHHtHMn23KVDpA287PT0aLSmWaasZobNfMmRtHsHLD -d4/E92GcdB/O/WuhwpyUgquUoue9G7q5cDmVF8Up8zlYNPXEpMZ7YLlmQ1A/bmH8 -DvmGqmAMQ0uVAgMBAAGjQjBAMB0GA1UdDgQWBBTEmRNsGAPCe8CjoA1/coB6HHcm -jTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQwF -AAOCAgEAUabz4vS4PZO/Lc4Pu1vhVRROTtHlznldgX/+tvCHM/jvlOV+3Gp5pxy+ -8JS3ptEwnMgNCnWefZKVfhidfsJxaXwU6s+DDuQUQp50DhDNqxq6EWGBeNjxtUVA -eKuowM77fWM3aPbn+6/Gw0vsHzYmE1SGlHKy6gLti23kDKaQwFd1z4xCfVzmMX3z -ybKSaUYOiPjjLUKyOKimGY3xn83uamW8GrAlvacp/fQ+onVJv57byfenHmOZ4VxG -/5IFjPoeIPmGlFYl5bRXOJ3riGQUIUkhOb9iZqmxospvPyFgxYnURTbImHy99v6Z -SYA7LNKmp4gDBDEZt7Y6YUX6yfIjyGNzv1aJMbDZfGKnexWoiIqrOEDCzBL/FePw -N983csvMmOa/orz6JopxVtfnJBtIRD6e/J/JzBrsQzwBvDR4yGn1xuZW7AYJNpDr -FEobXsmII9oDMJELuDY++ee1KG++P+w8j2Ud5cAeh6Squpj9kuNsJnfdBrRkBof0 -Tta6SqoWqPQFZ2aWuuJVecMsXUmPgEkrihLHdoBR37q9ZV0+N0djMenl9MU/S60E -inpxLK8JQzcPqOMyT/RFtm2XNuyE9QoB6he7hY1Ck3DDUOUUi78/w0EP3SIEIwiK -um1xRKtzCTrJ+VKACd+66eYWyi4uTLLT3OUEVLLUNIAytbwPF+E= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICQzCCAcmgAwIBAgIILcX8iNLFS5UwCgYIKoZIzj0EAwMwZzEbMBkGA1UEAwwS -QXBwbGUgUm9vdCBDQSAtIEczMSYwJAYDVQQLDB1BcHBsZSBDZXJ0aWZpY2F0aW9u -IEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwHhcN -MTQwNDMwMTgxOTA2WhcNMzkwNDMwMTgxOTA2WjBnMRswGQYDVQQDDBJBcHBsZSBS -b290IENBIC0gRzMxJjAkBgNVBAsMHUFwcGxlIENlcnRpZmljYXRpb24gQXV0aG9y -aXR5MRMwEQYDVQQKDApBcHBsZSBJbmMuMQswCQYDVQQGEwJVUzB2MBAGByqGSM49 -AgEGBSuBBAAiA2IABJjpLz1AcqTtkyJygRMc3RCV8cWjTnHcFBbZDuWmBSp3ZHtf -TjjTuxxEtX/1H7YyYl3J6YRbTzBPEVoA/VhYDKX1DyxNB0cTddqXl5dvMVztK517 -IDvYuVTZXpmkOlEKMaNCMEAwHQYDVR0OBBYEFLuw3qFYM4iapIqZ3r6966/ayySr -MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2gA -MGUCMQCD6cHEFl4aXTQY2e3v9GwOAEZLuN+yRhHFD/3meoyhpmvOwgPUnPWTxnS4 -at+qIxUCMG1mihDK1A3UT82NQz60imOlM27jbdoXt2QfyFMm+YhidDkLF1vLUagM -6BgD56KyKA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEuzCCA6OgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJVUzET -MBEGA1UEChMKQXBwbGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkxFjAUBgNVBAMTDUFwcGxlIFJvb3QgQ0EwHhcNMDYwNDI1MjE0 -MDM2WhcNMzUwMjA5MjE0MDM2WjBiMQswCQYDVQQGEwJVUzETMBEGA1UEChMKQXBw -bGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx -FjAUBgNVBAMTDUFwcGxlIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQDkkakJH5HbHkdQ6wXtXnmELes2oldMVeyLGYne+Uts9QerIjAC6Bg+ -+FAJ039BqJj50cpmnCRrEdCju+QbKsMflZ56DKRHi1vUFjczy8QPTc4UadHJGXL1 -XQ7Vf1+b8iUDulWPTV0N8WQ1IxVLFVkds5T39pyez1C6wVhQZ48ItCD3y6wsIG9w -tj8BMIy3Q88PnT3zK0koGsj+zrW5DtleHNbLPbU6rfQPDgCSC7EhFi501TwN22IW -q6NxkkdTVcGvL0Gz+PvjcM3mo0xFfh9Ma1CWQYnEdGILEINBhzOKgbEwWOxaBDKM -aLOPHd5lc/9nXmW8Sdh2nzMUZaF3lMktAgMBAAGjggF6MIIBdjAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUK9BpR5R2Cf70a40uQKb3 -R01/CF4wHwYDVR0jBBgwFoAUK9BpR5R2Cf70a40uQKb3R01/CF4wggERBgNVHSAE -ggEIMIIBBDCCAQAGCSqGSIb3Y2QFATCB8jAqBggrBgEFBQcCARYeaHR0cHM6Ly93 -d3cuYXBwbGUuY29tL2FwcGxlY2EvMIHDBggrBgEFBQcCAjCBthqBs1JlbGlhbmNl -IG9uIHRoaXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFzc3VtZXMgYWNjZXB0 -YW5jZSBvZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5kYXJkIHRlcm1zIGFuZCBj -b25kaXRpb25zIG9mIHVzZSwgY2VydGlmaWNhdGUgcG9saWN5IGFuZCBjZXJ0aWZp -Y2F0aW9uIHByYWN0aWNlIHN0YXRlbWVudHMuMA0GCSqGSIb3DQEBBQUAA4IBAQBc -NplMLXi37Yyb3PN3m/J20ncwT8EfhYOFG5k9RzfyqZtAjizUsZAS2L70c5vu0mQP -y3lPNNiiPvl4/2vIB+x9OYOLUyDTOMSxv5pPCmv/K/xZpwUJfBdAVhEedNO3iyM7 -R6PVbyTi69G3cN8PReEnyvFteO3ntRcXqNx+IjXKJdXZD9Zr1KIkIxH3oayPc4Fg -xhtbCS+SsvhESPBgOJ4V9T0mZyCKM2r3DYLP3uujL/lTaltkwGMzd/c6ByxW69oP -IQ7aunMZT7XZNn/Bh1XZp5m5MkL72NVxnn6hUrcbvZNCJBIqxw8dtk2cXmPIS4AX -UKqK1drk/NAJBzewdXUh ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFujCCBKKgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhjELMAkGA1UEBhMCVVMx -HTAbBgNVBAoTFEFwcGxlIENvbXB1dGVyLCBJbmMuMS0wKwYDVQQLEyRBcHBsZSBD -b21wdXRlciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxKTAnBgNVBAMTIEFwcGxlIFJv -b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTA1MDIxMDAwMTgxNFoXDTI1MDIx -MDAwMTgxNFowgYYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRBcHBsZSBDb21wdXRl -ciwgSW5jLjEtMCsGA1UECxMkQXBwbGUgQ29tcHV0ZXIgQ2VydGlmaWNhdGUgQXV0 -aG9yaXR5MSkwJwYDVQQDEyBBcHBsZSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 -eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOSRqQkfkdseR1DrBe1e -eYQt6zaiV0xV7IsZid75S2z1B6siMALoGD74UAnTf0GomPnRymacJGsR0KO75Bsq -wx+VnnoMpEeLW9QWNzPLxA9NzhRp0ckZcvVdDtV/X5vyJQO6VY9NXQ3xZDUjFUsV -WR2zlPf2nJ7PULrBWFBnjwi0IPfLrCwgb3C2PwEwjLdDzw+dPfMrSSgayP7OtbkO -2V4c1ss9tTqt9A8OAJILsSEWLnTVPA3bYharo3GSR1NVwa8vQbP4++NwzeajTEV+ -H0xrUJZBicR0YgsQg0GHM4qBsTBY7FoEMoxos48d3mVz/2deZbxJ2HafMxRloXeU -yS0CAwEAAaOCAi8wggIrMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ -MB0GA1UdDgQWBBQr0GlHlHYJ/vRrjS5ApvdHTX8IXjAfBgNVHSMEGDAWgBQr0GlH -lHYJ/vRrjS5ApvdHTX8IXjCCASkGA1UdIASCASAwggEcMIIBGAYJKoZIhvdjZAUB -MIIBCTBBBggrBgEFBQcCARY1aHR0cHM6Ly93d3cuYXBwbGUuY29tL2NlcnRpZmlj -YXRlYXV0aG9yaXR5L3Rlcm1zLmh0bWwwgcMGCCsGAQUFBwICMIG2GoGzUmVsaWFu -Y2Ugb24gdGhpcyBjZXJ0aWZpY2F0ZSBieSBhbnkgcGFydHkgYXNzdW1lcyBhY2Nl -cHRhbmNlIG9mIHRoZSB0aGVuIGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5k -IGNvbmRpdGlvbnMgb2YgdXNlLCBjZXJ0aWZpY2F0ZSBwb2xpY3kgYW5kIGNlcnRp -ZmljYXRpb24gcHJhY3RpY2Ugc3RhdGVtZW50cy4wRAYDVR0fBD0wOzA5oDegNYYz -aHR0cHM6Ly93d3cuYXBwbGUuY29tL2NlcnRpZmljYXRlYXV0aG9yaXR5L3Jvb3Qu -Y3JsMFUGCCsGAQUFBwEBBEkwRzBFBggrBgEFBQcwAoY5aHR0cHM6Ly93d3cuYXBw -bGUuY29tL2NlcnRpZmljYXRlYXV0aG9yaXR5L2Nhc2lnbmVycy5odG1sMA0GCSqG -SIb3DQEBBQUAA4IBAQCd2i0oWC99dgS5BNM+zrdmY06PL9T+S61yvaM5xlJNBZhS -9YlRASR5vhoy9+VEi0tEBzmC1lrKtCBe2a4VXR2MHTK/ODFiSF3H4ZCx+CRA+F9Y -m1FdV53B5f88zHIhbsTp6aF31ywXJsM/65roCwO66bNKcuszCVut5mIxauivL9Wv -Hld2j383LS4CXN1jyfJxuCZA3xWNdUQ/eb3mHZnhQyw+rW++uaT+DjUZUWOxw961 -kj5ReAFziqQjyqSI8R5cH0EWLX6VCqrpiUGYGxrdyyC/R14MJsVVNU3GMIuZZxTH -CR+6R8faAQmHJEKVvRNgGQrv6n8Obs3BREM6StXj ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID9zCCAt+gAwIBAgILMTI1MzcyODI4MjgwDQYJKoZIhvcNAQELBQAwWDELMAkG -A1UEBhMCSlAxHDAaBgNVBAoTE0phcGFuZXNlIEdvdmVybm1lbnQxDTALBgNVBAsT -BEdQS0kxHDAaBgNVBAMTE0FwcGxpY2F0aW9uQ0EyIFJvb3QwHhcNMTMwMzEyMTUw -MDAwWhcNMzMwMzEyMTUwMDAwWjBYMQswCQYDVQQGEwJKUDEcMBoGA1UEChMTSmFw -YW5lc2UgR292ZXJubWVudDENMAsGA1UECxMER1BLSTEcMBoGA1UEAxMTQXBwbGlj -YXRpb25DQTIgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKaq -rSVl1gAR1uh6dqr05rRL88zDUrSNrKZPtZJxb0a11a2LEiIXJc5F6BR6hZrkIxCo -+rFnUOVtR+BqiRPjrq418fRCxQX3TZd+PCj8sCaRHoweOBqW3FhEl2LjMsjRFUFN -dZh4vqtoqV7tR76kuo6hApfek3SZbWe0BSXulMjtqqS6MmxCEeu+yxcGkOGThchk -KM4fR8fAXWDudjbcMztR63vPctgPeKgZggiQPhqYjY60zxU2pm7dt+JNQCBT2XYq -0HisifBPizJtROouurCp64ndt295D6uBbrjmiykLWa+2SQ1RLKn9nShjZrhwlXOa -2Po7M7xCQhsyrLEy+z0CAwEAAaOBwTCBvjAdBgNVHQ4EFgQUVqesqgIdsqw9kA6g -by5Bxnbne9owDgYDVR0PAQH/BAQDAgEGMHwGA1UdEQR1MHOkcTBvMQswCQYDVQQG -EwJKUDEYMBYGA1UECgwP5pel5pys5Zu95pS/5bqcMRswGQYDVQQLDBLmlL/lupzo -qo3oqLzln7rnm6QxKTAnBgNVBAMMIOOCouODl+ODquOCseODvOOCt+ODp+ODs0NB -MiBSb290MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAH+aCXWs -B9FydC53VzDCBJzUgKaD56WgG5/+q/OAvdVKo6GPtkxgEefK4WCB10jBIFmlYTKL -nZ6X02aD2mUuWD7b5S+lzYxzplG+WCigeVxpL0PfY7KJR8q73rk0EWOgDiUX5Yf0 -HbCwpc9BqHTG6FPVQvSCLVMJEWgmcZR1E02qdog8dLHW40xPYsNJTE5t8XB+w3+m -Bcx4m+mB26jIx1ye/JKSLaaX8ji1bnOVDMA/zqaUMLX6BbfeniCq/BNkyYq6ZO/i -Y+TYmK5rtT6mVbgzPixy+ywRAPtbFi+E0hOe+gXFwctyTiLdhMpLvNIthhoEdlkf -SUJiOxMfFui61/0= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE -AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG -EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM -FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC -REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp -Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM -VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+ -SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ -4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L -cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi -eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV -HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG -A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3 -DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j -vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP -DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc -maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D -lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv -KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE -BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h -cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy -MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg -Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 -thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM -cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG -L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i -NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h -X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b -m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy -Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja -EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T -KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF -6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh -OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD -VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD -VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp -cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv -ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl -AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF -661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 -am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 -ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 -PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS -3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k -SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF -3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM -ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g -StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz -Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB -jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIJmzCCB4OgAwIBAgIBATANBgkqhkiG9w0BAQwFADCCAR4xPjA8BgNVBAMTNUF1 -dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIFJhaXogZGVsIEVzdGFkbyBWZW5lem9s -YW5vMQswCQYDVQQGEwJWRTEQMA4GA1UEBxMHQ2FyYWNhczEZMBcGA1UECBMQRGlz -dHJpdG8gQ2FwaXRhbDE2MDQGA1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0 -aWZpY2FjaW9uIEVsZWN0cm9uaWNhMUMwQQYDVQQLEzpTdXBlcmludGVuZGVuY2lh -IGRlIFNlcnZpY2lvcyBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMSUwIwYJ -KoZIhvcNAQkBFhZhY3JhaXpAc3VzY2VydGUuZ29iLnZlMB4XDTEwMTIyMjE4MDgy -MVoXDTMwMTIxNzIzNTk1OVowggEeMT4wPAYDVQQDEzVBdXRvcmlkYWQgZGUgQ2Vy -dGlmaWNhY2lvbiBSYWl6IGRlbCBFc3RhZG8gVmVuZXpvbGFubzELMAkGA1UEBhMC -VkUxEDAOBgNVBAcTB0NhcmFjYXMxGTAXBgNVBAgTEERpc3RyaXRvIENhcGl0YWwx -NjA0BgNVBAoTLVNpc3RlbWEgTmFjaW9uYWwgZGUgQ2VydGlmaWNhY2lvbiBFbGVj -dHJvbmljYTFDMEEGA1UECxM6U3VwZXJpbnRlbmRlbmNpYSBkZSBTZXJ2aWNpb3Mg -ZGUgQ2VydGlmaWNhY2lvbiBFbGVjdHJvbmljYTElMCMGCSqGSIb3DQEJARYWYWNy -YWl6QHN1c2NlcnRlLmdvYi52ZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC -ggIBAME77xNS8ZlW47RsBeEaaRZhJoZ4rw785UAFCuPZOAVMqNS1wMYqzy95q6Gk -UO81ER/ugiQX/KMcq/4HBn83fwdYWxPZfwBfK7BP2p/JsFgzYeFP0BXOLmvoJIzl -Jb6FW+1MPwGBjuaZGFImWZsSmGUclb51mRYMZETh9/J5CLThR1exStxHQptwSzra -zNFpkQY/zmj7+YZNA9yDoroVFv6sybYOZ7OxNDo7zkSLo45I7gMwtxqWZ8VkJZkC -8+p0dX6mkhUT0QAV64Zc9HsZiH/oLhEkXjhrgZ28cF73MXIqLx1fyM4kPH1yOJi/ -R72nMwL7D+Sd6mZgI035TxuHXc2/uOwXfKrrTjaJDz8Jp6DdessOkxIgkKXRjP+F -K3ze3n4NUIRGhGRtyvEjK95/2g02t6PeYiYVGur6ruS49n0RAaSS0/LJb6XzaAAe -0mmO2evnEqxIKwy2mZRNPfAVW1l3wCnWiUwryBU6OsbFcFFrQm+00wOicXvOTHBM -aiCVAVZTb9RSLyi+LJ1llzJZO3pq3IRiiBj38Nooo+2ZNbMEciSgmig7YXaUcmud -SVQvLSL+Yw+SqawyezwZuASbp7d/0rutQ59d81zlbMt3J7yB567rT2IqIydQ8qBW -k+fmXzghX+/FidYsh/aK+zZ7Wy68kKHuzEw1Vqkat5DGs+VzAgMBAAGjggLeMIIC -2jASBgNVHRMBAf8ECDAGAQH/AgECMDcGA1UdEgQwMC6CD3N1c2NlcnRlLmdvYi52 -ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAzNi0wMB0GA1UdDgQWBBStuyIdxuDS -Aaj9dlBSk+2YwU2u0zCCAVAGA1UdIwSCAUcwggFDgBStuyIdxuDSAaj9dlBSk+2Y -wU2u06GCASakggEiMIIBHjE+MDwGA1UEAxM1QXV0b3JpZGFkIGRlIENlcnRpZmlj -YWNpb24gUmFpeiBkZWwgRXN0YWRvIFZlbmV6b2xhbm8xCzAJBgNVBAYTAlZFMRAw -DgYDVQQHEwdDYXJhY2FzMRkwFwYDVQQIExBEaXN0cml0byBDYXBpdGFsMTYwNAYD -VQQKEy1TaXN0ZW1hIE5hY2lvbmFsIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25p -Y2ExQzBBBgNVBAsTOlN1cGVyaW50ZW5kZW5jaWEgZGUgU2VydmljaW9zIGRlIENl -cnRpZmljYWNpb24gRWxlY3Ryb25pY2ExJTAjBgkqhkiG9w0BCQEWFmFjcmFpekBz -dXNjZXJ0ZS5nb2IudmWCAQEwDgYDVR0PAQH/BAQDAgEGMDcGA1UdEQQwMC6CD3N1 -c2NlcnRlLmdvYi52ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAzNi0wMFQGA1Ud -HwRNMEswJKAioCCGHmhodHA6Ly93d3cuc3VzY2VydGUuZ29iLnZlL2xjcjAjoCGg -H4YdbGRhcDovL2FjcmFpei5zdXNjZXJ0ZS5nb2IudmUwNwYIKwYBBQUHAQEEKzAp -MCcGCCsGAQUFBzABhhtoaHRwOi8vb2NzcC5zdXNjZXJ0ZS5nb2IudmUwQAYDVR0g -BDkwNzA1BgVghl4BAjAsMCoGCCsGAQUFBwIBFh5odHRwOi8vd3d3LnN1c2NlcnRl -LmdvYi52ZS9kcGMwDQYJKoZIhvcNAQEMBQADggIBAK4qy/zmZ9zBwfW3yOYtLcBT -Oy4szJyPz7/RhNH3bPVH7HbDTGpi6JZ4YXdXMBeJE5qBF4a590Kgj8Rlnltt+Rbo -OFQOU1UDqKuTdBsA//Zry5899fmn8jBUkg4nh09jhHHbLlaUScdz704Zz2+UVg7i -s/r3Legxap60KzmdrmTAE9VKte1TQRgavQwVX5/2mO/J+SCas//UngI+h8SyOucq -mjudYEgBrZaodUsagUfn/+AzFNrGLy+al+5nZeHb8JnCfLHWS0M9ZyhgoeO/czyn -99+5G93VWNv4zfc4KiavHZKrkn8F9pg0ycIZh+OwPT/RE2zq4gTazBMlP3ACIe/p -olkNaOEa8KvgzW96sjBZpMW49zFmyINYkcj+uaNCJrVGsXgdBmkuRGJNWFZ9r0cG -woIaxViFBypsz045r1ESfYPlfDOavBhZ/giR/Xocm9CHkPRY2BApMMR0DUCyGETg -Ql+L3kfdTKzuDjUp2DM9FqysQmaM81YDZufWkMhlZPfHwC7KbNougoLroa5Umeos -bqAXWmk46SwIdWRPLLqbUpDTKooynZKpSYIkkotdgJoVZUUCY+RCO8jsVPEU6ece -SxztNUm5UOta1OJPMwSAKRHOo3ilVb9c6lAixDdvV8MeNbqe6asM1mpCHWbJ/0rg -5Ls9Cxx8hracyp0ev7b0 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ -RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD -VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX -DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y -ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy -VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr -mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr -IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK -mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu -XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy -dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye -jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 -BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 -DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 -9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx -jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 -Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz -ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS -R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDjjCCAnagAwIBAgIIKv++n6Lw6YcwDQYJKoZIhvcNAQEFBQAwKDELMAkGA1UE -BhMCQkUxGTAXBgNVBAMTEEJlbGdpdW0gUm9vdCBDQTIwHhcNMDcxMDA0MTAwMDAw -WhcNMjExMjE1MDgwMDAwWjAoMQswCQYDVQQGEwJCRTEZMBcGA1UEAxMQQmVsZ2l1 -bSBSb290IENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMZzQh6S -/3UPi790hqc/7bIYLS2X+an7mEoj39WN4IzGMhwWLQdC1i22bi+n9fzGhYJdld61 -IgDMqFNAn68KNaJ6x+HK92AQZw6nUHMXU5WfIp8MXW+2QbyM69odRr2nlL/zGsvU -+40OHjPIltfsjFPekx40HopQcSZYtF3CiInaYNKJIT/e1wEYNm7hLHADBGXvmAYr -XR5i3FVr/mZkIV/4L+HXmymvb82fqgxG0YjFnaKVn6w/Fa7yYd/vw2uaItgscf1Y -HewApDgglVrH1Tdjuk+bqv5WRi5j2Qsj1Yr6tSPwiRuhFA0m2kHwOI8w7QUmecFL -TqG4flVSOmlGhHUCAwEAAaOBuzCBuDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zBCBgNVHSAEOzA5MDcGBWA4CQEBMC4wLAYIKwYBBQUHAgEWIGh0dHA6 -Ly9yZXBvc2l0b3J5LmVpZC5iZWxnaXVtLmJlMB0GA1UdDgQWBBSFiuv0xbu+DlkD -lN7WgAEV4xCcOTARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUhYrr9MW7 -vg5ZA5Te1oABFeMQnDkwDQYJKoZIhvcNAQEFBQADggEBAFHYhd27V2/MoGy1oyCc -UwnzSgEMdL8rs5qauhjyC4isHLMzr87lEwEnkoRYmhC598wUkmt0FoqW6FHvv/pK -JaeJtmMrXZRY0c8RcrYeuTlBFk0pvDVTC9rejg7NqZV3JcqUWumyaa7YwBO+mPyW -nIR/VRPmPIfjvCCkpDZoa01gZhz5v6yAlGYuuUGK02XThIAC71AdXkbc98m6tTR8 -KvPG2F9fVJ3bTc0R5/0UAoNmXsimABKgX77OFP67H6dh96tK8QYUn8pJQsKpvO2F -sauBQeYNxUJpU4c5nUwfAA4+Bw11V0SoU7Q2dmSZ3G7rPUZuFF1eR1ONeE3gJ7uO -hXY= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd -MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg -Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow -TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw -HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB -BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr -6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV -L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 -1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx -MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ -QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB -arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr -Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi -FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS -P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN -9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP -AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz -uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h -9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s -A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t -OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo -+fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 -KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 -DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us -H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ -I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 -5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h -3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz -Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd -MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg -Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow -TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw -HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB -BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y -ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E -N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 -tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX -0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c -/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X -KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY -zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS -O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D -34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP -K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 -AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv -Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj -QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV -cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS -IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 -HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa -O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv -033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u -dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE -kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 -3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD -u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq -4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFaTCCA1GgAwIBAgIJAMMDmu5QkG4oMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNV -BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu -MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIxMB4XDTEyMDcxOTA5MDY1NloXDTQy -MDcxOTA5MDY1NlowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx -EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjEw -ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqw3j33Jijp1pedxiy3QRk -D2P9m5YJgNXoqqXinCaUOuiZc4yd39ffg/N4T0Dhf9Kn0uXKE5Pn7cZ3Xza1lK/o -OI7bm+V8u8yN63Vz4STN5qctGS7Y1oprFOsIYgrY3LMATcMjfF9DCCMyEtztDK3A -fQ+lekLZWnDZv6fXARz2m6uOt0qGeKAeVjGu74IKgEH3G8muqzIm1Cxr7X1r5OJe -IgpFy4QxTaz+29FHuvlglzmxZcfe+5nkCiKxLU3lSCZpq+Kq8/v8kiky6bM+TR8n -oc2OuRf7JT7JbvN32g0S9l3HuzYQ1VTW8+DiR0jm3hTaYVKvJrT1cU/J19IG32PK -/yHoWQbgCNWEFVP3Q+V8xaCJmGtzxmjOZd69fwX3se72V6FglcXM6pM6vpmumwKj -rckWtc7dXpl4fho5frLABaTAgqWjR56M6ly2vGfb5ipN0gTco65F97yLnByn1tUD -3AjLLhbKXEAz6GfDLuemROoRRRw1ZS0eRWEkG4IupZ0zXWX4Qfkuy5Q/H6MMMSRE -7cderVC6xkGbrPAXZcD4XW9boAo0PO7X6oifmPmvTiT6l7Jkdtqr9O3jw2Dv1fkC -yC2fg69naQanMVXVz0tv/wQFx1isXxYb5dKj6zHbHzMVTdDypVP1y+E9Tmgt2BLd -qvLmTZtJ5cUoobqwWsagtQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud -DwEB/wQEAwIBBjAdBgNVHQ4EFgQUiQq0OJMa5qvum5EY+fU8PjXQ04IwDQYJKoZI -hvcNAQEFBQADggIBADKL9p1Kyb4U5YysOMo6CdQbzoaz3evUuii+Eq5FLAR0rBNR -xVgYZk2C2tXck8An4b58n1KeElb21Zyp9HWc+jcSjxyT7Ff+Bw+r1RL3D65hXlaA -SfX8MPWbTx9BLxyE04nH4toCdu0Jz2zBuByDHBb6lM19oMgY0sidbvW9adRtPTXo -HqJPYNcHKfyyo6SdbhWSVhlMCrDpfNIZTUJG7L399ldb3Zh+pE3McgODWF3vkzpB -emOqfDqo9ayk0d2iLbYq/J8BjuIQscTK5GfbVSUZP/3oNn6z4eGBrxEWi1CXYBmC -AMBrTXO40RMHPuq2MU/wQppt4hF05ZSsjYSVPCGvxdpHyN85YmLLW1AL14FABZyb -7bq2ix4Eb5YgOe2kfSnbSM6C3NQCjR0EMVrHS/BsYVLXtFHCgWzN4funodKSds+x -DzdYpPJScWc/DIh4gInByLUfkmO+p3qKViwaqKactV2zY9ATIKHrkWzQjX2v3wvk -F7mGnjixlAxYjOBVqjtjbZqJYLhkKpLGN/R+Q0O3c+gB53+XD9fyexn9GtePyfqF -a3qdnom2piiZk4hA9z7NUaPK6u95RyG1/jLix8NRb76AdPCkwzryT+lf3xkK8jsT -Q6wxpLPn6/wY1gGp8yqPNg7rtLG8t0zJa7+h89n07eLw4+1knj0vllJPgFOL ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV -BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu -MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy -MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx -EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw -ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe -NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH -PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I -x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe -QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR -yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO -QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 -H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ -QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD -i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs -nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 -rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud -DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI -hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM -tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf -GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb -lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka -+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal -TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i -nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 -gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr -G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os -zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x -L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV -BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X -DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ -BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4 -QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny -gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw -zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q -130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2 -JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw -DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw -ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT -AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj -AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG -9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h -bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc -fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu -HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w -t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw -WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjET -MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAk -BgNVBAMMHUNlcnRpbm9taXMgLSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4 -Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNl -cnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYwJAYDVQQDDB1DZXJ0 -aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jY -F1AMnmHawE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N -8y4oH3DfVS9O7cdxbwlyLu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWe -rP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K -/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92NjMD2AR5vpTESOH2VwnHu -7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9qc1pkIuVC -28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6 -lSTClrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1E -nn1So2+WLhl+HPNbxxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB -0iSVL1N6aaLwD4ZFjliCK0wi1F6g530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql09 -5gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna4NH4+ej9Uji29YnfAgMBAAGj -WzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQN -jLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ -KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9s -ov3/4gbIOZ/xWqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZM -OH8oMDX/nyNTt7buFHAAQCvaR6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q -619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40nJ+U8/aGH88bc62UeYdocMMzpXDn -2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1BCxMjidPJC+iKunqj -o3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjvJL1v -nxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG -5ERQL1TEqkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWq -pdEdnV1j6CTmNhTih60bWfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZb -dsLLO7XSAPCjDuGtbkD326C00EauFddEwk01+dIL8hf2rGbVJLJP0RyZwG71fet0 -BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/vgt2Fl43N+bYdJeimUV5 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjET -MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAb -BgNVBAMTFENlcnRpbm9taXMgLSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMz -MTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMx -FzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRDZXJ0aW5vbWlzIC0g -Um9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQosP5L2 -fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJfl -LieY6pOod5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQV -WZUKxkd8aRi5pwP5ynapz8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDF -TKWrteoB4owuZH9kb/2jJZOLyKIOSY008B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb -5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09xRLWtwHkziOC/7aOgFLSc -CbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE6OXWk6Ri -wsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJ -wx3tFvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SG -m/lg0h9tkQPTYKbVPZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4 -F2iw4lNVYC2vPsKD2NkJK/DAZNuHi5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZng -WVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIB -BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I6tNxIqSSaHh0 -2TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF -AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/ -0KGRHCwPT5iVWVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWw -F6YSjNRieOpWauwK0kDDPAUwPk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZS -g081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAXlCOotQqSD7J6wWAsOMwaplv/8gzj -qh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJy29SWwNyhlCVCNSN -h4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9Iff/ -ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8V -btaw5BngDwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwj -Y/M50n92Uaf0yKHxDHYiI0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ -8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nMcyrDflOR1m749fPH0FFNjkulW+YZFzvW -gQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVrhkIGuUE= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT -AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD -QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP -MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do -0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ -UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d -RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ -OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv -JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C -AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O -BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ -LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY -MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ -44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I -Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw -i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN -9u6wWk5JRFRYX0KD ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM -MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD -QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM -MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD -QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E -jG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo -ePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI -ULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu -Ob7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg -AKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7 -HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA -uI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa -TOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg -xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q -CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x -O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs -6GAqm4VKQPNriiTsBhYscw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB -gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu -QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG -A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz -OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ -VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 -b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA -DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn -0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB -OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE -fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E -Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m -o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i -sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW -OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez -Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS -adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n -3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC -AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ -F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf -CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 -XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm -djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ -WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb -AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq -P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko -b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj -XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P -5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi -DrW5viSP ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM -MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D -ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU -cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 -WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg -Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw -IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH -UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM -TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU -BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM -kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x -AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV -HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y -sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL -I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 -J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY -VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI -03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD -TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y -aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx -MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j -aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP -T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 -sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL -TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 -/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp -7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz -EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt -hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP -a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot -aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg -TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV -PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv -cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL -tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd -BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB -ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT -ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL -jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS -ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy -P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 -xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d -Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN -5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe -/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z -AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ -5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD -VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 -IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 -MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz -IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz -MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj -dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw -EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp -MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G -CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9 -28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq -VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q -DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR -5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL -ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a -Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl -UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s -+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5 -Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj -ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx -hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV -HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1 -+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN -YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t -L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy -ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt -IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV -HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w -DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW -PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF -5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1 -glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH -FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2 -pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD -xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG -tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq -jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De -fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg -OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ -d0jQ ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn -MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL -ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg -b2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAxNjEzNDNaFw0zNzA5MzAxNjEzNDRa -MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBB -ODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIw -IAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0B -AQEFAAOCAQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtb -unXF/KGIJPov7coISjlUxFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0d -BmpAPrMMhe5cG3nCYsS4No41XQEMIwRHNaqbYE6gZj3LJgqcQKH0XZi/caulAGgq -7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jWDA+wWFjbw2Y3npuRVDM3 -0pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFVd9oKDMyX -roDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIG -A1UdEwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5j -aGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p -26EpW1eLTXYGduHRooowDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIA -BzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24ub3JnMCcGA1Ud -EgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYDVR0gBFEwTzBN -BgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz -aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEB -AAxBl8IahsAifJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZd -p0AJPaxJRUXcLo0waLIJuvvDL8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi -1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wNUPf6s+xCX6ndbcj0dc97wXImsQEc -XCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0 -eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu -tGWaIZDgqtCYvDi1czyL+Nw= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDQzCCAiugAwIBAgIQX/h7KCtU3I1CoxW1aMmt/zANBgkqhkiG9w0BAQUFADA1 -MRYwFAYDVQQKEw1DaXNjbyBTeXN0ZW1zMRswGQYDVQQDExJDaXNjbyBSb290IENB -IDIwNDgwHhcNMDQwNTE0MjAxNzEyWhcNMjkwNTE0MjAyNTQyWjA1MRYwFAYDVQQK -Ew1DaXNjbyBTeXN0ZW1zMRswGQYDVQQDExJDaXNjbyBSb290IENBIDIwNDgwggEg -MA0GCSqGSIb3DQEBAQUAA4IBDQAwggEIAoIBAQCwmrmrp68Kd6ficba0ZmKUeIhH -xmJVhEAyv8CrLqUccda8bnuoqrpu0hWISEWdovyD0My5jOAmaHBKeN8hF570YQXJ -FcjPFto1YYmUQ6iEqDGYeJu5Tm8sUxJszR2tKyS7McQr/4NEb7Y9JHcJ6r8qqB9q -VvYgDxFUl4F1pyXOWWqCZe+36ufijXWLbvLdT6ZeYpzPEApk0E5tzivMW/VgpSdH -jWn0f84bcN5wGyDWbs2mAag8EtKpP6BrXruOIIt6keO1aO6g58QBdKhTCytKmg9l -Eg6CTY5j/e/rmxrbU6YTYK/CfdfHbBcl1HP7R2RQgYCUTOG/rksc35LtLgXfAgED -o1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUJ/PI -FR5umgIJFq0roIlgX9p7L6owEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEF -BQADggEBAJ2dhISjQal8dwy3U8pORFBi71R803UXHOjgxkhLtv5MOhmBVrBW7hmW -Yqpao2TB9k5UM8Z3/sUcuuVdJcr18JOagxEu5sv4dEX+5wW4q+ffy0vhN4TauYuX -cB7w4ovXsNgOnbFp1iqRe6lJT37mjpXYgyc81WhJDtSd9i7rp77rMKSsH0T8lasz -Bvt9YAretIpjsJyp8qS5UwGH0GikJ3+r/+n6yUA4iGe0OcaEb1fJU9u6ju7AQ7L4 -CYNu/2bPPu8Xs1gYJQk0XuPL1hS27PKSb3TkL4Eq1ZKR4OCXPDJoBYVL0fdX4lId -kxpUnwVwwEpxYB5DC2Ae/qPOgRnhCzU= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw -PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz -cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9 -MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz -IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ -ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR -VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL -kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd -EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas -H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0 -HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud -DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4 -QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu -Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/ -AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8 -yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR -FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA -ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB -kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 -l7+ijrRU ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDoTCCAomgAwIBAgIQKTZHquOKrIZKI1byyrdhrzANBgkqhkiG9w0BAQUFADBO -MQswCQYDVQQGEwJ1czEYMBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQ0wCwYDVQQL -EwRGQkNBMRYwFAYDVQQDEw1Db21tb24gUG9saWN5MB4XDTA3MTAxNTE1NTgwMFoX -DTI3MTAxNTE2MDgwMFowTjELMAkGA1UEBhMCdXMxGDAWBgNVBAoTD1UuUy4gR292 -ZXJubWVudDENMAsGA1UECxMERkJDQTEWMBQGA1UEAxMNQ29tbW9uIFBvbGljeTCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJeNvTMn5K1b+3i9L0dHbsd4 -6ZOcpN7JHP0vGzk4rEcXwH53KQA7Ax9oD81Npe53uCxiazH2+nIJfTApBnznfKM9 -hBiKHa4skqgf6F5PjY7rPxr4nApnnbBnTfAu0DDew5SwoM8uCjR/VAnTNr2kSVdS -c+md/uRIeUYbW40y5KVIZPMiDZKdCBW/YDyD90ciJSKtKXG3d+8XyaK2lF7IMJCk -FEhcVlcLQUwF1CpMP64Sm1kRdXAHImktLNMxzJJ+zM2kfpRHqpwJCPZLr1LoakCR -xVW9QLHIbVeGlRfmH3O+Ry4+i0wXubklHKVSFzYIWcBCvgortFZRPBtVyYyQd+sC -AwEAAaN7MHkwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O -BBYEFC9Yl9ipBZilVh/72at17wI8NjTHMBIGCSsGAQQBgjcVAQQFAgMBAAEwIwYJ -KwYBBAGCNxUCBBYEFHa3YJbdFFYprHWF03BjwbxHhhyLMA0GCSqGSIb3DQEBBQUA -A4IBAQBgrvNIFkBypgiIybxHLCRLXaCRc+1leJDwZ5B6pb8KrbYq+Zln34PFdx80 -CTj5fp5B4Ehg/uKqXYeI6oj9XEWyyWrafaStsU+/HA2fHprA1RRzOCuKeEBuMPdi -4c2Z/FFpZ2wR3bgQo2jeJqVW/TZsN5hs++58PGxrcD/3SDcJjwtCga1GRrgLgwb0 -Gzigf0/NC++DiYeXHIowZ9z9VKEDfgHLhUyxCynDvux84T8PCVI8L6eaSP436REG -WOE2QYrEtr+O3c5Ks7wawM36GpnScZv6z7zyxFSjiDV2zBssRm8MtNHDYXaSdBHq -S4CNHIkRi+xb/xfJSPzn4AYR4oRe ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB -gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV -BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw -MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl -YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P -RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 -UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI -2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 -Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp -+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ -DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O -nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW -/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g -PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u -QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY -SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv -IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ -RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 -zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd -BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB -ZQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL -MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE -BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT -IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw -MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy -ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N -T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR -FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J -cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW -BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm -fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv -GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB -hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV -BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 -MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT -EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR -Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR -6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X -pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC -9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV -/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf -Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z -+pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w -qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah -SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC -u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf -Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq -crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E -FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB -/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl -wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM -4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV -2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna -FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ -CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK -boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke -jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL -S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb -QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl -0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB -NVOFBkpdn627G190 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDkzCCAnugAwIBAgIQFBOWgxRVjOp7Y+X8NId3RDANBgkqhkiG9w0BAQUFADA0 -MRMwEQYDVQQDEwpDb21TaWduIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQG -EwJJTDAeFw0wNDAzMjQxMTMyMThaFw0yOTAzMTkxNTAyMThaMDQxEzARBgNVBAMT -CkNvbVNpZ24gQ0ExEDAOBgNVBAoTB0NvbVNpZ24xCzAJBgNVBAYTAklMMIIBIjAN -BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8ORUaSvTx49qROR+WCf4C9DklBKK -8Rs4OC8fMZwG1Cyn3gsqrhqg455qv588x26i+YtkbDqthVVRVKU4VbirgwTyP2Q2 -98CNQ0NqZtH3FyrV7zb6MBBC11PN+fozc0yz6YQgitZBJzXkOPqUm7h65HkfM/sb -2CEJKHxNGGleZIp6GZPKfuzzcuc3B1hZKKxC+cX/zT/npfo4sdAMx9lSGlPWgcxC -ejVb7Us6eva1jsz/D3zkYDaHL63woSV9/9JLEYhwVKZBqGdTUkJe5DSe5L6j7Kpi -Xd3DTKaCQeQzC6zJMw9kglcq/QytNuEMrkvF7zuZ2SOzW120V+x0cAwqTwIDAQAB -o4GgMIGdMAwGA1UdEwQFMAMBAf8wPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDovL2Zl -ZGlyLmNvbXNpZ24uY28uaWwvY3JsL0NvbVNpZ25DQS5jcmwwDgYDVR0PAQH/BAQD -AgGGMB8GA1UdIwQYMBaAFEsBmz5WGmU2dst7l6qSBe4y5ygxMB0GA1UdDgQWBBRL -AZs+VhplNnbLe5eqkgXuMucoMTANBgkqhkiG9w0BAQUFAAOCAQEA0Nmlfv4pYEWd -foPPbrxHbvUanlR2QnG0PFg/LUAlQvaBnPGJEMgOqnhPOAlXsDzACPw1jvFIUY0M -cXS6hMTXcpuEfDhOZAYnKuGntewImbQKDdSFc8gS4TXt8QUxHXOZDOuWyt3T5oWq -8Ir7dcHyCTxlZWTzTNity4hp8+SDtwy9F1qWF8pb/627HOkthIDYIb6FUtnUdLlp -hbpN7Sgy6/lhSuTENh4Z3G+EER+V9YMoGKgzkkMn3V0TBEVPh9VGzT2ouvDzuFYk -Res3x+F2T3I5GN9+dHLHcy056mDmrRGiVod7w2ia/viMcKjfZTL0pECMocJEAw6U -AGegcQCCSA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGATCCA+mgAwIBAgIRAI9hcRW6eVgXjH0ROqzW264wDQYJKoZIhvcNAQELBQAw -RTEfMB0GA1UEAxMWQ29tU2lnbiBHbG9iYWwgUm9vdCBDQTEVMBMGA1UEChMMQ29t -U2lnbiBMdGQuMQswCQYDVQQGEwJJTDAeFw0xMTA3MTgxMDI0NTRaFw0zNjA3MTYx -MDI0NTVaMEUxHzAdBgNVBAMTFkNvbVNpZ24gR2xvYmFsIFJvb3QgQ0ExFTATBgNV -BAoTDENvbVNpZ24gTHRkLjELMAkGA1UEBhMCSUwwggIiMA0GCSqGSIb3DQEBAQUA -A4ICDwAwggIKAoICAQCyKClzKh3rm6n1nvigmV/VU1D4hSwYW2ro3VqpzpPo0Ph3 -3LguqjXd5juDwN4mpxTpD99d7Xu5X6KGTlMVtfN+bTbA4t3x7DU0Zqn0BE5XuOgs -3GLH41Vmr5wox1bShVpM+IsjcN4E/hMnDtt/Bkb5s33xCG+ohz5dlq0gA9qfr/g4 -O9lkHZXTCeYrmVzd/il4x79CqNvGkdL3um+OKYl8rg1dPtD8UsytMaDgBAopKR+W -igc16QJzCbvcinlETlrzP/Ny76BWPnAQgaYBULax/Q5thVU+N3sEOKp6uviTdD+X -O6i96gARU4H0xxPFI75PK/YdHrHjfjQevXl4J37FJfPMSHAbgPBhHC+qn/014DOx -46fEGXcdw2BFeIIIwbj2GH70VyJWmuk/xLMCHHpJ/nIF8w25BQtkPpkwESL6esaU -b1CyB4Vgjyf16/0nRiCAKAyC/DY/Yh+rDWtXK8c6QkXD2XamrVJo43DVNFqGZzbf -5bsUXqiVDOz71AxqqK+p4ek9374xPNMJ2rB5MLPAPycwI0bUuLHhLy6nAIFHLhut -TNI+6Y/soYpi5JSaEjcY7pxI8WIkUAzr2r+6UoT0vAdyOt7nt1y8844a7szo/aKf -woziHl2O1w6ZXUC30K+ptXVaOiW79pBDcbLZ9ZdbONhS7Ea3iH4HJNwktrBJLQID -AQABo4HrMIHoMA8GA1UdEwEB/wQFMAMBAf8wgYQGA1UdHwR9MHswPKA6oDiGNmh0 -dHA6Ly9mZWRpci5jb21zaWduLmNvLmlsL2NybC9jb21zaWduZ2xvYmFscm9vdGNh -LmNybDA7oDmgN4Y1aHR0cDovL2NybDEuY29tc2lnbi5jby5pbC9jcmwvY29tc2ln -bmdsb2JhbHJvb3RjYS5jcmwwDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBQCRZPY -DUhirGm6rgZbPvuqJpFQsTAfBgNVHSMEGDAWgBQCRZPYDUhirGm6rgZbPvuqJpFQ -sTANBgkqhkiG9w0BAQsFAAOCAgEAk1V5V9701xsfy4mfX+tP9Ln5e9h3N+QMwUfj -kr+k3e8iXOqADjTpUHeBkEee5tJq09ZLp/43F5tZ2eHdYq2ZEX7iWHCnOQet6Yw9 -SU1TahsrGDA6JJD9sdPFnNZooGsU1520e0zNB0dNWwxrWAmu4RsBxvEpWCJbvzQL -dOfyX85RWwli81OiVMBc5XvJ1mxsIIqli45oRynKtsWP7E+b0ISJ1n+XFLdQo/Nm -WA/5sDfT0F5YPzWdZymudMbXitimxC+n4oQE4mbQ4Zm718Iwg3pP9gMMcSc7Qc1J -kJHPH9O7gVubkKHuSYj9T3Ym6c6egL1pb4pz/uT7cT26Fiopc/jdqbe2EAfoJZkv -hlp/zdzOoXTWjiKNA5zmgWnZn943FuE9KMRyKtyi/ezJXCh8ypnqLIKxeFfZl69C -BwJsPXUTuqj8Fic0s3aZmmr7C4jXycP+Q8V+akMEIoHAxcd960b4wVWKqOcI/kZS -Q0cYqWOY1LNjznRt9lweWEfwDBL3FhrHOmD4++1N3FkkM4W+Q1b2WOL24clDMj+i -2n9Iw0lc1llHMSMvA5D0vpsXZpOgcCVahfXczQKi9wQ3oZyonJeWx4/rXdMtagAB -VBYGFuMEUEQtybI+eIbnp5peO2WAAblQI4eTy/jMVowe5tfMEXovV3sz9ULgmGb3 -DscLP1I= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAw -PDEbMBkGA1UEAxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWdu -MQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwx -GzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjEL -MAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGtWhf -HZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs49oh -gHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sW -v+bznkqH7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ue -Mv5WJDmyVIRD9YTC2LxBkMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr -9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d19guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt -6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUwAwEB/zBEBgNVHR8EPTA7 -MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29tU2lnblNl -Y3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58 -ADsAj8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkq -hkiG9w0BAQUFAAOCAQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7p -iL1DRYHjZiM/EoZNGeQFsOY3wo3aBijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtC -dsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtpFhpFfTMDZflScZAmlaxMDPWL -kz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP51qJThRv4zdL -hfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz -OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF -MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD -bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha -ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM -HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 -UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 -tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R -ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM -lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp -/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G -A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G -A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj -dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy -MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl -cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js -L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL -BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni -acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 -o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K -zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 -PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y -Johw1+qRzT65ysCQblrGXnRl11z+o+I= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF -MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD -bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw -NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV -BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn -ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 -3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z -qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR -p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 -HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw -ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea -HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw -Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh -c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E -RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt -dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku -Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp -3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 -nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF -CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na -xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX -KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc -MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj -IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB -IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE -RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl -U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290 -IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU -ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC -QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr -rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S -NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc -QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH -txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP -BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC -AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp -tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa -IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl -6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+ -xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU -Cm26OWMohpLzGITY+9HPBVZkVw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv -b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl -cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c -JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP -mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ -wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 -VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ -AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB -AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW -BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun -pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC -dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf -fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm -NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx -H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe -+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv -b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl -cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA -n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc -biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp -EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA -bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu -YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB -AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW -BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI -QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I -0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni -lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 -B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv -ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo -IhNzbM8m9Yop5w== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw -CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu -ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg -RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV -UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu -Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq -hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf -Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q -RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ -BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD -AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY -JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv -6pZjamVFkpUBtA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD -QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT -MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j -b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB -CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 -nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt -43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P -T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 -gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO -BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR -TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw -DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr -hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg -06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF -PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls -YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk -CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH -MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT -MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j -b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI -2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx -1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ -q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz -tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ -vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP -BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV -5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY -1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 -NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG -Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 -8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe -pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl -MrY= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw -CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu -ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe -Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw -EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x -IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF -K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG -fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO -Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd -BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx -AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ -oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 -sycX ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j -ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 -LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug -RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm -+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW -PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM -xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB -Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 -hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg -EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA -FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec -nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z -eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF -hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 -Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe -vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep -+OkuE6N36B9K ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg -RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV -UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu -Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y -ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If -xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV -ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO -DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ -jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ -CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi -EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM -fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY -uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK -chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t -9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD -ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 -SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd -+SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc -fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa -sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N -cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N -0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie -4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI -r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 -/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm -gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBb -MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3Qx -ETAPBgNVBAsTCERTVCBBQ0VTMRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0w -MzExMjAyMTE5NThaFw0xNzExMjAyMTE5NThaMFsxCzAJBgNVBAYTAlVTMSAwHgYD -VQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UECxMIRFNUIEFDRVMx -FzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPu -ktKe1jzIDZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7 -gLFViYsx+tC3dr5BPTCapCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZH -fAjIgrrep4c9oW24MFbCswKBXy314powGCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4a -ahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPyMjwmR/onJALJfh1biEIT -ajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1UdEwEB/wQF -MAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rk -c3QuY29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjto -dHRwOi8vd3d3LnRydXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMt -aW5kZXguaHRtbDAdBgNVHQ4EFgQUCXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZI -hvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V25FYrnJmQ6AgwbN99Pe7lv7Uk -QIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6tFr8hlxCBPeP/ -h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq -nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpR -rscL9yuwNwXsvFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf2 -9w4LTJxoeHtxMcfrHuBnQfO3oKfN5XozNmr6mis= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ -MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT -DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow -PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD -Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O -rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq -OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b -xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw -7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD -aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV -HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG -SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69 -ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr -AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz -R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 -JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo -Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDOzCCAiOgAwIBAgIRANAeRlAAACmMAAAAAgAAAAIwDQYJKoZIhvcNAQEFBQAw -PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD -Ew5EU1QgUm9vdCBDQSBYNDAeFw0wMDA5MTMwNjIyNTBaFw0yMDA5MTMwNjIyNTBa -MD8xJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjEXMBUGA1UE -AxMORFNUIFJvb3QgQ0EgWDQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQCthX3OFEYY8gSeIYur0O4ypOT68HnDrjLfIutL5PZHRwQGjzCPb9PFo/ihboJ8 -RvfGhBAqpQCo47zwYEhpWm1jB+L/OE/dBBiyn98krfU2NiBKSom2J58RBeAwHGEy -cO+lewyjVvbDDLUy4CheY059vfMjPAftCRXjqSZIolQb9FdPcAoa90mFwB7rKniE -J7vppdrUScSS0+eBrHSUPLdvwyn4RGp+lSwbWYcbg5EpSpE0GRJdchic0YDjvIoC -YHpe7Rkj93PYRTQyU4bhC88ck8tMqbvRYqMRqR+vobbkrj5LLCOQCHV5WEoxWh+0 -E2SpIFe7RkV++MmpIAc0h1tZAgMBAAGjMjAwMA8GA1UdEwEB/wQFMAMBAf8wHQYD -VR0OBBYEFPCD6nPIP1ubWzdf9UyPWvf0hki9MA0GCSqGSIb3DQEBBQUAA4IBAQCE -G85wl5eEWd7adH6XW/ikGN5salvpq/Fix6yVTzE6CrhlP5LBdkf6kx1bSPL18M45 -g0rw2zA/MWOhJ3+S6U+BE0zPGCuu8YQaZibR7snm3HiHUaZNMu5c8D0x0bcMxDjY -AVVcHCoNiL53Q4PLW27nbY6wwG0ffFKmgV3blxrYWfuUDgGpyPwHwkfVFvz9qjaV -mf12VJffL6W8omBPtgteb6UaT/k1oJ7YI0ldGf+ngpVbRhD+LC3cUtT6GO/BEPZu -8YTV/hbiDH5v3khVqMIeKT6o8IuXGG7F6a6vKwP1F1FwTXf4UC/ivhme7vdUH7B/ -Vv4AEbT8dNfEeFxrkDbh ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV -BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC -aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV -BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 -Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz -MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ -BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp -em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN -ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY -B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH -D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF -Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo -q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D -k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH -fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut -dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM -ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 -zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn -rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX -U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 -Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 -XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF -Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR -HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY -GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c -77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 -+GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK -vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 -FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl -yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P -AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD -y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d -NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIE5zCCA8+gAwIBAgIBADANBgkqhkiG9w0BAQUFADCBjTELMAkGA1UEBhMCQ0Ex -EDAOBgNVBAgTB09udGFyaW8xEDAOBgNVBAcTB1Rvcm9udG8xHTAbBgNVBAoTFEVj -aG93b3J4IENvcnBvcmF0aW9uMR8wHQYDVQQLExZDZXJ0aWZpY2F0aW9uIFNlcnZp -Y2VzMRowGAYDVQQDExFFY2hvd29yeCBSb290IENBMjAeFw0wNTEwMDYxMDQ5MTNa -Fw0zMDEwMDcxMDQ5MTNaMIGNMQswCQYDVQQGEwJDQTEQMA4GA1UECBMHT250YXJp -bzEQMA4GA1UEBxMHVG9yb250bzEdMBsGA1UEChMURWNob3dvcnggQ29ycG9yYXRp -b24xHzAdBgNVBAsTFkNlcnRpZmljYXRpb24gU2VydmljZXMxGjAYBgNVBAMTEUVj -aG93b3J4IFJvb3QgQ0EyMIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEA -utU/5BkV15UBf+s+JQruKQxr77s3rjp/RpOtmhHILIiO5gsEWP8MMrfrVEiidjI6 -Qh6ans0KAWc2Dw0/j4qKAQzOSyAZgjcdypNTBZ7muv212DA2Pu41rXqwMrlBrVi/ -KTghfdLlNRu6JrC5y8HarrnRFSKF1Thbzz921kLDRoCi+FVs5eVuK5LvIfkhNAqA -byrTgO3T9zfZgk8upmEkANPDL1+8y7dGPB/d6lk0I5mv8PESKX02TlvwgRSIiTHR -k8++iOPLBWlGp7ZfqTEXkPUZhgrQQvxcrwCUo6mk8TqgxCDP5FgPoHFiPLef5szP -ZLBJDWp7GLyE1PmkQI6WiwIBA6OCAVAwggFMMA8GA1UdEwEB/wQFMAMBAf8wCwYD -VR0PBAQDAgEGMB0GA1UdDgQWBBQ74YEboKs/OyGC1eISrq5QqxSlEzCBugYDVR0j -BIGyMIGvgBQ74YEboKs/OyGC1eISrq5QqxSlE6GBk6SBkDCBjTELMAkGA1UEBhMC -Q0ExEDAOBgNVBAgTB09udGFyaW8xEDAOBgNVBAcTB1Rvcm9udG8xHTAbBgNVBAoT -FEVjaG93b3J4IENvcnBvcmF0aW9uMR8wHQYDVQQLExZDZXJ0aWZpY2F0aW9uIFNl -cnZpY2VzMRowGAYDVQQDExFFY2hvd29yeCBSb290IENBMoIBADBQBgNVHSAESTBH -MEUGCysGAQQB+REKAQMBMDYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuZWNob3dv -cnguY29tL2NhL3Jvb3QyL2Nwcy5wZGYwDQYJKoZIhvcNAQEFBQADggEBAG+nrPi/ -0RpfEzrj02C6JGPUar4nbjIhcY6N7DWNeqBoUulBSIH/PYGNHYx7/lnJefiixPGE -7TQ5xPgElxb9bK8zoAApO7U33OubqZ7M7DlHnFeCoOoIAZnG1kuwKwD5CXKB2a74 -HzcqNnFW0IsBFCYqrVh/rQgJOzDA8POGbH0DeD0xjwBBooAolkKT+7ZItJF1Pb56 -QpDL9G+16F7GkmnKlAIYT3QTS3yFGYChnJcd+6txUPhKi9sSOOmAIaKHnkH9Scz+ -A2cSi4A3wUYXVatuVNHpRb2lygfH3SuCX9MU8Ure3zBlSU1LALtMqI4JmcQmQpIq -zIzvO2jHyu9PQqo= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1 -MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1 -czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG -CSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy -MTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl -ZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS -b290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy -euuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO -bntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw -WFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d -MtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE -1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD -VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/ -zQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB -BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF -BQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV -v9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG -E5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u -uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW -iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v -GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG -A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 -d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu -dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq -RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy -MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD -VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 -L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g -Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD -ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi -A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt -ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH -Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O -BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC -R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX -hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC -VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 -cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs -IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz -dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy -NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu -dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt -dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 -aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T -RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN -cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW -wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 -U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 -jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP -BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN -BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ -jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ -Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v -1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R -nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH -VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC -VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 -Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW -KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl -cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw -NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw -NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy -ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV -BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ -KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo -Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 -4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 -KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI -rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi -94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB -sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi -gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo -kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE -vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA -A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t -O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua -AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP -9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ -eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m -0vdXcDazv/wor3ElhVsT/h5/WrQ8 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML -RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp -bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 -IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0xOTEy -MjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 -LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp -YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG -A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq -K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe -sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX -MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT -XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ -HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH -4QIDAQABo3QwcjARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGA -vtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJFrlwMB0G -CSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA -WUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo -oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQ -h7A6tcOdBTcSo8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18 -f3v/rxzP5tsHrV7bhZ3QKw0z2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfN -B/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVy -vUxFnmG6v4SBkgPR0ml8xQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML -RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp -bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 -IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 -MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 -LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp -YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG -A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq -K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe -sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX -MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT -XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ -HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH -4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub -j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo -U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf -zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b -u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ -bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er -fF6adulZkMV8gzURZVE= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe -MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 -ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe -Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw -IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL -SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH -SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh -ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X -DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 -TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ -fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA -sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU -WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS -nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH -dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip -NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC -AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF -MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH -ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB -uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl -PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP -JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ -gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 -j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 -5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB -o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS -/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z -Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE -W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D -hNQ+IIX3Sj0rnP0qCglN6oH4EZw= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEYDCCA0igAwIBAgICATAwDQYJKoZIhvcNAQELBQAwWTELMAkGA1UEBhMCVVMx -GDAWBgNVBAoTD1UuUy4gR292ZXJubWVudDENMAsGA1UECxMERlBLSTEhMB8GA1UE -AxMYRmVkZXJhbCBDb21tb24gUG9saWN5IENBMB4XDTEwMTIwMTE2NDUyN1oXDTMw -MTIwMTE2NDUyN1owWTELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD1UuUy4gR292ZXJu -bWVudDENMAsGA1UECxMERlBLSTEhMB8GA1UEAxMYRmVkZXJhbCBDb21tb24gUG9s -aWN5IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2HX7NRY0WkG/ -Wq9cMAQUHK14RLXqJup1YcfNNnn4fNi9KVFmWSHjeavUeL6wLbCh1bI1FiPQzB6+ -Duir3MPJ1hLXp3JoGDG4FyKyPn66CG3G/dFYLGmgA/Aqo/Y/ISU937cyxY4nsyOl -4FKzXZbpsLjFxZ+7xaBugkC7xScFNknWJidpDDSPzyd6KgqjQV+NHQOGgxXgVcHF -mCye7Bpy3EjBPvmE0oSCwRvDdDa3ucc2Mnr4MrbQNq4iGDGMUHMhnv6DOzCIJOPp -wX7e7ZjHH5IQip9bYi+dpLzVhW86/clTpyBLqtsgqyFOHQ1O5piF5asRR12dP8Qj -wOMUBm7+nQIDAQABo4IBMDCCASwwDwYDVR0TAQH/BAUwAwEB/zCB6QYIKwYBBQUH -AQsEgdwwgdkwPwYIKwYBBQUHMAWGM2h0dHA6Ly9odHRwLmZwa2kuZ292L2ZjcGNh -L2NhQ2VydHNJc3N1ZWRCeWZjcGNhLnA3YzCBlQYIKwYBBQUHMAWGgYhsZGFwOi8v -bGRhcC5mcGtpLmdvdi9jbj1GZWRlcmFsJTIwQ29tbW9uJTIwUG9saWN5JTIwQ0Es -b3U9RlBLSSxvPVUuUy4lMjBHb3Zlcm5tZW50LGM9VVM/Y0FDZXJ0aWZpY2F0ZTti -aW5hcnksY3Jvc3NDZXJ0aWZpY2F0ZVBhaXI7YmluYXJ5MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUrQx6dVzl85jEeZgOrCj9l/TnAvwwDQYJKoZIhvcNAQELBQAD -ggEBAI9z2uF/gLGH9uwsz9GEYx728Yi3mvIRte9UrYpuGDco71wb5O9Qt2wmGCMi -TR0mRyDpCZzicGJxqxHPkYnos/UqoEfAFMtOQsHdDA4b8Idb7OV316rgVNdF9IU+ -7LQd3nyKf1tNnJaK0KIyn9psMQz4pO9+c+iR3Ah6cFqgr2KBWfgAdKLI3VTKQVZH -venAT+0g3eOlCd+uKML80cgX2BLHb94u6b2akfI8WpQukSKAiaGMWMyDeiYZdQKl -Dn0KJnNR6obLB6jI/WNaNZvSr79PMUjBhHDbNXuaGQ/lj/RqDG8z2esccKIN47lQ -A2EC/0rskqTcLe4qNJMHtyznGI8= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT -MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i -YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG -EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg -R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 -9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq -fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv -iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU -1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ -bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW -MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA -ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l -uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn -Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS -tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF -PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un -hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV -5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL -MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj -KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 -MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 -eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV -BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw -NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV -BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH -MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL -So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal -tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO -BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG -CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT -qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz -rD6ogRLQy7rQkgu2npaqBA+K ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB -mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT -MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s -eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv -cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ -BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg -MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0 -BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg -LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz -+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm -hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn -5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W -JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL -DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC -huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw -HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB -AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB -zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN -kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD -AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH -SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G -spki4cErx5z481+oghLrGREt ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY -MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo -R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx -MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK -Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9 -AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA -ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0 -7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W -kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI -mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G -A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ -KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1 -6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl -4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K -oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj -UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU -AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD -VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 -IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 -MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD -aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx -MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy -cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG -A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl -BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI -hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed -KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7 -G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2 -zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4 -ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG -HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2 -Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V -yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e -beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r -6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh -wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog -zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW -BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr -ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp -ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk -cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt -YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC -CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow -KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI -hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ -UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz -X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x -fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz -a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd -Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd -SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O -AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso -M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge -v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z -09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEn -MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL -ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENo -YW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYxNDE4WhcNMzcwOTMwMTYxNDE4WjB9 -MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgy -NzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4G -A1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUA -A4IBDQAwggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0 -Mi+ITaFgCPS3CU6gSS9J1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/s -QJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8Oby4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpV -eAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl6DJWk0aJqCWKZQbua795 -B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c8lCrEqWh -z0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0T -AQH/BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1i -ZXJzaWduLm9yZy9jaGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4w -TcbOX60Qq+UDpfqpFDAOBgNVHQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAH -MCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBjaGFtYmVyc2lnbi5vcmcwKgYD -VR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9yZzBbBgNVHSAE -VDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh -bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0B -AQUFAAOCAQEAPDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUM -bKGKfKX0j//U2K0X1S0E0T9YgOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXi -ryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJPJ7oKXqJ1/6v/2j1pReQvayZzKWG -VwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4IBHNfTIzSJRUTN3c -ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/ -AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG -A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv -b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw -MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i -YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT -aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ -jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp -xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp -1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG -snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ -U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 -9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E -BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B -AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz -yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE -38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP -AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad -DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME -HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk -MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH -bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX -DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD -QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ -FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw -DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F -uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX -kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs -ewv4n4Q= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk -MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH -bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX -DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD -QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu -MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc -8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke -hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI -KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg -515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO -xwy8p2Fp8fc74SrL+SvzZpA3 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G -A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp -Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 -MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG -A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL -v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 -eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq -tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd -C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa -zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB -mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH -V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n -bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG -3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs -J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO -291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS -ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd -AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 -TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G -A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp -Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 -MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG -A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 -RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT -gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm -KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd -QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ -XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw -DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o -LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU -RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp -jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK -6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX -mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs -Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH -WD9f ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh -MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE -YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 -MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo -ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg -MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN -ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA -PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w -wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi -EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY -avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ -YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE -sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h -/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 -IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD -ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy -OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P -TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ -HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER -dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf -ReYNnyicsbkqWletNw+vHX/bvZ8= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT -EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp -ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz -NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH -EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE -AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw -DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD -E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH -/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy -DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh -GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR -tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA -AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE -FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX -WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu -9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr -gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo -2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO -LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI -4uJEvlz36hz1 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFSzCCAzOgAwIBAgIRALZLiAfiI+7IXBKtpg4GofIwDQYJKoZIhvcNAQELBQAw -PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eTAeFw0xMjA5MjgwODU4NTFaFw0zNzEyMzExNTU5NTla -MD8xCzAJBgNVBAYTAlRXMTAwLgYDVQQKDCdHb3Zlcm5tZW50IFJvb3QgQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC -AQC2/5c8gb4BWCQnr44BK9ZykjAyG1+bfNTUf+ihYHMwVxAA+lCWJP5Q5ow6ldFX -eYTVZ1MMKoI+GFy4MCYa1l7GLbIEUQ7v3wxjR+vEEghRK5lxXtVpe+FdyXcdIOxW -juVhYC386RyA3/pqg7sFtR4jEpyCygrzFB0g5AaPQySZn7YKk1pzGxY5vgW28Yyl -ZJKPBeRcdvc5w88tvQ7Yy6gOMZvJRg9nU0MEj8iyyIOAX7ryD6uBNaIgIZfOD4k0 -eA/PH07p+4woPN405+2f0mb1xcoxeNLOUNFggmOd4Ez3B66DNJ1JSUPUfr0t4urH -cWWACOQ2nnlwCjyHKenkkpTqBpIpJ3jmrdc96QoLXvTg1oadLXLLi2RW5vSueKWg -OTNYPNyoj420ai39iHPplVBzBN8RiD5C1gJ0+yzEb7xs1uCAb9GGpTJXA9ZN9E4K -mSJ2fkpAgvjJ5E7LUy3Hsbbi08J1J265DnGyNPy/HE7CPfg26QrMWJqhGIZO4uGq -s3NZbl6dtMIIr69c/aQCb/+4DbvVq9dunxpPkUDwH0ZVbaCSw4nNt7H/HLPLo5wK -4/7NqrwB7N1UypHdTxOHpPaY7/1J1lcqPKZc9mA3v9g+fk5oKiMyOr5u5CI9ByTP -isubXVGzMNJxbc5Gim18SjNE2hIvNkvy6fFRCW3bapcOFwIDAQABo0IwQDAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBTVZx3gnHosnMvFmOcdByYqhux0zTAOBgNV -HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAJA75cJTQijq9TFOjj2Rnk0J -89ixUuZPrAwxIbvx6pnMg/y2KOTshAcOD06Xu29oRo8OURWV+Do7H1+CDgxxDryR -T64zLiNB9CZrTxOH+nj2LsIPkQWXqmrBap+8hJ4IKifd2ocXhuGzyl3tOKkpboTe -Rmv8JxlQpRJ6jH1i/NrnzLyfSa8GuCcn8on3Fj0Y5r3e9YwSkZ/jBI3+BxQaWqw5 -ghvxOBnhY+OvbLamURfr+kvriyL2l/4QOl+UoEtTcT9a4RD4co+WgN2NApgAYT2N -vC2xR8zaXeEgp4wxXPHj2rkKhkfIoT0Hozymc26Uke1uJDr5yTDRB6iBfSZ9fYTf -hsmL5a4NHr6JSFEVg5iWL0rrczTXdM3Jb9DCuiv2mv6Z3WAUjhv5nDk8f0OJU+jl -wqu+Iq0nOJt3KLejY2OngeepaUXrjnhWzAWEx/uttjB8YwWfLYwkf0uLkvw4Hp+g -pVezbp3YZLhwmmBScMip0P/GnO0QYV7Ngw5u6E0CQUridgR51lQ/ipgyFKDdLZzn -uoJxo4ZVKZnSKdt1OvfbQ/+2W/u3fjWAjg1srnm3Ni2XUqGwB5wH5Ss2zQOXlL0t -DjQG/MAWifw3VOTWzz0TBPKR2ck2Lj7FWtClTILD/y58Jnb38/1FoqVuVa4uzM8s -iTTa9g3nkagQ6hed8vbs ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix -RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 -dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p -YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw -NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK -EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl -cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl -c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz -dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ -fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns -bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD -75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP -FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV -HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp -5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu -b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA -A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p -6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 -TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7 -dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys -Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI -l7WdmplNsDz4SgCbZN2fOUvRJ9e4 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx -FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg -Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG -A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr -b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ -jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn -PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh -ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9 -nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h -q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED -MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC -mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3 -7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB -oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs -EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO -fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi -AmvZWg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFHjCCBAagAwIBAgIEAKA3oDANBgkqhkiG9w0BAQsFADCBtzELMAkGA1UEBhMC -Q1oxOjA4BgNVBAMMMUkuQ0EgLSBRdWFsaWZpZWQgQ2VydGlmaWNhdGlvbiBBdXRo -b3JpdHksIDA5LzIwMDkxLTArBgNVBAoMJFBydm7DrSBjZXJ0aWZpa2HEjW7DrSBh -dXRvcml0YSwgYS5zLjE9MDsGA1UECww0SS5DQSAtIEFjY3JlZGl0ZWQgUHJvdmlk -ZXIgb2YgQ2VydGlmaWNhdGlvbiBTZXJ2aWNlczAeFw0wOTA5MDEwMDAwMDBaFw0x -OTA5MDEwMDAwMDBaMIG3MQswCQYDVQQGEwJDWjE6MDgGA1UEAwwxSS5DQSAtIFF1 -YWxpZmllZCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSwgMDkvMjAwOTEtMCsGA1UE -CgwkUHJ2bsOtIGNlcnRpZmlrYcSNbsOtIGF1dG9yaXRhLCBhLnMuMT0wOwYDVQQL -DDRJLkNBIC0gQWNjcmVkaXRlZCBQcm92aWRlciBvZiBDZXJ0aWZpY2F0aW9uIFNl -cnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtTaEy0KC8M9l -4lSaWHMs4+sVV1LwzyJYiIQNeCrv1HHm/YpGIdY/Z640ceankjQvIX7m23BK4OSC -6KO8kZYA3zopOz6GFCOKV2PvLukbc+c2imF6kLHEv6qNA8WxhPbR3xKwlHDwB2yh -Wzo7V3QVgDRG83sugqQntKYC3LnlTGbJpNP+Az72gpO9AHUn/IBhFk4ksc8lYS2L -9GCy9CsmdKSBP78p9w8Lx7vDLqkDgt1/zBrcUWmSSb7AE/BPEeMryQV1IdI6nlGn -BhWkXOYf6GSdayJw86btuxC7viDKNrbp44HjQRaSxnp6O3eto1x4DfiYdw/YbJFe -7EjkxSQBywIDAQABo4IBLjCCASowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E -BAMCAQYwgecGA1UdIASB3zCB3DCB2QYEVR0gADCB0DCBzQYIKwYBBQUHAgIwgcAa -gb1UZW50byBjZXJ0aWZpa2F0IGplIHZ5ZGFuIGpha28ga3ZhbGlmaWtvdmFueSBz -eXN0ZW1vdnkgY2VydGlmaWthdCBwb2RsZSB6YWtvbmEgYy4gMjI3LzIwMDAgU2Iu -IHYgcGxhdG5lbSB6bmVuaS9UaGlzIGlzIHF1YWxpZmllZCBzeXN0ZW0gY2VydGlm -aWNhdGUgYWNjb3JkaW5nIHRvIEN6ZWNoIEFjdCBOby4gMjI3LzIwMDAgQ29sbC4w -HQYDVR0OBBYEFHnL0CPpOmdwkXRP01Hi4CD94Sj7MA0GCSqGSIb3DQEBCwUAA4IB -AQB9laU214hYaBHPZftbDS/2dIGLWdmdSbj1OZbJ8LIPBMxYjPoEMqzAR74tw96T -i6aWRa5WdOWaS6I/qibEKFZhJAVXX5mkx2ewGFLJ+0Go+eTxnjLOnhVF2V2s+57b -m8c8j6/bS6Ij6DspcHEYpfjjh64hE2r0aSpZDjGzKFM6YpqsCJN8qYe2X1qmGMLQ -wvNdjG+nPzCJOOuUEypIWt555ZDLXqS5F7ZjBjlfyDZjEfS2Es9Idok8alf563Mi -9/o+Ba46wMYOkk3P1IlU0RqCajdbliioACKDztAqubONU1guZVzV8tuMASVzbJeL -/GAB7ECTwe1RuKrLYtglMKI9 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK -MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu -VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw -MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw -JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT -3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU -+ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp -S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 -bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi -T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL -vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK -Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK -dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT -c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv -l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N -iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD -ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH -6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt -LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 -nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 -+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK -W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT -AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq -l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG -4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ -mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A -7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN -MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu -VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN -MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 -MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 -ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy -RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS -bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF -/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R -3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw -EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy -9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V -GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ -2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV -WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD -W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN -AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj -t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV -DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 -TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G -lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW -mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df -WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 -+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ -tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA -GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv -8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw -TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh -cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 -WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu -ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY -MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc -h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ -0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U -A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW -T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH -B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC -B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv -KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn -OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn -jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw -qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI -rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq -hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL -ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ -3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK -NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 -ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur -TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC -jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc -oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq -4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA -mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d -emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEXzCCA0egAwIBAgIBATANBgkqhkiG9w0BAQUFADCB0DELMAkGA1UEBhMCRVMx -SDBGBgNVBAoTP0laRU5QRSBTLkEuIC0gQ0lGIEEtMDEzMzcyNjAtUk1lcmMuVml0 -b3JpYS1HYXN0ZWl6IFQxMDU1IEY2MiBTODFCMEAGA1UEBxM5QXZkYSBkZWwgTWVk -aXRlcnJhbmVvIEV0b3JiaWRlYSAzIC0gMDEwMTAgVml0b3JpYS1HYXN0ZWl6MRMw -EQYDVQQDEwpJemVucGUuY29tMR4wHAYJKoZIhvcNAQkBFg9JbmZvQGl6ZW5wZS5j -b20wHhcNMDMwMTMwMjMwMDAwWhcNMTgwMTMwMjMwMDAwWjCB0DELMAkGA1UEBhMC -RVMxSDBGBgNVBAoTP0laRU5QRSBTLkEuIC0gQ0lGIEEtMDEzMzcyNjAtUk1lcmMu -Vml0b3JpYS1HYXN0ZWl6IFQxMDU1IEY2MiBTODFCMEAGA1UEBxM5QXZkYSBkZWwg -TWVkaXRlcnJhbmVvIEV0b3JiaWRlYSAzIC0gMDEwMTAgVml0b3JpYS1HYXN0ZWl6 -MRMwEQYDVQQDEwpJemVucGUuY29tMR4wHAYJKoZIhvcNAQkBFg9JbmZvQGl6ZW5w -ZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1btoCXXhp3xIW -D+Bxl8nUCxkyiazWfpt0e68t+Qt9+lZjKZSdEw2Omj4qvr+ovRmDXO3iWpWVOWDl -3JHJjAzFCe8ZEBNDH+QNYwZHmPBaMYFOYFdbAFVHWvys152C308hcFJ6xWWGmjvl -2eMiEl9P2nR2LWue368DCu+ak7j3gjAXaCOdP1a7Bfr+RW3X2SC5R4Xyp8iHlL5J -PHJD/WBkLrezwzQPdACw8m9EG7q9kUwlNpL32mROujS3ZkT6mQTzJieLiE3X04s0 -uIUqVkk5MhjcHFf7al0N5CzjtTcnXYJKN2Z9EDVskk4olAdGi46eSoZXbjUOP5gk -Ej6wVZAXAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG -MB0GA1UdDgQWBBTqVk/sPIOhFIh4gbIrBSLAB0FbQjANBgkqhkiG9w0BAQUFAAOC -AQEAYp7mEzzhw6o5Hf5+T5kcI+t4BJyiIWy7vHlLs/G8dLYXO81aN/Mzg928eMTR -TxxYZL8dd9uwsJ50TVfX6L0R4Dyw6wikh3fHRrat9ufXi63j5K91Ysr7aXqnF38d -iAgHYkrwC3kuxHBb9C0KBz6h8Q45/KCyN7d37wWAq38yyhPDlaOvyoE6bdUuK5hT -m5EYA5JmPyrhQ1moDOyueWBAjxzMEMj+OAY1H90cLv6wszsqerxRrdTOHBdv7MjB -EIpvEEQkXUxVXAzFuuT6m2t91Lfnwfl/IvljHaVC7DlyyhRYHD6D4Rx+4QKp4tWL -vpw6LkI+gKNJ/YdMCsRZQzEEFA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF8DCCA9igAwIBAgIPBuhGJy8fCo/RhFzjafbVMA0GCSqGSIb3DQEBBQUAMDgx -CzAJBgNVBAYTAkVTMRQwEgYDVQQKDAtJWkVOUEUgUy5BLjETMBEGA1UEAwwKSXpl -bnBlLmNvbTAeFw0wNzEyMTMxMzA4MjdaFw0zNzEyMTMwODI3MjVaMDgxCzAJBgNV -BAYTAkVTMRQwEgYDVQQKDAtJWkVOUEUgUy5BLjETMBEGA1UEAwwKSXplbnBlLmNv -bTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMnTesoPHqynhugWZWqx -whtFMnGV2f4QW8yv56V5AY+Jw8ryVXH3d753lPNypCxE2J6SmxQ6oeckkAoKVo7F -2CaU4dlI4S0+2gpy3aOZFdqBoof0e24md4lYrdbrDLJBenNubdt6eEHpCIgSfocu -ZhFjbFT7PJ1ywLwu/8K33Q124zrX97RovqL144FuwUZvXY3gTcZUVYkaMzEKsVe5 -o4qYw+w7NMWVQWl+dcI8IMVhulFHoCCQk6GQS/NOfIVFVJrRBSZBsLVNHTO+xAPI -JXzBcNs79AktVCdIrC/hxKw+yMuSTFM5NyPs0wH54AlETU1kwOENWocivK0bo/4m -tRXzp/yEGensoYi0RGmEg/OJ0XQGqcwL1sLeJ4VQJsoXuMl6h1YsGgEebL4TrRCs -tST1OJGh1kva8bvS3ke18byB9llrzxlT6Y0Vy0rLqW9E5RtBz+GGp8rQap+8TI0G -M1qiheWQNaBiXBZO8OOi+gMatCxxs1gs3nsL2xoP694hHwZ3BgOwye+Z/MC5TwuG -KP7Suerj2qXDR2kS4Nvw9hmL7Xtw1wLW7YcYKCwEJEx35EiKGsY7mtQPyvp10gFA -Wo15v4vPS8+qFsGV5K1Mij4XkdSxYuWC5YAEpAN+jb/af6IPl08M0w3719Hlcn4c -yHf/W5oPt64FRuXxqBbsR6QXAgMBAAGjgfYwgfMwgbAGA1UdEQSBqDCBpYEPaW5m -b0BpemVucGUuY29tpIGRMIGOMUcwRQYDVQQKDD5JWkVOUEUgUy5BLiAtIENJRiBB -MDEzMzcyNjAtUk1lcmMuVml0b3JpYS1HYXN0ZWl6IFQxMDU1IEY2MiBTODFDMEEG -A1UECQw6QXZkYSBkZWwgTWVkaXRlcnJhbmVvIEV0b3JiaWRlYSAxNCAtIDAxMDEw -IFZpdG9yaWEtR2FzdGVpejAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUHRxlDqjyJXu0kc/ksbHmvVV0bAUwDQYJKoZIhvcNAQEFBQAD -ggIBAMeBRm8hGE+gBe/n1bqXUKJg7aWSFBpSm/nxiEqg3Hh10dUflU7F57dp5iL0 -+CmoKom+z892j+Mxc50m0xwbRxYpB2iEitL7sRskPtKYGCwkjq/2e+pEFhsqxPqg -l+nqbFik73WrAGLRne0TNtsiC7bw0fRue0aHwp28vb5CO7dz0JoqPLRbEhYArxk5 -ja2DUBzIgU+9Ag89njWW7u/kwgN8KRwCfr00J16vU9adF79XbOnQgxCvv11N75B7 -XSus7Op9ACYXzAJcY9cZGKfsK8eKPlgOiofmg59OsjQerFQJTx0CCzl+gQgVuaBp -E8gyK+OtbBPWg50jLbJtooiGfqgNASYJQNntKE6MkyQP2/EeTXp6WuKlWPHcj1+Z -ggwuz7LdmMySlD/5CbOlliVbN/UShUHiGUzGigjB3Bh6Dx4/glmimj4/+eAJn/3B -kUtdyXvWton83x18hqrNA/ILUpLxYm9/h+qrdslsUMIZgq+qHfUgKGgu1fxkN0/P -pUTEvnK0jHS0bKf68r10OEMr3q/53NjgnZ/cPcqlY0S/kqJPTIAcuxrDmkoEVU3K -7iYLHL8CxWTTnn7S05EcS6L1HOUXHA0MUqORH5zwIe0ClG+poEnK6EOMxPQ02nwi -o8ZmPrgbBYhdurz3vOXcFD2nhqi2WVIhA16L4wTtSyoeo09Q ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4 -MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6 -ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD -VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j -b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq -scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO -xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H -LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX -uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD -yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+ -JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q -rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN -BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L -hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB -QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+ -HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu -Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg -QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB -BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx -MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA -A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb -laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56 -awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo -JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw -LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT -VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk -LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb -UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/ -QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+ -naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls -QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDczCCAlugAwIBAgIBBDANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJLUjEN -MAsGA1UECgwES0lTQTEuMCwGA1UECwwlS29yZWEgQ2VydGlmaWNhdGlvbiBBdXRo -b3JpdHkgQ2VudHJhbDEWMBQGA1UEAwwNS0lTQSBSb290Q0EgMTAeFw0wNTA4MjQw -ODA1NDZaFw0yNTA4MjQwODA1NDZaMGQxCzAJBgNVBAYTAktSMQ0wCwYDVQQKDARL -SVNBMS4wLAYDVQQLDCVLb3JlYSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBDZW50 -cmFsMRYwFAYDVQQDDA1LSVNBIFJvb3RDQSAxMIIBIDANBgkqhkiG9w0BAQEFAAOC -AQ0AMIIBCAKCAQEAvATk+hM58DSWIGtsaLv623f/J/es7C/n/fB/bW+MKs0lCVsk -9KFo/CjsySXirO3eyDOE9bClCTqnsUdIxcxPjHmc+QZXfd3uOPbPFLKc6tPAXXdi -8EcNuRpAU1xkcK8IWsD3z3X5bI1kKB4g/rcbGdNaZoNy4rCbvdMlFQ0yb2Q3lIVG -yHK+d9VuHygvx2nt54OJM1jT3qC/QOhDUO7cTWu8peqmyGGO9cNkrwYV3CmLP3WM -vHFE2/yttRcdbYmDz8Yzvb9Fov4Kn6MRXw+5H5wawkbMnChmn3AmPC7fqoD+jMUE -CSVPzZNHPDfqAmeS/vwiJFys0izgXAEzisEZ2wIBA6MyMDAwHQYDVR0OBBYEFL+2 -J9gDWnZlTGEBQVYx5Yt7OtnMMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEF -BQADggEBABOvUQveimpb5poKyLGQSk6hAp3MiNKrZr097LuxQpVqslxa/6FjZJap -aBV/JV6K+KRzwYCKhQoOUugy50X4TmWAkZl0Q+VFnUkq8JSV3enhMNITbslOsXfl -BM+tWh6UCVrXPAgcrnrpFDLBRa3SJkhyrKhB2vAhhzle3/xk/2F0KpzZm4tfwjeT -2KM3LzuTa7IbB6d/CVDv0zq+IWuKkDsnSlFOa56ch534eJAx7REnxqhZvvwYC/uO -fi5C4e3nCSG9uRPFVmf0JqZCQ5BEVLRxm3bkGhKsGigA35vB1fjbXKP4krG9tNT5 -UNkAAk/bg9ART6RCVmE6fhMy04Qfybo= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD -VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 -ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G -CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y -OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx -FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp -Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o -dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP -kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc -cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U -fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 -N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC -xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 -+rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G -A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM -Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG -SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h -mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk -ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 -tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c -2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t -HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG -EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 -MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl -cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR -dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB -pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM -b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm -aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz -IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT -lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz -AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 -VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG -ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 -BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG -AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M -U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh -bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C -+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC -bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F -uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 -XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi -MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu -MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp -dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV -UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO -ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz -c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP -OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl -mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF -BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 -qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw -gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB -BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu -bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp -dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 -6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ -h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH -/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv -wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN -pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB -ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly -aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl -ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w -NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G -A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD -VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX -SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR -VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2 -w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF -mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg -4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9 -4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw -DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw -EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx -SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2 -ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8 -vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa -hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi -Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ -/L7fCg0= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt -MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg -Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i -YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x -CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG -b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh -bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 -HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx -WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX -1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk -u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P -99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r -M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB -BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh -cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 -gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO -ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf -aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic -Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 -MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV -wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe -rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 -68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh -4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp -UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o -abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc -3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G -KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt -hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO -Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt -zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD -ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC -MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 -cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN -qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 -YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv -b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 -8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k -NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj -ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp -q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt -nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 -MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf -qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW -n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym -c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ -O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 -o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j -IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq -IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz -8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh -vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l -7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG -cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD -ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 -AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC -roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga -W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n -lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE -+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV -csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd -dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg -KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM -HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 -WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x -GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv -b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV -BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W -YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa -GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg -Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J -WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB -rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp -+ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 -ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i -Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz -PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og -/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH -oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI -yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud -EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 -A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL -MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT -ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f -BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn -g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl -fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K -WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha -B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc -hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR -TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD -mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z -ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y -4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza -8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 -MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR -/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu -FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR -U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c -ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR -FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k -A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw -eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl -sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp -VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q -A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ -ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD -ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px -KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI -FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv -oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg -u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP -0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf -3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl -8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ -DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN -PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ -ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x -GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv -b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV -BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W -YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM -V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB -4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr -H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd -8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv -vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT -mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe -btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc -T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt -WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ -c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A -4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD -VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG -CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 -aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 -aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu -dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw -czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G -A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC -TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg -Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 -7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem -d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd -+LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B -4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN -t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x -DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 -k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s -zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j -Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT -mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK -4SVhM7JZG+Ju1zdXtg2pEto= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC -TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0 -aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0 -aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz -MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw -IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR -dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp -li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D -rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ -WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug -F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU -xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC -Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv -dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw -ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl -IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh -c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy -ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh -Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI -KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T -KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq -y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p -dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD -VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL -MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk -fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8 -7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R -cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y -mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW -xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK -SnQ2+Q== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK -MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x -GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx -MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg -Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ -iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa -/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ -jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI -HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 -sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w -gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw -KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG -AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L -URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO -H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm -I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY -iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc -f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI -MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x -FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz -MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv -cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN -AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz -Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO -0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao -wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj -7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS -8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT -BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB -/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg -JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC -NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 -6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ -3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm -D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS -CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR -3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDEl -MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMh -U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIz -MloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09N -IFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNlY3VyaXR5IENvbW11 -bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSE -RMqm4miO/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gO -zXppFodEtZDkBp2uoQSXWHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5 -bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4zZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDF -MxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4bepJz11sS6/vmsJWXMY1 -VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK9U2vP9eC -OKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G -CSqGSIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HW -tWS3irO4G8za+6xmiEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZ -q51ihPZRwSzJIxXYKLerJRO1RuGGAv8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDb -EJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnWmHyojf6GPgcWkuF75x3sM3Z+ -Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEWT1MKZPlO9L9O -VL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY -MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t -dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 -WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD -VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 -9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ -DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 -Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N -QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ -xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G -A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T -AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG -kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr -Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 -Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU -JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot -RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl -MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe -U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX -DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy -dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj -YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV -OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr -zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM -VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ -hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO -ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw -awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs -OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 -DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF -coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc -okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 -t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy -1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ -SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP -MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx -MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV -BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o -Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt -5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s -3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej -vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu -8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw -DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG -MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil -zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/ -3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD -FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6 -Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2 -ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO -TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh -dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y -MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg -TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS -b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS -M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC -UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d -Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p -rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l -pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb -j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC -KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS -/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X -cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH -1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP -px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB -/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 -MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI -eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u -2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS -v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC -wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy -CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e -vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 -Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa -Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL -eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 -FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc -7uzXLg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO -TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh -dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oX -DTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl -ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv -b3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ5291 -qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8Sp -uOUfiUtnvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPU -Z5uW6M7XxgpT0GtJlvOjCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvE -pMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiile7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp -5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCROME4HYYEhLoaJXhena/M -UGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpICT0ugpTN -GmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy -5V6548r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv -6q012iDTiIJh8BIitrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEK -eN5KzlW/HdXZt1bv8Hb/C3m1r737qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6 -B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMBAAGjgZcwgZQwDwYDVR0TAQH/ -BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcCARYxaHR0cDov -L3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV -HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqG -SIb3DQEBCwUAA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLyS -CZa59sCrI2AGeYwRTlHSeYAz+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen -5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwjf/ST7ZwaUb7dRUG/kSS0H4zpX897 -IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaNkqbG9AclVMwWVxJK -gnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfkCpYL -+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxL -vJxxcypFURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkm -bEgeqmiSBeGCc1qb3AdbCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvk -N1trSt8sV4pAWja63XVECDdCcAz+3F4hoKOKwJCcaNpQ5kUQR3i2TtJlycM33+FC -Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z -ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO -TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh -dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX -DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl -ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv -b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP -cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW -IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX -xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy -KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR -9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az -5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8 -6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7 -Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP -bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt -BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt -XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF -MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd -INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD -U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp -LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8 -Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp -gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh -/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw -0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A -fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq -4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR -1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/ -QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM -94B7IWcnMFk= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl -MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp -U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw -NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE -ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp -ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 -DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf -8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN -+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 -X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa -K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA -1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G -A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR -zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 -YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD -bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w -DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 -L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D -eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl -xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp -VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY -WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT -HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs -ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw -MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 -b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj -aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp -Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg -nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 -HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N -Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN -dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 -HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO -BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G -CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU -sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 -4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg -8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K -pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 -mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT -HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs -ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 -MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD -VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy -ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy -dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p -OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 -8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K -Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe -hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk -6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw -DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q -AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI -bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB -ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z -qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd -iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn -0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN -sSi6 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEW -MBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkgRzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1 -OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoG -A1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRzIwggIiMA0G -CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8Oo1XJ -JZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsD -vfOpL9HG4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnoo -D/Uefyf3lLE3PbfHkffiAez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/ -Q0kGi4xDuFby2X8hQxfqp0iVAXV16iulQ5XqFYSdCI0mblWbq9zSOdIxHWDirMxW -RST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbsO+wmETRIjfaAKxojAuuK -HDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8HvKTlXcxN -nw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM -0D4LnMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/i -UUjXuG+v+E5+M5iSFGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9 -Ha90OrInwMEePnWjFqmveiJdnxMaz6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHg -TuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE -AwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJKoZIhvcNAQEL -BQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K -2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfX -UfEpY9Z1zRbkJ4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl -6/2o1PXWT6RbdejF0mCy2wl+JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK -9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG/+gyRr61M3Z3qAFdlsHB1b6uJcDJ -HgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTcnIhT76IxW1hPkWLI -wpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/XldblhY -XzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5l -IxKVCCIcl85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoo -hdVddLHRDiBYmxOlsGOm7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulr -so8uBtjRkcfGEvRM/TAXw8HaOFvjqermobp573PYtlNXLfbQ4ddI ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW -MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg -Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9 -MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi -U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh -cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA -A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk -pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf -OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C -Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT -Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi -HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM -Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w -+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ -Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 -Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B -26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID -AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE -FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j -ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js -LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM -BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0 -Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy -dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh -cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh -YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg -dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp -bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ -YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT -TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ -9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8 -jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW -FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz -ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1 -ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L -EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu -L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq -yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC -O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V -um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh -NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEW -MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg -Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM3WhcNMzYwOTE3MTk0NjM2WjB9 -MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi -U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh -cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA -A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk -pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf -OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C -Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT -Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi -HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM -Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w -+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ -Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 -Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B -26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID -AQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD -VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFul -F2mHMMo0aEPQQa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCC -ATgwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w -ZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVybWVk -aWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENvbW1lcmNpYWwgKFN0 -YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0aGUg -c2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0 -aWZpY2F0aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93 -d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgG -CWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1 -dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5fPGFf59Jb2vKXfuM/gTF -wWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWmN3PH/UvS -Ta0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst -0OcNOrg+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNc -pRJvkrKTlMeIFw6Ttn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKl -CcWw0bdT82AUuoVpaiF8H3VhFyAXe2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVF -P0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA2MFrLH9ZXF2RsXAiV+uKa0hK -1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBsHvUwyKMQ5bLm -KhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE -JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ -8dCAWZvLMdibD4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnm -fyWl8kgAwKQB2j8= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBk -MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0 -YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg -Q0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4MTgyMjA2MjBaMGQxCzAJBgNVBAYT -AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp -Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIICIjAN -BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9 -m2BtRsiMMW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdih -FvkcxC7mlSpnzNApbjyFNDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/ -TilftKaNXXsLmREDA/7n29uj/x2lzZAeAR81sH8A25Bvxn570e56eqeqDFdvpG3F -EzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkCb6dJtDZd0KTeByy2dbco -kdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn7uHbHaBu -HYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNF -vJbNcA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo -19AOeCMgkckkKmUpWyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjC -L3UcPX7ape8eYIVpQtPM+GP+HkM5haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJW -bjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNYMUJDLXT5xp6mig/p/r+D5kNX -JLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw -FDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j -BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzc -K6FptWfUjNP9MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzf -ky9NfEBWMXrrpA9gzXrzvsMnjgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7Ik -Vh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQMbFamIp1TpBcahQq4FJHgmDmHtqB -sfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4HVtA4oJVwIHaM190e -3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtlvrsR -ls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ip -mXeascClOS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HH -b6D0jqTsNFFbjCYDcKF31QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksf -rK/7DZBaZmBwXarNeNQk7shBoJMBkpxqnvy5JMWzFYJ+vq6VK+uxwNrjAWALXmms -hFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCyx/yP2FS1k2Kdzs9Z+z0Y -zirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMWNY6E0F/6 -MBr1mmz0DlP5OlvRHA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF2TCCA8GgAwIBAgIQHp4o6Ejy5e/DfEoeWhhntjANBgkqhkiG9w0BAQsFADBk -MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0 -YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg -Q0EgMjAeFw0xMTA2MjQwODM4MTRaFw0zMTA2MjUwNzM4MTRaMGQxCzAJBgNVBAYT -AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp -Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAyMIICIjAN -BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlUJOhJ1R5tMJ6HJaI2nbeHCOFvEr -jw0DzpPMLgAIe6szjPTpQOYXTKueuEcUMncy3SgM3hhLX3af+Dk7/E6J2HzFZ++r -0rk0X2s682Q2zsKwzxNoysjL67XiPS4h3+os1OD5cJZM/2pYmLcX5BtS5X4HAB1f -2uY+lQS3aYg5oUFgJWFLlTloYhyxCwWJwDaCFCE/rtuh/bxvHGCGtlOUSbkrRsVP -ACu/obvLP+DHVxxX6NZp+MEkUp2IVd3Chy50I9AU/SpHWrumnf2U5NGKpV+GY3aF -y6//SSj8gO1MedK75MDvAe5QQQg1I3ArqRa0jG6F6bYRzzHdUyYb3y1aSgJA/MTA -tukxGggo5WDDH8SQjhBiYEQN7Aq+VRhxLKX0srwVYv8c474d2h5Xszx+zYIdkeNL -6yxSNLCK/RJOlrDrcH+eOfdmQrGrrFLadkBXeyq96G4DsguAhYidDMfCd7Camlf0 -uPoTXGiTOmekl9AbmbeGMktg2M7v0Ax/lZ9vh0+Hio5fCHyqW/xavqGRn1V9TrAL -acywlKinh/LTSlDcX3KwFnUey7QYYpqwpzmqm59m2I2mbJYV4+by+PGDYmy7Velh -k6M99bFXi08jsJvllGov34zflVEpYKELKeRcVVi3qPyZ7iVNTA6z00yPhOgpD/0Q -VAKFyPnlw4vP5w8CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw -FDASBgdghXQBUwIBBgdghXQBUwIBMBIGA1UdEwEB/wQIMAYBAf8CAQcwHQYDVR0O -BBYEFE0mICKJS9PVpAqhb97iEoHF8TwuMB8GA1UdIwQYMBaAFE0mICKJS9PVpAqh -b97iEoHF8TwuMA0GCSqGSIb3DQEBCwUAA4ICAQAyCrKkG8t9voJXiblqf/P0wS4R -fbgZPnm3qKhyN2abGu2sEzsOv2LwnN+ee6FTSA5BesogpxcbtnjsQJHzQq0Qw1zv -/2BZf82Fo4s9SBwlAjxnffUy6S8w5X2lejjQ82YqZh6NM4OKb3xuqFp1mrjX2lhI -REeoTPpMSQpKwhI3qEAMw8jh0FcNlzKVxzqfl9NX+Ave5XLzo9v/tdhZsnPdTSpx -srpJ9csc1fV5yJmz/MFMdOO0vSk3FQQoHt5FRnDsr7p4DooqzgB53MBfGWcsa0vv -aGgLQ+OswWIJ76bdZWGgr4RVSJFSHMYlkSrQwSIjYVmvRRGFHQEkNI/Ps/8XciAT -woCqISxxOQ7Qj1zB09GOInJGTB2Wrk9xseEFKZZZ9LuedT3PDTcNYtsmjGOpI99n -Bjx8Oto0QuFmtEYE3saWmA9LSHokMnWRn6z3aOkquVVlzl1h0ydw2Df+n7mvoC5W -t6NlUe07qxS/TFED6F+KBZvuim6c779o+sjaC+NCydAXFJy3SuCvkychVSa1ZC+N -8f+mQAWFBVzKBxlcCxMoTFh/wqXvRdpg065lYZ1Tg3TCrvJcwhbtkj6EPnNgiLx2 -9CzP0H1907he0ZESEOnN3col49XtmS++dYFLJPlFRpTJKSFTnCZFqhMX5OfNeOI5 -wSsSnqaeG8XmDtkx2Q== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF4DCCA8igAwIBAgIRAPL6ZOJ0Y9ON/RAdBB92ylgwDQYJKoZIhvcNAQELBQAw -ZzELMAkGA1UEBhMCY2gxETAPBgNVBAoTCFN3aXNzY29tMSUwIwYDVQQLExxEaWdp -dGFsIENlcnRpZmljYXRlIFNlcnZpY2VzMR4wHAYDVQQDExVTd2lzc2NvbSBSb290 -IEVWIENBIDIwHhcNMTEwNjI0MDk0NTA4WhcNMzEwNjI1MDg0NTA4WjBnMQswCQYD -VQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2Vy -dGlmaWNhdGUgU2VydmljZXMxHjAcBgNVBAMTFVN3aXNzY29tIFJvb3QgRVYgQ0Eg -MjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMT3HS9X6lds93BdY7Bx -UglgRCgzo3pOCvrY6myLURYaVa5UJsTMRQdBTxB5f3HSek4/OE6zAMaVylvNwSqD -1ycfMQ4jFrclyxy0uYAyXhqdk/HoPGAsp15XGVhRXrwsVgu42O+LgrQ8uMIkqBPH -oCE2G3pXKSinLr9xJZDzRINpUKTk4RtiGZQJo/PDvO/0vezbE53PnUgJUmfANykR -HvvSEaeFGHR55E+FFOtSN+KxRdjMDUN/rhPSays/p8LiqG12W0OfvrSdsyaGOx9/ -5fLoZigWJdBLlzin5M8J0TbDC77aO0RYjb7xnglrPvMyxyuHxuxenPaHZa0zKcQv -idm5y8kDnftslFGXEBuGCxobP/YCfnvUxVFkKJ3106yDgYjTdLRZncHrYTNaRdHL -OdAGalNgHa/2+2m8atwBz735j9m9W8E6X47aD0upm50qKGsaCnw8qyIL5XctcfaC -NYGu+HuB5ur+rPQam3Rc6I8k9l2dRsQs0h4rIWqDJ2dVSqTjyDKXZpBy2uPUZC5f -46Fq9mDU5zXNysRojddxyNMkM3OxbPlq4SjbX8Y96L5V5jcb7STZDxmPX2MYWFCB -UWVv8p9+agTnNCRxunZLWB4ZvRVgRaoMEkABnRDixzgHcgplwLa7JSnaFp6LNYth -7eVxV4O1PHGf40+/fh6Bn0GXAgMBAAGjgYYwgYMwDgYDVR0PAQH/BAQDAgGGMB0G -A1UdIQQWMBQwEgYHYIV0AVMCAgYHYIV0AVMCAjASBgNVHRMBAf8ECDAGAQH/AgED -MB0GA1UdDgQWBBRF2aWBbj2ITY1x0kbBbkUe88SAnTAfBgNVHSMEGDAWgBRF2aWB -bj2ITY1x0kbBbkUe88SAnTANBgkqhkiG9w0BAQsFAAOCAgEAlDpzBp9SSzBc1P6x -XCX5145v9Ydkn+0UjrgEjihLj6p7jjm02Vj2e6E1CqGdivdj5eu9OYLU43otb98T -PLr+flaYC/NUn81ETm484T4VvwYmneTwkLbUwp4wLh/vx3rEUMfqe9pQy3omywC0 -Wqu1kx+AiYQElY2NfwmTv9SoqORjbdlk5LgpWgi/UOGED1V7XwgiG/W9mR4U9s70 -WBCCswo9GcG/W6uqmdjyMb3lOGbcWAXH7WMaLgqXfIeTK7KK4/HsGOV1timH59yL -Gn602MnTihdsfSlEvoqq9X46Lmgxk7lq2prg2+kupYTNHAq4Sgj5nPFhJpiTt3tm -7JFe3VE/23MPrQRYCd0EApUKPtN236YQHoA96M2kZNEzx5LH4k5E4wnJTsJdhw4S -nr8PyQUQ3nqjsTzyP6WqJ3mtMX0f/fwZacXduT98zca0wjAefm6S139hdlqP65VN -vBFuIXxZN5nQBrz5Bm0yFqXZaajh3DyAHmBR3NdUIR7KYndP+tiPsys6DXhyyWhB -WkdKwqPrGtcKqzwyVcgKEZzfdNbwQBUdyLmPtTbFr/giuMod89a2GQ+fYWVq6nTI -fI/DT11lgh/ZDYnadXL77/FHZxOzyNEZiCcmmpl5fx7kLD977vHeTYuWl8PVP3wb -I+2ksx0WckNLIOFZfsLorSa/ovc= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV -BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln -biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF -MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT -d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC -CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8 -76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+ -bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c -6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE -emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd -MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt -MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y -MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y -FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi -aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM -gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB -qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7 -lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn -8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov -L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6 -45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO -UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5 -O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC -bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv -GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a -77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC -hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3 -92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp -Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w -ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt -Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFejCCA2KgAwIBAgIJAN7E8kTzHab8MA0GCSqGSIb3DQEBCwUAMEoxCzAJBgNV -BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxJDAiBgNVBAMTG1N3aXNzU2ln -biBHb2xkIFJvb3QgQ0EgLSBHMzAeFw0wOTA4MDQxMzMxNDdaFw0zNzA4MDQxMzMx -NDdaMEoxCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxJDAiBgNV -BAMTG1N3aXNzU2lnbiBHb2xkIFJvb3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEB -BQADggIPADCCAgoCggIBAMPon8hlWp1nG8FFl7S0h0NbYWCAnvJ/XvlnRN1E+qu1 -q3f/KhlMzm/Ej0Gf4OLNcuDR1FJhQQkKvwpw++CDaWEpytsimlul5t0XlbBvhI46 -PmRaQfsbWPz9Kz6ypOasyYK8zvaV+Jd37Sb2WK6eJ+IPg+zFNljIe8/Vh6GphxoT -Z2EBbaZpnOKQ8StoZfPosHz8gj3erdgKAAlEeROc8P5udXvCvLNZAQt8xdUt8L// -bVfSSYHrtLNQrFv5CxUVjGn/ozkB7fzc3CeXjnuL1Wqm1uAdX80Bkeb1Ipi6LgkY -OG8TqIHS+yE35y20YueBkLDGeVm3Z3X+vo87+jbsr63ST3Q2AeVXqyMEzEpel89+ -xu+MzJUjaY3LOMcZ9taKABQeND1v2gwLw7qX/BFLUmE+vzNnUxC/eBsJwke6Hq9Y -9XWBf71W8etW19lpDAfpNzGwEhwy71bZvnorfL3TPbxqM006PFAQhyfHegpnU9t/ -gJvoniP6+Qg6i6GONFpIM19k05eGBxl9iJTOKnzFat+vvKmfzTqmurtU+X+P388O -WsStmryzOndzg0yTPJBotXxQlRHIgl6UcdBBGPvJxmXszom2ziKzEVs/4J0+Gxho -DaoDoWdZv2udvPjyZS+aQTpF2F7QNmxvOx5jtI6YTBPbIQ6fe+3qoKpxw+ujoNIl -AgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud -DgQWBBRclwZGNKvfMMV8xQ1VcWYwtWCPnjAfBgNVHSMEGDAWgBRclwZGNKvfMMV8 -xQ1VcWYwtWCPnjANBgkqhkiG9w0BAQsFAAOCAgEAd0tN3uqFSqssJ9ZFx/FfIMFb -YO0Hy6Iz3DbPx5TxBsfV2s/NrYQ+/xJIf0HopWZXMMQd5KcaLy1Cwe9Gc7LV9Vr9 -Dnpr0sgxow1IlldlY1UYwPzkisyYhlurDIonN/ojaFlcJtehwcK5Tiz/KV7mlAu+ -zXJPleiP9ve4Pl7Oz54RyawDKUiKqbamNLmsQP/EtnM3scd/qVHbSypHX0AkB4gG -tySz+3/3sIsz+r8jdaNc/qplGsK+8X2BdwOBsY3XlQ16PEKYt4+pfVDh31IGmqBS -VHiDB2FSCTdeipynxlHRXGPRhNzC29L6Wxg2fWa81CiXL3WWHIQHrIuOUxG+JCGq -Z/LBrYic07B4Z3j101gDIApdIPG152XMDiDj1d/mLxkrhWjBBCbPj+0FU6HdBw7r -QSbHtKksW+NpPWbAYhvAqobAN8MxBIZwOb5rXyFAQaB/5dkPOEtwX0n4hbgrLqof -k0FD+PuydDwfS1dbt9RRoZJKzr4Qou7YFCJ7uUG9jemIqdGPAxpg/z+HiaCZJyJm -sD5onnKIUTidEz5FbQXlRrVz7UOGsRQKHrzaDb8eJFxmjw6+of3G62m8Q3nXA3b5 -3IeZuJjEzX9tEPkQvixC/pwpTYNrCr21jsRIiv0hB6aAfR+b6au9gmFECnEnX22b -kJ6u/zYks2gD1pWMa3M= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFwTCCA6mgAwIBAgIITrIAZwwDXU8wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE -BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEjMCEGA1UEAxMaU3dpc3NTaWdu -IFBsYXRpbnVtIENBIC0gRzIwHhcNMDYxMDI1MDgzNjAwWhcNMzYxMDI1MDgzNjAw -WjBJMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMSMwIQYDVQQD -ExpTd2lzc1NpZ24gUGxhdGludW0gQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQAD -ggIPADCCAgoCggIBAMrfogLi2vj8Bxax3mCq3pZcZB/HL37PZ/pEQtZ2Y5Wu669y -IIpFR4ZieIbWIDkm9K6j/SPnpZy1IiEZtzeTIsBQnIJ71NUERFzLtMKfkr4k2Htn -IuJpX+UFeNSH2XFwMyVTtIc7KZAoNppVRDBopIOXfw0enHb/FZ1glwCNioUD7IC+ -6ixuEFGSzH7VozPY1kneWCqv9hbrS3uQMpe5up1Y8fhXSQQeol0GcN1x2/ndi5ob -jM89o03Oy3z2u5yg+gnOI2Ky6Q0f4nIoj5+saCB9bzuohTEJfwvH6GXp43gOCWcw -izSC+13gzJ2BbWLuCB4ELE6b7P6pT1/9aXjvCR+htL/68++QHkwFix7qepF6w9fl -+zC8bBsQWJj3Gl/QKTIDE0ZNYWqFTFJ0LwYfexHihJfGmfNtf9dng34TaNhxKFrY -zt3oEBSa/m0jh26OWnA81Y0JAKeqvLAxN23IhBQeW71FYyBrS3SMvds6DsHPWhaP -pZjydomyExI7C3d3rLvlPClKknLKYRorXkzig3R3+jVIeoVNjZpTxN94ypeRSCtF -KwH3HBqi7Ri6Cr2D+m+8jVeTO9TUps4e8aCxzqv9KyiaTxvXw3LbpMS/XUz13XuW -ae5ogObnmLo2t/5u7Su9IPhlGdpVCX4l3P5hYnL5fhgC72O00Puv5TtjjGePAgMB -AAGjgawwgakwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O -BBYEFFCvzAeHFUdvOMW0ZdHelarp35zMMB8GA1UdIwQYMBaAFFCvzAeHFUdvOMW0 -ZdHelarp35zMMEYGA1UdIAQ/MD0wOwYJYIV0AVkBAQEBMC4wLAYIKwYBBQUHAgEW -IGh0dHA6Ly9yZXBvc2l0b3J5LnN3aXNzc2lnbi5jb20vMA0GCSqGSIb3DQEBBQUA -A4ICAQAIhab1Fgz8RBrBY+D5VUYI/HAcQiiWjrfFwUF1TglxeeVtlspLpYhg0DB0 -uMoI3LQwnkAHFmtllXcBrqS3NQuB2nEVqXQXOHtYyvkv+8Bldo1bAbl93oI9ZLi+ -FHSjClTTLJUYFzX1UWs/j6KWYTl4a0vlpqD4U99REJNi54Av4tHgvI42Rncz7Lj7 -jposiU0xEQ8mngS7twSNC/K5/FqdOxa3L8iYq/6KUFkuozv8KV2LwUvJ4ooTHbG/ -u0IdUt1O2BReEMYxB+9xJ/cbOQncguqLs5WGXv312l0xpuAxtpTmREl0xRbl9x8D -YSjFyMsSoEJL+WuICI20MhjzdZ/EfwBPBZWcoxcCw7NTm6ogOSkrZvqdr16zktK1 -puEa+S1BaYEUtLS17Yk9zvupnTVCRLEcFHOBzyoBNZox1S2PbYTfgE1X4z/FhHXa -icYwu+uPyyIIoK6q8QNsOktNCaUOcsZWayFCTiMlFGiudgp8DAdwZPmaL/YFOSbG -DI8Zf0NebvRbFS/bYV3mZy8/CJT5YLSYMdp08YSTcU1f+2BY0fvEwW2JorsgH51x -kcsymxM9Pn2SUjWskpSi0xjCfMfqr3YFFt1nJ8J+HAciIfNAChs0B0QTwoRqjt8Z -Wr9/6x3iGjjRXK9HkmuAtTClyY3YqzGBH9/CZjfTk6mFhnll0g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFgTCCA2mgAwIBAgIIIj+pFyDegZQwDQYJKoZIhvcNAQELBQAwTjELMAkGA1UE -BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEoMCYGA1UEAxMfU3dpc3NTaWdu -IFBsYXRpbnVtIFJvb3QgQ0EgLSBHMzAeFw0wOTA4MDQxMzM0MDRaFw0zNzA4MDQx -MzM0MDRaME4xCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxKDAm -BgNVBAMTH1N3aXNzU2lnbiBQbGF0aW51bSBSb290IENBIC0gRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCUoO8TG59EIBvNxaoiu9nyUj56Wlh35o2h -K8ncpPPksxOUAGKbHPJDUEOBfq8wNkmsGIkMGEW4PsdUbePYmllriholqba1Dbd9 -I/BffagHqfc+hi7IAU3c5jbtHeU3B2kSS+OD0QQcJPAfcHHnGe1zSG6VKxW2VuYC -31bpm/rqpu7gwsO64MzGyHvXbzqVmzqPvlss0qmgOD7WiOGxYhOO3KswZ82oaqZj -K4Kwy8c9Tu1y9n2rMk5lAusPmXT4HBoojA5FAJMsFJ9txxue9orce3jjtJRHHU0F -bYR6kFSynot1woDfhzk/n/tIVAeNoCn1+WBfWnLou5ugQuAIADSjFTwT49YaawKy -lCGjnUG8KmtOMzumlDj8PccrM7MuKwZ0rJsQb8VORfddoVYDLA1fer0e3h13kGva -pS2KTOnfQfTnS+x9lUKfTKkJD0OIPz2T5yv0ekjaaMTdEoAxGl0kVCamJCGzTK3a -Fwg2AlfGnIZwyXXJnnxh2HjmuegUafkcECgSXUt1ULo80GdwVVVWS/s9HNjbeU2X -37ie2xcs1TUHuFCp9473Vv96Z0NPINnKZtY4YEvulDHWDaJIm/80aZTGNfWWiO+q -ZsyBputMU/8ydKe2nZhXtLomqfEzM2J+OrADEVf/3G8RI60+xgrQzFS3LcKTHeXC -pozH2O9T9wIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zAdBgNVHQ4EFgQUVio/kFj0F1oUstcIG4VbVGpUGigwHwYDVR0jBBgwFoAUVio/ -kFj0F1oUstcIG4VbVGpUGigwDQYJKoZIhvcNAQELBQADggIBAGztiudDqHknm7jP -hz5kOBiMEUKShjfgWMMb7gQu94TsgxBoDH94LZzCl442ThbYDuprSK1Pnl0NzA2p -PhiFfsxomTk11tifhsEy+01lsyIUS8iFZtoX/3GRrJxWV95xLFZCv/jNDvCi0//S -IhX70HgKfuGwWs6ON9upnueVz2PyLA3S+m/zyNX7ALf3NWcQ03tS7BAy+L/dXsmm -gqTxsL8dLt0l5L1N8DWpkQFH+BAClFvrPusNutUdYyylLqvn4x6j7kuqX7FmAbSC -WvlGS8fx+N8svv113ZY4mjc6bqXmMhVus5DAOYp0pZWgvg0uiXnNKVaOw15XUcQF -bwRVj4HpTL1ZRssqvE3JHfLGTwXkyAQN925P2sM6nNLC9enGJHoUPhxCMKgCRTGp -/FCp3NyGOA9bkz9/CE5qDSc6EHlWwxW4PgaG9tlwZ691eoviWMzGdU8yVcVsFAko -O/KV5GreLCgHraB9Byjd1Fqj6aZ8E4yZC1J429nR3z5aQ3Z/RmBTws3ndkd8Vc20 -OWQQW5VLNV1EgyTV4C4kDMGAbmkAgAZ3CmaCEAxRbzeJV9vzTOW4ue4jZpdgt1Ld -2Zb7uoo7oE3OXvBETJDMIU8bOphrjjGD+YMIUssZwTVr7qEVW4g/bazyNJJTpjAq -E9fmhqhd2ULSx52peovL3+6iMcLl ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE -BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu -IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow -RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY -U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A -MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv -Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br -YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF -nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH -6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt -eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/ -c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ -MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH -HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf -jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6 -5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB -rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU -F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c -wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 -cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB -AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp -WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9 -xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ -2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ -IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8 -aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X -em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR -dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/ -OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+ -hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy -tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFfjCCA2agAwIBAgIJAKqIsFoLsXabMA0GCSqGSIb3DQEBCwUAMEwxCzAJBgNV -BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxJjAkBgNVBAMTHVN3aXNzU2ln -biBTaWx2ZXIgUm9vdCBDQSAtIEczMB4XDTA5MDgwNDEzMTkxNFoXDTM3MDgwNDEz -MTkxNFowTDELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEmMCQG -A1UEAxMdU3dpc3NTaWduIFNpbHZlciBSb290IENBIC0gRzMwggIiMA0GCSqGSIb3 -DQEBAQUAA4ICDwAwggIKAoICAQC+h5sF5nF8Um9t7Dep6bPczF9/01DqIZsE8D2/ -vo7JpRQWMhDPmfzscK1INmckDBcy1inlSjmxN+umeAxsbxnKTvdR2hro+iE4bJWc -L9aLzDsCm78mmxFFtrg0Wh2mVEhSyJ14cc5ISsyneIPcaKtmHncH0zYYCNfUbWD4 -8HnTMzYJkmO3BJr1p5baRa90GvyC46hbDjo/UleYfrycjMHAslrfxH7+DKZUdoN+ -ut3nKvRKNk+HZS6lujmNWWEp89OOJHCMU5sRpUcHsnUFXA2E2UTZzckmRFduAn2V -AdSrJIbuPXD7V/qwKRTQnfLFl8sJyvHyPefYS5bpiC+eR1GKVGWYSNIS5FR3DAfm -vluc8d0Dfo2E/L7JYtX8yTroibVfwgVSYfCcPuwuTYxykY7IQ8GiKF71gCTc4i+H -O1MA5cvwsnyNeRmgiM14+MWKWnflBqzdSt7mcG6+r771sasOCLDboD+Uxb4Subx7 -J3m1MildrsUgI5IDe1Q5sIkiVG0S48N46jpA/aSTrOktiDzbpkdmTN/YF+0W3hrW -10Fmvx2A8aTgZBEpXgwnBWLr5cQEYtHEnwxqVdZYOJxmD537q1SAmZzsSdaCn9pF -1j9TBgO3/R/shn104KS06DK2qgcj+O8kQZ5jMHj0VN2O8Fo4jhJ/eMdvAlYhM864 -uK1pVQIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd -BgNVHQ4EFgQUoYxFkwoSYwunV18ySn3hIee3PmYwHwYDVR0jBBgwFoAUoYxFkwoS -YwunV18ySn3hIee3PmYwDQYJKoZIhvcNAQELBQADggIBAIeuYW1IOCrGHNxKLoR4 -ScAjKkW4NU3RBfq5BTPEZL3brVQWKrA+DVoo2qYagHMMxEFvr7g0tnfUW44dC4tG -kES1s+5JGInBSzSzhzV0op5FZ+1FcWa2uaElc9fCrIj70h2na9rAWubYWWQ0l2Ug -MTMDT86tCZ6u6cI+GHW0MyUSuwXsULpxQOK93ohGBSGEi6MrHuswMIm/EfVcRPiR -i0tZRQswDcoMT29jvgT+we3gh/7IzVa/5dyOetTWKU6A26ubP45lByL3RM2WHy3H -9Qm2mHD/ONxQFRGEO3+p8NgkVMgXjCsTSdaZf0XRD46/aXI3Uwf05q79Wz55uQbN -uIF4tE2g0DW65K7/00m8Ne1jxrP846thWgW2C+T/qSq+31ROwktcaNqjMqLJTVcY -UzRZPGaZ1zwCeKdMcdC/2/HEPOcB5gTyRPZIJjAzybEBGesC8cwh+joCMBedyF+A -P90lrAKb4xfevcqSFNJSgVPm6vwwZzKpYvaTFxUHMV4PG2n19Km3fC2z7YREMkco -BzuGaUWpxzaWkHJ02BKmcyPRTrm2ejrEKaFQBhG52fQmbmIIEiAW8AFXF9QFNmeX -61H5/zMkDAUPVr/vPRxSjoreaQ9aH/DVAzFEs5LG6nWorrvHYAOImP/HBIRSkIbh -tJOpUC/o69I2rDBgp9ADE7UK ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICqDCCAi2gAwIBAgIQIW4zpcvTiKRvKQe0JzzE2DAKBggqhkjOPQQDAzCBlDEL -MAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYD -VQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBD -bGFzcyAxIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0g -RzQwHhcNMTExMDA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBlDELMAkGA1UEBhMC -VVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZTeW1h -bnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAxIFB1 -YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcq -hkjOPQIBBgUrgQQAIgNiAATXZrUb266zYO5G6ohjdTsqlG3zXxL24w+etgoUU0hS -yNw6s8tIICYSTvqJhNTfkeQpfSgB2dsYQ2mhH7XThhbcx39nI9/fMTGDAzVwsUu3 -yBe7UcvclBfb6gk7dhLeqrWjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E -BTADAQH/MB0GA1UdDgQWBBRlwI0l9Qy6l3eQP54u4Fr1ztXh5DAKBggqhkjOPQQD -AwNpADBmAjEApa7jRlP4mDbjIvouKEkN7jB+M/PsP3FezFWJeJmssv3cHFwzjim5 -axfIEWi13IMHAjEAnMhE2mnCNsNUGRCFAtqdR+9B52wmnQk9922Q0QVEL7C8g5No -8gxFSTm/mQQc0xCg ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID9jCCAt6gAwIBAgIQJDJ18h0v0gkz97RqytDzmDANBgkqhkiG9w0BAQsFADCB -lDELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8w -HQYDVQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRl -YyBDbGFzcyAxIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -IC0gRzYwHhcNMTExMDE4MDAwMDAwWhcNMzcxMjAxMjM1OTU5WjCBlDELMAkGA1UE -BhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZT -eW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAx -IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzYwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDHOddJZKmZgiJM6kXZBxbje/SD -6Jlz+muxNuCad6BAwoGNAcfMjL2Pffd543pMA03Z+/2HOCgs3ZqLVAjbZ/sbjP4o -ki++t7JIp4Gh2F6Iw8w5QEFa0dzl2hCfL9oBTf0uRnz5LicKaTfukaMbasxEvxvH -w9QRslBglwm9LiL1QYRmn81ApqkAgMEflZKf3vNI79sdd2H8f9/ulqRy0LY+/3gn -r8uSFWkI22MQ4uaXrG7crPaizh5HmbmJtxLmodTNWRFnw2+F2EJOKL5ZVVkElauP -N4C/DfD8HzpkMViBeNfiNfYgPym4jxZuPkjctUwH4fIa6n4KedaovetdhitNAgMB -AAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW -BBQzQejIORIVk0jyljIuWvXalF9TYDANBgkqhkiG9w0BAQsFAAOCAQEAFeNzV7EX -tl9JaUSm9l56Z6zS3nVJq/4lVcc6yUQVEG6/MWvL2QeTfxyFYwDjMhLgzMv7OWyP -4lPiPEAz2aSMR+atWPuJr+PehilWNCxFuBL6RIluLRQlKCQBZdbqUqwFblYSCT3Q -dPTXvQbKqDqNVkL6jXI+dPEDct+HG14OelWWLDi3mIXNTTNEyZSPWjEwN0ujOhKz -5zbRIWhLLTjmU64cJVYIVgNnhJ3Gw84kYsdMNs+wBkS39V8C3dlU6S+QTnrIToNA -DJqXPDe/v+z28LSFdyjBC8hnghAXOKK3Buqbvzr46SMHv3TgmDgVVXjucgBcGaP0 -0jPg/73RVDkpDw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICqDCCAi2gAwIBAgIQNBdlEkA7t1aALYDLeVWmHjAKBggqhkjOPQQDAzCBlDEL -MAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYD -VQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBD -bGFzcyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0g -RzQwHhcNMTExMDA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBlDELMAkGA1UEBhMC -VVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZTeW1h -bnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAyIFB1 -YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcq -hkjOPQIBBgUrgQQAIgNiAATR2UqOTA2ESlG6fO/TzPo6mrWnYxM9AeBJPvrBR8mS -szrX/m+c95o6D/UOCgrDP8jnEhSO1dVtmCyzcTIK6yq99tdqIAtnRZzSsr9TImYJ -XdsR8/EFM1ij4rjPfM2Cm72jQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E -BTADAQH/MB0GA1UdDgQWBBQ9MvM6qQyQhPmijGkGYVQvh3L+BTAKBggqhkjOPQQD -AwNpADBmAjEAyKapr0F/tckRQhZoaUxcuCcYtpjxwH+QbYfTjEYX8D5P/OqwCMR6 -S7wIL8fip29lAjEA1lnehs5fDspU1cbQFQ78i5Ry1I4AWFPPfrFLDeVQhuuea9// -KabYR9mglhjb8kWz ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID9jCCAt6gAwIBAgIQZIKe/DcedF38l/+XyLH/QTANBgkqhkiG9w0BAQsFADCB -lDELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8w -HQYDVQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRl -YyBDbGFzcyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -IC0gRzYwHhcNMTExMDE4MDAwMDAwWhcNMzcxMjAxMjM1OTU5WjCBlDELMAkGA1UE -BhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZT -eW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAy -IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzYwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNzOkFyGOFyz9AYxe9GPo15gRn -V2WYKaRPyVyPDzTS+NqoE2KquB5QZ3iwFkygOakVeq7t0qLA8JA3KRgmXOgNPLZs -ST/B4NzZS7YUGQum05bh1gnjGSYc+R9lS/kaQxwAg9bQqkmi1NvmYji6UBRDbfkx -+FYW2TgCkc/rbN27OU6Z4TBnRfHU8I3D3/7yOAchfQBeVkSz5GC9kSucq1sEcg+y -KNlyqwUgQiWpWwNqIBDMMfAr2jUs0Pual07wgksr2F82owstr2MNHSV/oW5cYqGN -KD6h/Bwg+AEvulWaEbAZ0shQeWsOagXXqgQ2sqPy4V93p3ec5R7c6d9qwWVdAgMB -AAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW -BBSHjCCVyJhK0daABkqQNETfHE2/sDANBgkqhkiG9w0BAQsFAAOCAQEAgY6ypWaW -tyGltu9vI1pf24HFQqV4wWn99DzX+VxrcHIa/FqXTQCAiIiCisNxDY7FiZss7Y0L -0nJU9X3UXENX6fOupQIR9nYrgVfdfdp0MP1UR/bgFm6mtApI5ud1Bw8pGTnOefS2 -bMVfmdUfS/rfbSw8DVSAcPCIC4DPxmiiuB1w2XaM/O6lyc+tHc+ZJVdaYkXLFmu9 -Sc2lo4xpeSWuuExsi0BmSxY/zwIa3eFsawdhanYVKZl/G92IgMG/tY9zxaaWI4Sm -KIYkM2oBLldzJbZev4/mHWGoQClnHYebHX+bn5nNMdZUvmK7OaxoEkiRIKXLsd3+ -b/xa5IJVWa8xqQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICpzCCAi2gAwIBAgIQTHm1miicdjFk9YlE0JEC3jAKBggqhkjOPQQDAzCBlDEL -MAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYD -VQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBD -bGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0g -RzQwHhcNMTIxMDE4MDAwMDAwWhcNMzcxMjAxMjM1OTU5WjCBlDELMAkGA1UEBhMC -VVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZTeW1h -bnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAzIFB1 -YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcq -hkjOPQIBBgUrgQQAIgNiAARXz+qzOU0/oSHgbi84csaHl/OFC0fnD1HI0fSZm8pZ -Zf9M+eoLtyXV0vbsMS0yYhLXdoan+jjJZdT+c+KEOfhMSWIT3brViKBfPchPsD+P -oVAR5JNGrcNfy/GkapVW6MCjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E -BTADAQH/MB0GA1UdDgQWBBQknbzScfcdwiW+IvGJpSwVOzQeXjAKBggqhkjOPQQD -AwNoADBlAjEAuWZoZdsF0Dh9DvPIdWG40CjEsUozUVj78jwQyK5HeHbKZiQXhj5Q -Vm6lLZmIuL0kAjAD6qfnqDzqnWLGX1TamPR3vU+PGJyRXEdrQE0QHbPhicoLIsga -xcX+i93B3294n5E= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF9jCCA96gAwIBAgIQZWNxhdNvRcaPfzH5CYeSgjANBgkqhkiG9w0BAQwFADCB -lDELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8w -HQYDVQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRl -YyBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -IC0gRzYwHhcNMTIxMDE4MDAwMDAwWhcNMzcxMjAxMjM1OTU5WjCBlDELMAkGA1UE -BhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZT -eW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAz -IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzYwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC3DrL6TbyachX7d1vb/UMPywv3 -YC6zK34Mu1PyzE5l8xm7/zUd99Opu0Attd141Kb5N+qFBXttt+YTSwZ8+3ZjjyAd -LTgrBIXy6LDRX01KIclq2JTqHgJQpqqQB6BHIepm+QSg5oPwxPVeluInTWHDs8GM -IrZmoQDRVin77cF/JMo9+lqUsITDx7pDHP1kDvEo+0dZ8ibhMblE+avd+76+LDfj -rAsY0/wBovGkCjWCR0yrvYpe3xOF/CDMSFmvr0FvyyPNypOn3dVfyGQ7/wEDoApP -LW49hL6vyDKyUymQFfewBZoKPPa5BpDJpeFdoDuw/qi2v/WJKFckOiGGceTciotB -VeweMCRZ0cBZuHivqlp03iWAMJjtMERvIXAc2xJTDtamKGaTLB/MTzwbgcW59nhv -0DI6CHLbaw5GF4WU87zvvPekXo7p6bVk5bdLRRIsTDe3YEMKTXEGAJQmNXQfu3o5 -XE475rgD4seTi4QsJUlF3X8jlGAfy+nN9quX92Hn+39igcjcCjBcGHzmzu/Hbh6H -fLPpysh7avRo/IOlDFa0urKNSgrHl5fFiDAVPRAIVBVycmczM/R8t84AJ1NlziTx -WmTnNi/yLgLCl99y6AIeoPc9tftoYAP6M6nmEm0G4amoXU48/tnnAGWsthlNe4N/ -NEfq4RhtsYsceavnnQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQUOXEIAD7eyIbnkP/k/SEPziQZFvYwDQYJKoZIhvcN -AQEMBQADggIBAFBriE1gSM5a4yLOZ3yEp80c/ekMA4w2rwqHDmquV64B0Da78v25 -c8FftaiuTKL6ScsHRhY2vePIVzh+OOS/JTNgxtw3nGO7XpgeGrKC8K6mdxGAREeh -KcXwszrOmPC47NMOgAZ3IzBM/3lkYyJbd5NDS3Wz2ztuO0rd8ciutTeKlYg6EGhw -OLlbcH7VQ8n8X0/l5ns27vAg7UdXEyYQXhQGDXt2B8LGLRb0rqdsD7yID08sAraj -1yLmmUc12I2lT4ESOhF9s8wLdfMecKMbA+r6mujmLjY5zJnOOj8Mt674Q5mwk25v -qtkPajGRu5zTtCj7g0x6c4JQZ9IOrO1gxbJdNZjPh34eWR0kvFa62qRa2MzmvB4Q -jxuMjvPB27e+1LBbZY8WaPNWxSoZFk0PuGWHbSSDuGLc4EdhGoh7zk5//dzGDVqa -pPO1TPbdMaboHREhMzAEYX0c4D5PjT+1ixIAWn2poQDUg+twuxj4pNIcgS23CBHI -Jnu21OUPA0Zy1CVAHr5JXW2T8VyyO3VUaTqg7kwiuqya4gitRWMFSlI1dsQ09V4H -Mq3cfCbRW4+t5OaqG3Wf61206MCpFXxOSgdy30bJ1JGSdVaw4e43NmUoxRXIK3bM -bW8Zg/T92hXiQeczeUaDV/nxpbZt07zXU+fucW14qZen7iCcGRVyFT0E ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDcTCCAlmgAwIBAgIVAOYJ/nrqAGiM4CS07SAbH+9StETRMA0GCSqGSIb3DQEB -BQUAMFAxCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGlj -emVuaW93YSBTLkEuMRcwFQYDVQQDDA5TWkFGSVIgUk9PVCBDQTAeFw0xMTEyMDYx -MTEwNTdaFw0zMTEyMDYxMTEwNTdaMFAxCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L -cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRcwFQYDVQQDDA5TWkFGSVIg -Uk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKxHL49ZMTml -6g3wpYwrvQKkvc0Kc6oJ5sxfgmp1qZfluwbv88BdocHSiXlY8NzrVYzuWBp7J/9K -ULMAoWoTIzOQ6C9TNm4YbA9A1jdX1wYNL5Akylf8W5L/I4BXhT9KnlI6x+a7BVAm -nr/Ttl+utT/Asms2fRfEsF2vZPMxH4UFqOAhFjxTkmJWf2Cu4nvRQJHcttB+cEAo -ag/hERt/+tzo4URz6x6r19toYmxx4FjjBkUhWQw1X21re//Hof2+0YgiwYT84zLb -eqDqCOMOXxvH480yGDkh/QoazWX3U75HQExT/iJlwnu7I1V6HXztKIwCBjsxffbH -3jOshCJtywcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwHQYDVR0OBBYEFFOSo33/gnbwM9TrkmdHYTMbaDsqMA0GCSqGSIb3DQEBBQUA -A4IBAQA5UFWd5EL/pBviIMm1zD2JLUCpp0mJG7JkwznIOzawhGmFFaxGoxAhQBEg -haP+E0KR66oAwVC6xe32QUVSHfWqWndzbODzLB8yj7WAR0cDM45ZngSBPBuFE3Wu -GLJX9g100ETfIX+4YBR/4NR/uvTnpnd9ete7Whl0ZfY94yuu4xQqB5QFv+P7IXXV -lTOjkjuGXEcyQAjQzbFaT9vIABSbeCXWBbjvOXukJy6WgAiclzGNSYprre8Ryydd -fmjW9HIGwsIO03EldivvqEYL1Hv1w/Pur+6FUEOaL68PEIUovfgwIB2BAw+vZDuw -cH0mX548PojGyg434cDjkSXa3mHF ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx -KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd -BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl -YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 -OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy -aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 -ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd -AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC -FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi -1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq -jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ -wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj -QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ -WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy -NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC -uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw -IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 -g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN -9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP -BSeOE6Fuwg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx -KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd -BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl -YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 -OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy -aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 -ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN -8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ -RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 -hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 -ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM -EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj -QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 -A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy -WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ -1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 -6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT -91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml -e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p -TpPDpFQUWw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw -NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv -b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD -VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 -MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F -VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 -7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X -Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ -/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs -81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm -dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe -Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu -sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 -pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs -slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ -arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD -VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG -9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl -dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx -0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj -TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed -Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 -Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI -OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 -vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW -t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn -HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx -SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp -IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi -BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw -MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh -d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig -YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v -dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/ -BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6 -papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E -BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K -DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3 -KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox -XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB -rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf -Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw -MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV -BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa -Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl -LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u -MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl -ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm -gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8 -YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf -b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9 -9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S -zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk -OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV -HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA -2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW -oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu -t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c -KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM -m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu -MdRAGmI0Nj81Aa6sY6A= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB -qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf -Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw -MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV -BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw -NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j -LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG -A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl -IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs -W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta -3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk -6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 -Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J -NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA -MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP -r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU -DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz -YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX -xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 -/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ -LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 -jVaMaA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGHDCCBASgAwIBAgIES45gAzANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJE -SzESMBAGA1UEChMJVFJVU1QyNDA4MSIwIAYDVQQDExlUUlVTVDI0MDggT0NFUyBQ -cmltYXJ5IENBMB4XDTEwMDMwMzEyNDEzNFoXDTM3MTIwMzEzMTEzNFowRTELMAkG -A1UEBhMCREsxEjAQBgNVBAoTCVRSVVNUMjQwODEiMCAGA1UEAxMZVFJVU1QyNDA4 -IE9DRVMgUHJpbWFyeSBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB -AJlJodr3U1Fa+v8HnyACHV81/wLevLS0KUk58VIABl6Wfs3LLNoj5soVAZv4LBi5 -gs7E8CZ9w0F2CopW8vzM8i5HLKE4eedPdnaFqHiBZ0q5aaaQArW+qKJx1rT/AaXt -alMB63/yvJcYlXS2lpexk5H/zDBUXeEQyvfmK+slAySWT6wKxIPDwVapauFY9QaG -+VBhCa5jBstWS7A5gQfEvYqn6csZ3jW472kW6OFNz6ftBcTwufomGJBMkonf4ZLr -6t0AdRi9jflBPz3MNNRGxyjIuAmFqGocYFA/OODBRjvSHB2DygqQ8k+9tlpvzMRr -kU7jq3RKL+83G1dJ3/LTjCLz4ryEMIC/OJ/gNZfE0qXddpPtzflIPtUFVffXdbFV -1t6XZFhJ+wBHQCpJobq/BjqLWUA86upsDbfwnePtmIPRCemeXkY0qabC+2Qmd2Fe -xyZphwTyMnbqy6FG1tB65dYf3mOqStmLa3RcHn9+2dwNfUkh0tjO2FXD7drWcU0O -I9DW8oAypiPhm/QCjMU6j6t+0pzqJ/S0tdAo+BeiXK5hwk6aR+sRb608QfBbRAs3 -U/q8jSPByenggac2BtTN6cl+AA1Mfcgl8iXWNFVGegzd/VS9vINClJCe3FNVoUnR -YCKkj+x0fqxvBLopOkJkmuZw/yhgMxljUi2qYYGn90OzAgMBAAGjggESMIIBDjAP -BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjARBgNVHSAECjAIMAYGBFUd -IAAwgZcGA1UdHwSBjzCBjDAsoCqgKIYmaHR0cDovL2NybC5vY2VzLnRydXN0MjQw -OC5jb20vb2Nlcy5jcmwwXKBaoFikVjBUMQswCQYDVQQGEwJESzESMBAGA1UEChMJ -VFJVU1QyNDA4MSIwIAYDVQQDExlUUlVTVDI0MDggT0NFUyBQcmltYXJ5IENBMQ0w -CwYDVQQDEwRDUkwxMB8GA1UdIwQYMBaAFPZt+LFIs0FDAduGROUYBbdezAY3MB0G -A1UdDgQWBBT2bfixSLNBQwHbhkTlGAW3XswGNzANBgkqhkiG9w0BAQsFAAOCAgEA -VPAQGrT7dIjD3/sIbQW86f9CBPu0c7JKN6oUoRUtKqgJ2KCdcB5ANhCoyznHpu3m -/dUfVUI5hc31CaPgZyY37hch1q4/c9INcELGZVE/FWfehkH+acpdNr7j8UoRZlkN -15b/0UUBfGeiiJG/ugo4llfoPrp8bUmXEGggK3wyqIPcJatPtHwlb6ympfC2b/Ld -v/0IdIOzIOm+A89Q0utx+1cOBq72OHy8gpGb6MfncVFMoL2fjP652Ypgtr8qN9Ka -/XOazktiIf+2Pzp7hLi92hRc9QMYexrV/nnFSQoWdU8TqULFUoZ3zTEC3F/g2yj+ -FhbrgXHGo5/A4O74X+lpbY2XV47aSuw+DzcPt/EhMj2of7SA55WSgbjPMbmNX0rb -oenSIte2HRFW5Tr2W+qqkc/StixgkKdyzGLoFx/xeTWdJkZKwyjqge2wJqws2upY -EiThhC497+/mTiSuXd69eVUwKyqYp9SD2rTtNmF6TCghRM/dNsJOl+osxDVGcwvt -WIVFF/Onlu5fu1NHXdqNEfzldKDUvCfii3L2iATTZyHwU9CALE+2eIA+PIaLgnM1 -1oCfUnYBkQurTrihvzz9PryCVkLxiqRmBVvUz+D4N5G/wvvKDS6t6cPCS+hqM482 -cbBsn0R9fFLO4El62S9eH1tqOzO20OAOK65yJIsOpSE= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF -MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL -ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx -MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc -MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+ -AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH -iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj -vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA -0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB -OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/ -BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E -FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01 -GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW -zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4 -1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE -f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F -jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN -ZetX2fNXlrtIzYE= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx -EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT -VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 -NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT -B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF -10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz -0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh -MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH -zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc -46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 -yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi -laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP -oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA -BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE -qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm -4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL -1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn -LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF -H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo -RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ -nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh -15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW -6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW -nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j -wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz -aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy -KwbQBM0= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES -MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU -V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz -WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO -LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE -AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH -K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX -RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z -rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx -3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq -hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC -MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls -XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D -lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn -aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ -YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRS -MRgwFgYDVQQHDA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJp -bGltc2VsIHZlIFRla25vbG9qaWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSw -VEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ryb25payB2ZSBLcmlwdG9sb2ppIEFy -YcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNVBAsMGkthbXUgU2Vy -dGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUgS8O2 -ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAe -Fw0wNzA4MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIx -GDAWBgNVBAcMD0dlYnplIC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmls -aW1zZWwgdmUgVGVrbm9sb2ppayBBcmHFn3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBU -QUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZlIEtyaXB0b2xvamkgQXJh -xZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2FtdSBTZXJ0 -aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7Zr -IFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIB -IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4h -gb46ezzb8R1Sf1n68yJMlaCQvEhOEav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yK -O7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1xnnRFDDtG1hba+818qEhTsXO -fJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR6Oqeyjh1jmKw -lZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL -hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQID -AQABo0IwQDAdBgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/ -BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmP -NOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4N5EY3ATIZJkrGG2AA1nJrvhY0D7t -wyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLTy9LQQfMmNkqblWwM -7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYhLBOh -gLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5n -oN+J1q2MdqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUs -yZyQ2uypQjyttgI= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEPTCCAyWgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvzE/MD0GA1UEAww2VMOc -UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx -c8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV4wXAYDVQQKDFVUw5xS -S1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg -SGl6bWV0bGVyaSBBLsWeLiAoYykgQXJhbMSxayAyMDA3MB4XDTA3MTIyNTE4Mzcx -OVoXDTE3MTIyMjE4MzcxOVowgb8xPzA9BgNVBAMMNlTDnFJLVFJVU1QgRWxla3Ry -b25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTELMAkGA1UEBhMC -VFIxDzANBgNVBAcMBkFua2FyYTFeMFwGA1UECgxVVMOcUktUUlVTVCBCaWxnaSDE -sGxldGnFn2ltIHZlIEJpbGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7F -ni4gKGMpIEFyYWzEsWsgMjAwNzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAKu3PgqMyKVYFeaK7yc9SrToJdPNM8Ig3BnuiD9NYvDdE3ePYakqtdTyuTFY -KTsvP2qcb3N2Je40IIDu6rfwxArNK4aUyeNgsURSsloptJGXg9i3phQvKUmi8wUG -+7RP2qFsmmaf8EMJyupyj+sA1zU511YXRxcw9L6/P8JorzZAwan0qafoEGsIiveG -HtyaKhUG9qPw9ODHFNRRf8+0222vR5YXm3dx2KdxnSQM9pQ/hTEST7ruToK4uT6P -IzdezKKqdfcYbwnTrqdUKDT74eA7YH2gvnmJhsifLfkKS8RQouf9eRbHegsYz85M -733WB2+Y8a+xwXrXgTW4qhe04MsCAwEAAaNCMEAwHQYDVR0OBBYEFCnFkKslrxHk -Yb+j/4hhkeYO/pyBMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G -CSqGSIb3DQEBBQUAA4IBAQAQDdr4Ouwo0RSVgrESLFF6QSU2TJ/sPx+EnWVUXKgW -AkD6bho3hO9ynYYKVZ1WKKxmLNA6VpM0ByWtCLCPyA8JWcqdmBzlVPi5RX9ql2+I -aE1KBiY3iAIOtsbWcpnOa3faYjGkVh+uX4132l32iPwa2Z61gfAyuOOI0JzzaqC5 -mxRZNTZPz/OOXl0XrRWV2N2y1RVuAE6zS89mlOTgzbUF2mNXi+WzqtvALhyQRNsa -XRik7r4EW5nVcV9VZWRi1aKbBFmGyGJ353yCRWo9F7/snXUMrqNvWtMvmDb08PUZ -qxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAKpoRq0Tl9 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFkjCCA3qgAwIBAgIBCDANBgkqhkiG9w0BAQUFADA6MQswCQYDVQQGEwJDTjER -MA8GA1UEChMIVW5pVHJ1c3QxGDAWBgNVBAMTD1VDQSBHbG9iYWwgUm9vdDAeFw0w -ODAxMDEwMDAwMDBaFw0zNzEyMzEwMDAwMDBaMDoxCzAJBgNVBAYTAkNOMREwDwYD -VQQKEwhVbmlUcnVzdDEYMBYGA1UEAxMPVUNBIEdsb2JhbCBSb290MIICIjANBgkq -hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2rPlBlA/9nP3xDK/RqUlYjOHsGj+p9+I -A2N9Apb964fJ7uIIu527u+RBj8cwiQ9tJMAEbBSUgU2gDXRm8/CFr/hkGd656YGT -0CiFmUdCSiw8OCdKzP/5bBnXtfPvm65bNAbXj6ITBpyKhELVs6OQaG2BkO5NhOxM -cE4t3iQ5zhkAQ5N4+QiGHUPR9HK8BcBn+sBR0smFBySuOR56zUHSNqth6iur8CBV -mTxtLRwuLnWW2HKX4AzKaXPudSsVCeCObbvaE/9GqOgADKwHLx25urnRoPeZnnRc -GQVmMc8+KlL+b5/zub35wYH1N9ouTIElXfbZlJrTNYsgKDdfUet9Ysepk9H50DTL -qScmLCiQkjtVY7cXDlRzq6987DqrcDOsIfsiJrOGrCOp139tywgg8q9A9f9ER3Hd -J90TKKHqdjn5EKCgTUCkJ7JZFStsLSS3JGN490MYeg9NEePorIdCjedYcaSrbqLA -l3y74xNLytu7awj5abQEctXDRrl36v+6++nwOgw19o8PrgaEFt2UVdTvyie3AzzF -HCYq9TyopZWbhvGKiWf4xwxmse1Bv4KmAGg6IjTuHuvlb4l0T2qqaqhXZ1LUIGHB -zlPL/SR/XybfoQhplqCe/klD4tPq2sTxiDEhbhzhzfN1DiBEFsx9c3Q1RSw7gdQg -7LYJjD5IskkCAwEAAaOBojCBnzALBgNVHQ8EBAMCAQYwDAYDVR0TBAUwAwEB/zBj -BgNVHSUEXDBaBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcD -BAYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEFBQcDBwYIKwYBBQUHAwgGCCsGAQUF -BwMJMB0GA1UdDgQWBBTZw9P4gJJnzF3SOqLXcaK0xDiALTANBgkqhkiG9w0BAQUF -AAOCAgEA0Ih5ygiq9ws0oE4Jwul+NUiJcIQjL1HDKy9e21NrW3UIKlS6Mg7VxnGF -sZdJgPaE0PC6t3GUyHlrpsVE6EKirSUtVy/m1jEp+hmJVCl+t35HNmktbjK81HXa -QnO4TuWDQHOyXd/URHOmYgvbqm4FjMh/Rk85hZCdvBtUKayl1/7lWFZXbSyZoUkh -1WHGjGHhdSTBAd0tGzbDLxLMC9Z4i3WA6UG5iLHKPKkWxk4V43I29tSgQYWvimVw -TbVEEFDs7d9t5tnGwBLxSzovc+k8qe4bqi81pZufTcU0hF8mFGmzI7GJchT46U1R -IgP/SobEHOh7eQrbRyWBfvw0hKxZuFhD5D1DCVR0wtD92e9uWfdyYJl2b/Unp7uD -pEqB7CmB9HdL4UISVdSGKhK28FWbAS7d9qjjGcPORy/AeGEYWsdl/J1GW1fcfA67 -loMQfFUYCQSu0feLKj6g5lDWMDbX54s4U+xJRODPpN/xU3uLWrb2EZBL1nXz/gLz -Ka/wI3J9FO2pXd96gZ6bkiL8HvgBRUGXx2sBYb4zaPKgZYRmvOAqpGjTcezHCN6j -w8k2SjTxF+KAryAhk5Qe5hXTVGLxtTgv48y5ZwSpuuXu+RBuyy5+E6+SFP7zJ3N7 -OPxzbbm5iPZujAv1/P8JDrMtXnt145Ik4ubhWD5LKAN1axibRww= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDhDCCAmygAwIBAgIBCTANBgkqhkiG9w0BAQUFADAzMQswCQYDVQQGEwJDTjER -MA8GA1UEChMIVW5pVHJ1c3QxETAPBgNVBAMTCFVDQSBSb290MB4XDTA0MDEwMTAw -MDAwMFoXDTI5MTIzMTAwMDAwMFowMzELMAkGA1UEBhMCQ04xETAPBgNVBAoTCFVu -aVRydXN0MREwDwYDVQQDEwhVQ0EgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBALNdB8qGJn1r4vs4CQ7MgsJqGgCiFV/W6dQBt1YDAVmP9ThpJHbC -XivF9iu/r/tB/Q9a/KvXg3BNMJjRnrJ2u5LWu+kQKGkoNkTo8SzXWHwk1n8COvCB -a2FgP/Qz3m3l6ihST/ypHWN8C7rqrsRoRuTej8GnsrZYWm0dLNmMOreIy4XU9+gD -Xv2yTVDo1h//rgI/i0+WITyb1yXJHT/7mLFZ5PCpO6+zzYUs4mBGzG+OoOvwNMXx -QhhgrhLtRnUc5dipllq+3lrWeGeWW5N3UPJuG96WUUqm1ktDdSFmjXfsAoR2XEQQ -th1hbOSjIH23jboPkXXHjd+8AmCoKai9PUMCAwEAAaOBojCBnzALBgNVHQ8EBAMC -AQYwDAYDVR0TBAUwAwEB/zBjBgNVHSUEXDBaBggrBgEFBQcDAQYIKwYBBQUHAwIG -CCsGAQUFBwMDBggrBgEFBQcDBAYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEFBQcD -BwYIKwYBBQUHAwgGCCsGAQUFBwMJMB0GA1UdDgQWBBTbHzXza0z/QjFkm827Wh4d -SBC37jANBgkqhkiG9w0BAQUFAAOCAQEAOGy3iPGt+lg3dNHocN6cJ1nL5BXXoMNg -14iABMUwTD3UGusGXllH5rxmy+AI/Og17GJ9ysDawXiv5UZv+4mCI4/211NmVaDe -JRI7cTYWVRJ2+z34VFsxugAG+H1V5ad2g6pcSpemKijfvcZsCyOVjjN/Hl5AHxNU -LJzltQ7dFyiuawHTUin1Ih+QOfTcYmjwPIZH7LgFRbu3DJaUxmfLI3HQjnQi1kHr -A6i26r7EARK1s11AdgYg1GS4KUYGis4fk5oQ7vuqWrTcL9Ury/bXBYSYBZELhPc9 -+tb5evosFeo2gkO3t7jj83EB7UNDogVFwygFBzXjAaU4HoDU18PZ3g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl -eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT -JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx -MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT -Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg -VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo -I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng -o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G -A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB -zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW -RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB -iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl -cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV -BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw -MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV -BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU -aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy -dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK -AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B -3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY -tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ -Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 -VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT -79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 -c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT -Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l -c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee -UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE -Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd -BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G -A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF -Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO -VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 -ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs -8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR -iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze -Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ -XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ -qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB -VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB -L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG -jjxDah2nGN59PRbxYvnKkKj9 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB -kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug -Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw -IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG -EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD -VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu -dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN -BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6 -E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ -D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK -4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq -lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW -bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB -o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT -MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js -LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr -BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB -AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft -Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj -j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH -KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv -2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3 -mfnGV/TJVTl4uix5yaaIK/QI ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEojCCA4qgAwIBAgIQRL4Mi1AAJLQR0zYlJWfJiTANBgkqhkiG9w0BAQUFADCB -rjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug -Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0BgNVBAMTLVVUTi1VU0VSRmlyc3Qt -Q2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBFbWFpbDAeFw05OTA3MDkxNzI4NTBa -Fw0xOTA3MDkxNzM2NThaMIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAV -BgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5l -dHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UE -AxMtVVROLVVTRVJGaXJzdC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWls -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsjmFpPJ9q0E7YkY3rs3B -YHW8OWX5ShpHornMSMxqmNVNNRm5pELlzkniii8efNIxB8dOtINknS4p1aJkxIW9 -hVE1eaROaJB7HHqkkqgX8pgV8pPMyaQylbsMTzC9mKALi+VuG6JG+ni8om+rWV6l -L8/K2m2qL+usobNqqrcuZzWLeeEeaYji5kbNoKXqvgvOdjp6Dpvq/NonWz1zHyLm -SGHGTPNpsaguG7bUMSAsvIKKjqQOpdeJQ/wWWq8dcdcRWdq6hw2v+vPhwvCkxWeM -1tZUOt4KpLoDd7NlyP0e03RiqhjKaJMeoYV+9Udly/hNVyh00jT/MLbu9mIwFIws -6wIDAQABo4G5MIG2MAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud -DgQWBBSJgmd9xJ0mcABLtFBIfN49rgRufTBYBgNVHR8EUTBPME2gS6BJhkdodHRw -Oi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1DbGllbnRBdXRoZW50 -aWNhdGlvbmFuZEVtYWlsLmNybDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH -AwQwDQYJKoZIhvcNAQEFBQADggEBALFtYV2mGn98q0rkMPxTbyUkxsrt4jFcKw7u -7mFVbwQ+zznexRtJlOTrIEy05p5QLnLZjfWqo7NK2lYcYJeA3IKirUq9iiv/Cwm0 -xtcgBEXkzYABurorbs6q15L+5K/r9CYdFip/bDCVNy8zEqx/3cfREYxRmLLQo5HQ -rfafnoOTHh1CuEava2bwm3/q4wMC5QJRwarVNZ1yQAOJujEdxRBoUp7fooXFXAim -eOZTT7Hot9MUnpOmw2TjrH5xzbyf6QMbzPvprDHBr3wVdAKZw7JHpsIyYdfHb0gk -USeh1YdV8nuPmD0Wnu51tvjQjvLzxq4oW6fw8zYX/MMF08oDSlQ= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB -lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug -Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt -SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG -A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe -MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v -d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh -cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn -0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ -M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a -MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd -oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI -DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy -oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD -VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0 -dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy -bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF -BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM -//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli -CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE -CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t -3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS -KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEZjCCA06gAwIBAgIQRL4Mi1AAJLQR0zYt4LNfGzANBgkqhkiG9w0BAQUFADCB -lTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug -Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHTAbBgNVBAMTFFVUTi1VU0VSRmlyc3Qt -T2JqZWN0MB4XDTk5MDcwOTE4MzEyMFoXDTE5MDcwOTE4NDAzNlowgZUxCzAJBgNV -BAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkxHjAc -BgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8GA1UECxMYaHR0cDovL3d3 -dy51c2VydHJ1c3QuY29tMR0wGwYDVQQDExRVVE4tVVNFUkZpcnN0LU9iamVjdDCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6qgT+jo2F4qjEAVZURnicP -HxzfOpuCaDDASmEd8S8O+r5596Uj71VRloTN2+O5bj4x2AogZ8f02b+U60cEPgLO -KqJdhwQJ9jCdGIqXsqoc/EHSoTbL+z2RuufZcDX65OeQw5ujm9M89RKZd7G3CeBo -5hy485RjiGpq/gt2yb70IuRnuasaXnfBhQfdDWy/7gbHd2pBnqcP1/vulBe3/IW+ -pKvEHDHd17bR5PDv3xaPslKT16HUiaEHLr/hARJCHhrh2JU022R5KP+6LhHC5ehb -kkj7RwvCbNqtMoNB86XlQXD9ZZBt+vpRxPm9lisZBCzTbafc8H9vg2XiaquHhnUC -AwEAAaOBrzCBrDALBgNVHQ8EBAMCAcYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E -FgQU2u1kdBScFDyr3ZmpvVsoTYs8ydgwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDov -L2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmlyc3QtT2JqZWN0LmNybDApBgNV -HSUEIjAgBggrBgEFBQcDAwYIKwYBBQUHAwgGCisGAQQBgjcKAwQwDQYJKoZIhvcN -AQEFBQADggEBAAgfUrE3RHjb/c652pWWmKpVZIC1WkDdIaXFwfNfLEzIR1pp6ujw -NTX00CXzyKakh0q9G7FzCL3Uw8q2NbtZhncxzaeAFK4T7/yxSPlrJSUtUbYsbUXB -mMiKVl0+7kNOPmsnjtA6S4ULX9Ptaqd1y9Fahy85dRNacrACgZ++8A+EVCBibGnU -4U3GDZlDAQ0Slox4nb9QorFEqmrPF3rPbw/U+CRVX/A0FklmPlBGyWNxODFiuGK5 -81OtbLUrohKqGU8J2l7nk8aOFAj+8DCAGKCGhU3IfdeLA/5u1fedFqySLKAj5ZyR -Uh+U3xeUc8OzwcFxBSAAeL0TUh2oPs0AH8g= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl -cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu -LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT -aWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp -dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD -VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT -aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ -bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu -IENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg -LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN2E1Lm0+afY8wR4 -nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/EbRrsC+MO -8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjV -ojYJrKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjb -PG7PoBMAGrgnoeS+Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP2 -6KbqxzcSXKMpHgLZ2x87tNcPVkeBFQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vr -n5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAq2aN17O6x5q25lXQBfGfMY1a -qtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/Ny9Sn2WCVhDr4 -wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3 -ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrs -pSCAaWihT37ha88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4 -E1Z5T21Q6huwtVexN2ZYI/PcD98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJ -BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVy -aVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24s -IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNp -Z24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 -eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJBgNV -BAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNp -Z24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIElu -Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24g -Q2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt -IEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArwoNwtUs22e5LeWU -J92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6tW8UvxDO -JxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUY -wZF7C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9o -koqQHgiBVrKtaaNS0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjN -qWm6o+sdDZykIKbBoMXRRkwXbdKsZj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/E -Srg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0JhU8wI1NQ0kdvekhktdmnLfe -xbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf0xwLRtxyID+u -7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU -sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RI -sH/7NiXaldDxJBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTP -cjnhsUPgKM+351psE2tJs//jGHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl -cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu -LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT -aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp -dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD -VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT -aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ -bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu -IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg -LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b -N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t -KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu -kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm -CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ -Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu -imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te -2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe -DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC -/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p -F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt -TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL -MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW -ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln -biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp -U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y -aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG -A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp -U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg -SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln -biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm -GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve -fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ -aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj -aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW -kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC -4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga -FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB -yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL -ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp -U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW -ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL -MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW -ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln -biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp -U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y -aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1 -nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex -t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz -SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG -BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+ -rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/ -NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E -BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH -BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy -aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv -MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE -p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y -5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK -WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ -4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N -hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB -vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL -ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp -U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W -ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe -Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX -MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0 -IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y -IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh -bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF -9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH -H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H -LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN -/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT -rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud -EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw -WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs -exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud -DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4 -sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+ -seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz -4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+ -BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR -lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3 -7M2CYfE45k+XmCpajQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr -MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl -cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv -bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw -CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h -dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l -cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h -2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E -lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV -ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq -299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t -vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL -dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD -AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF -AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR -zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3 -LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd -7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw -++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt -398znM/jra6O1I7mT1GvFpLgXPYHDw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID+TCCAuGgAwIBAgIQW1fXqEywr9nTb0ugMbTW4jANBgkqhkiG9w0BAQUFADB5 -MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl -cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xKjAoBgNVBAMTIVZpc2EgSW5m -b3JtYXRpb24gRGVsaXZlcnkgUm9vdCBDQTAeFw0wNTA2MjcxNzQyNDJaFw0yNTA2 -MjkxNzQyNDJaMHkxCzAJBgNVBAYTAlVTMQ0wCwYDVQQKEwRWSVNBMS8wLQYDVQQL -EyZWaXNhIEludGVybmF0aW9uYWwgU2VydmljZSBBc3NvY2lhdGlvbjEqMCgGA1UE -AxMhVmlzYSBJbmZvcm1hdGlvbiBEZWxpdmVyeSBSb290IENBMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyREA4R/QkkfpLx0cYjga/EhIPZpchH0MZsRZ -FfP6C2ITtf/Wc+MtgD4yTK0yoiXvni3d+aCtEgK3GDvkdgYrgF76ROJFZwUQjQ9l -x42gRT05DbXvWFoy7dTglCZ9z/Tt2Cnktv9oxKgmkeHY/CyfpCBg1S8xth2JlGMR -0ug/GMO5zANuegZOv438p5Lt5So+du2Gl+RMFQqEPwqN5uJSqAe0VtmB4gWdQ8on -Bj2ZAM2R73QW7UW0Igt2vA4JaSiNtaAG/Y/58VXWHGgbq7rDtNK1R30X0kJV0rGA -ib3RSwB3LpG7bOjbIucV5mQgJoVjoA1e05w6g1x/KmNTmOGRVwIDAQABo30wezAP -BgNVHRMBAf8EBTADAQH/MDkGA1UdIAQyMDAwLgYFZ4EDAgEwJTAVBggrBgEFBQcC -ARYJMS4yLjMuNC41MAwGCCsGAQUFBwICMAAwDgYDVR0PAQH/BAQDAgEGMB0GA1Ud -DgQWBBRPitp2/2d3I5qmgH1924h1hfeBejANBgkqhkiG9w0BAQUFAAOCAQEACUW1 -QdUHdDJydgDPmYt+telnG/Su+DPaf1cregzlN43bJaJosMP7NwjoJY/H2He4XLWb -5rXEkl+xH1UyUwF7mtaUoxbGxEvt8hPZSTB4da2mzXgwKvXuHyzF5Qjy1hOB0/pS -WaF9ARpVKJJ7TOJQdGKBsF2Ty4fSCLqZLgfxbqwMsd9sysXI3rDXjIhekqvbgeLz -PqZr+pfgFhwCCLSMQWl5Ll3u7Qk9wR094DZ6jj6+JCVCRUS3HyabH4OlM0Vc2K+j -INsF/64Or7GNtRf9HYEJvrPxHINxl3JVwhYj4ASeaO4KwhVbwtw94Tc/XrGcexDo -c5lC3rAi4/UZqweYCw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEGjCCAwKgAwIBAgIDAYagMA0GCSqGSIb3DQEBBQUAMIGjMQswCQYDVQQGEwJG -STEQMA4GA1UECBMHRmlubGFuZDEhMB8GA1UEChMYVmFlc3RvcmVraXN0ZXJpa2Vz -a3VzIENBMSkwJwYDVQQLEyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBTZXJ2aWNl -czEZMBcGA1UECxMQVmFybWVubmVwYWx2ZWx1dDEZMBcGA1UEAxMQVlJLIEdvdi4g -Um9vdCBDQTAeFw0wMjEyMTgxMzUzMDBaFw0yMzEyMTgxMzUxMDhaMIGjMQswCQYD -VQQGEwJGSTEQMA4GA1UECBMHRmlubGFuZDEhMB8GA1UEChMYVmFlc3RvcmVraXN0 -ZXJpa2Vza3VzIENBMSkwJwYDVQQLEyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBT -ZXJ2aWNlczEZMBcGA1UECxMQVmFybWVubmVwYWx2ZWx1dDEZMBcGA1UEAxMQVlJL -IEdvdi4gUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALCF -FdrIAzfQo0Y3bBseljDCWoUSZyPyu5/nioFgJ/gTqTy894aqqvTzJSm0/nWuHoGG -igWyHWWyOOi0zCia+xc28ZPVec7Bg4shT8MNrUHfeJ1I4x9CRPw8bSEga60ihCRC -jxdNwlAfZM0tOSJWiP2yY51U2kJpwMhP1xjiPshphJQ9LIDGfM6911Mf64i5psu7 -hVfvV3ZdDIvTXhJBnyHAOfQmbQj6OLOhd7HuFtjQaNq0mKWgZUZKa41+qk1guPjI -DfxxPu45h4G02fhukO4/DmHXHSto5i7hQkQmeCxY8n0Wf2HASSQqiYe2XS8pGfim -545SnkFLWg6quMJmQlMCAwEAAaNVMFMwDwYDVR0TAQH/BAUwAwEB/zARBglghkgB -hvhCAQEEBAMCAAcwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBTb6eGb0tEkC/yr -46Bn6q6cS3f0sDANBgkqhkiG9w0BAQUFAAOCAQEArX1ID1QRnljurw2bEi8hpM2b -uoRH5sklVSPj3xhYKizbXvfNVPVRJHtiZ+GxH0mvNNDrsczZog1Sf0JLiGCXzyVy -t08pLWKfT6HAVVdWDsRol5EfnGTCKTIB6dTI2riBmCguGMcs/OubUpbf9MiQGS0j -8/G7cdqehSO9Gu8u5Hp5t8OdhkktY7ktdM9lDzJmid87Ie4pbzlj2RXBbvbfgD5Q -eBmK3QOjFKU3p7UsfLYRh+cF8ry23tT/l4EohP7+bEaFEEGfTXWMB9SZZ291im/k -UJL2mdUQuMSpe/cXjUu/15WfCdxEDx4yw8DP03kN5Mc7h/CQNIghYkmSBAQfvA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB -gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk -MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY -UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx -NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 -dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy -dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 -38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP -KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q -DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 -qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa -JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi -PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P -BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs -jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 -eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD -ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR -vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt -qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa -IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy -i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ -O+7ETPTsJ3xCwnR8gooJybQDJbw= ------END CERTIFICATE----- -` diff --git a/libgo/go/crypto/x509/root_darwin_ios.go b/libgo/go/crypto/x509/root_darwin_ios.go new file mode 100644 index 00000000000..5ecc4911b35 --- /dev/null +++ b/libgo/go/crypto/x509/root_darwin_ios.go @@ -0,0 +1,5262 @@ +// Code generated by root_darwin_ios_gen.go -version 55161.80.1; DO NOT EDIT. +// Update the version in root.go and regenerate with "go generate". + +// +build darwin,arm64 darwin,amd64,ios +// +build !x509omitbundledroots + +package x509 + +func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) { + return nil, nil +} + +// loadSystemRootsWithCgo is not available on iOS. +var loadSystemRootsWithCgo func() (*CertPool, error) + +func loadSystemRoots() (*CertPool, error) { + p := NewCertPool() + p.AppendCertsFromPEM([]byte(systemRootsPEM)) + return p, nil +} + +const systemRootsPEM = ` +# "AAA Certificate Services" +# D7 A7 A0 FB 5D 7E 27 31 D7 71 E9 48 4E BC DE F7 +# 1D 5F 0C 3E 0A 29 48 78 2B C8 3E E0 EA 69 9E F4 +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj +YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM +GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua +BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe +3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 +YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR +rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm +ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU +oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v +QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t +b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF +AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q +GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 +G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi +l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 +smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- +# "AC RAIZ FNMT-RCM" +# EB C5 57 0C 29 01 8C 4D 67 B1 AA 12 7B AF 12 F7 +# 03 B4 61 1E BC 17 B7 DA B5 57 38 94 17 9B 93 FA +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx +CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ +WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ +BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG +Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ +yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf +BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz +WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF +tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z +374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC +IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL +mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 +wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS +MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 +ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet +UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H +YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 +LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 +RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM +LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf +77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N +JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm +fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp +6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp +1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B +9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok +RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv +uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- +# "Actalis Authentication Root CA" +# 55 92 60 84 EC 96 3A 64 B9 6E 2A BE 01 CE 0B A8 +# 6A 64 FB FE BC C7 AA B5 AF C1 55 B3 7F D7 60 66 +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE +BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w +MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC +SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 +ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv +UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX +4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 +KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ +gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb +rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ +51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F +be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe +KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F +v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn +fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 +jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz +ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL +e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 +jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz +WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V +SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j +pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX +X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok +fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R +K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU +ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU +LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT +LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- +# "AddTrust Class 1 CA Root" +# 8C 72 09 27 9A C0 4E 27 5E 16 D0 7F D3 B7 75 E8 +# 01 54 B5 96 80 46 E3 1F 52 DD 25 76 63 24 E9 A7 +-----BEGIN CERTIFICATE----- +MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 +b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMw +MTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYD +VQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ul +CDtbKRY654eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6n +tGO0/7Gcrjyvd7ZWxbWroulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyl +dI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJch +PXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC ++Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0O +BBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBl +MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk +ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENB +IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0MkhHma6X +7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0PhiVYrqW9yTkkz +43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY +eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJl +pz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOA +WiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk= +-----END CERTIFICATE----- +# "AddTrust External CA Root" +# 68 7F A4 51 38 22 78 FF F0 C8 B1 1F 8D 43 D5 76 +# 67 1C 6E B2 BC EA B4 13 FB 83 D9 65 D0 6D 2F F2 +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs +IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 +MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux +FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h +bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt +H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 +uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX +mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX +a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN +E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 +WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD +VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 +Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU +cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx +IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN +AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH +YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC +Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX +c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a +mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +-----END CERTIFICATE----- +# "Admin-Root-CA" +# A3 1F 09 30 53 BD 12 C1 F5 C3 C6 EF D4 98 02 3F +# D2 91 4D 77 58 D0 5D 69 8C E0 84 B5 06 26 E0 E5 +-----BEGIN CERTIFICATE----- +MIIFVTCCBD2gAwIBAgIEO/OB0DANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQGEwJj +aDEOMAwGA1UEChMFYWRtaW4xETAPBgNVBAsTCFNlcnZpY2VzMSIwIAYDVQQLExlD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRYwFAYDVQQDEw1BZG1pbi1Sb290LUNB +MB4XDTAxMTExNTA4NTEwN1oXDTIxMTExMDA3NTEwN1owbDELMAkGA1UEBhMCY2gx +DjAMBgNVBAoTBWFkbWluMREwDwYDVQQLEwhTZXJ2aWNlczEiMCAGA1UECxMZQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdGllczEWMBQGA1UEAxMNQWRtaW4tUm9vdC1DQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMvgr0QUIv5qF0nyXZ3PXAJi +C4C5Wr+oVTN7oxIkXkxvO0GJToM9n7OVJjSmzBL0zJ2HXj0MDRcvhSY+KiZZc6Go +vDvr5Ua481l7ILFeQAFtumeza+vvxeL5Nd0Maga2miiacLNAKXbAcUYRa0Ov5VZB +++YcOYNNt/aisWbJqA2y8He+NsEgJzK5zNdayvYXQTZN+7tVgWOck16Da3+4FXdy +fH1NCWtZlebtMKtERtkVAaVbiWW24CjZKAiVfggjsiLo3yVMPGj3budLx5D9hEEm +vlyDOtcjebca+AcZglppWMX/iHIrx7740y0zd6cWEqiLIcZCrnpkr/KzwO135GkC +AwEAAaOCAf0wggH5MA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIASBkTCBjjCBiwYI +YIV0AREDAQAwfzArBggrBgEFBQcCAjAfGh1UaGlzIGlzIHRoZSBBZG1pbi1Sb290 +LUNBIENQUzBQBggrBgEFBQcCARZEaHR0cDovL3d3dy5pbmZvcm1hdGlrLmFkbWlu +LmNoL1BLSS9saW5rcy9DUFNfMl8xNl83NTZfMV8xN18zXzFfMC5wZGYwfwYDVR0f +BHgwdjB0oHKgcKRuMGwxFjAUBgNVBAMTDUFkbWluLVJvb3QtQ0ExIjAgBgNVBAsT +GUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxETAPBgNVBAsTCFNlcnZpY2VzMQ4w +DAYDVQQKEwVhZG1pbjELMAkGA1UEBhMCY2gwHQYDVR0OBBYEFIKf+iNzIPGXi7JM +Tb5CxX9mzWToMIGZBgNVHSMEgZEwgY6AFIKf+iNzIPGXi7JMTb5CxX9mzWTooXCk +bjBsMQswCQYDVQQGEwJjaDEOMAwGA1UEChMFYWRtaW4xETAPBgNVBAsTCFNlcnZp +Y2VzMSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRYwFAYDVQQD +Ew1BZG1pbi1Sb290LUNBggQ784HQMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0B +AQUFAAOCAQEAeE96XCYRpy6umkPKXDWCRn7INo96ZrWpMggcDORuofHIwdTkgOeM +vWOxDN/yuT7CC3FAaUajbPRbDw0hRMcqKz0aC8CgwcyIyhw/rFK29mfNTG3EviP9 +QSsEbnelFnjpm1wjz4EaBiFjatwpUbI6+Zv3XbEt9QQXBn+c6DeFLe4xvC4B+MTr +a440xTk59pSYux8OHhEvqIwHCkiijGqZhTS3KmGFeBopaR+dJVBRBMoXwzk4B3Hn +0Zib1dEYFZa84vPJZyvxCbLOnPRDJgH6V2uQqbG+6DXVaf/wORVOvF/wzzv0viM/ +RWbEtJZdvo8N3sdtCULzifnxP/V0T9+4ZQ== +-----END CERTIFICATE----- +# "AffirmTrust Commercial" +# 03 76 AB 1D 54 C5 F9 80 3C E4 B2 E2 01 A0 EE 7E +# EF 7B 57 B6 36 E8 A9 3C 9B 8D 48 60 C9 6F 5F A7 +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP +Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr +ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL +MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 +yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr +VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ +nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG +XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj +vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt +Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g +N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC +nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- +# "AffirmTrust Networking" +# 0A 81 EC 5A 92 97 77 F1 45 90 4A F3 8D 5D 50 9F +# 66 B5 E2 C5 8F CD B5 31 05 8B 0E 17 F3 F0 B4 1B +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y +YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua +kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL +QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp +6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG +yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i +QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO +tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu +QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ +Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u +olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 +x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- +# "AffirmTrust Premium" +# 70 A7 3F 7F 37 6B 60 07 42 48 90 45 34 B1 14 82 +# D5 BF 0E 69 8E CC 49 8D F5 25 77 EB F2 E9 3B 9A +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz +dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG +A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U +cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf +qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ +JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ ++jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS +s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 +HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 +70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG +V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S +qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S +5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia +C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX +OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE +FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 +KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B +8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ +MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc +0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ +u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF +u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH +YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 +GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO +RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e +KeC2uAloGRwYQw== +-----END CERTIFICATE----- +# "AffirmTrust Premium ECC" +# BD 71 FD F6 DA 97 E4 CF 62 D1 64 7A DD 25 81 B0 +# 7D 79 AD F8 39 7E B4 EC BA 9C 5E 84 88 82 14 23 +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC +VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ +cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ +BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt +VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D +0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 +ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G +A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs +aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I +flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== +-----END CERTIFICATE----- +# "Amazon Root CA 1" +# 8E CD E6 88 4F 3D 87 B1 12 5B A3 1A C3 FC B1 3D +# 70 16 DE 7F 57 CC 90 4F E1 CB 97 C6 AE 98 19 6E +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj +ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM +9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw +IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 +VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L +93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm +jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA +A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI +U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs +N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv +o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU +5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy +rqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- +# "Amazon Root CA 2" +# 1B A5 B2 AA 8C 65 40 1A 82 96 01 18 F8 0B EC 4F +# 62 30 4D 83 CE C4 71 3A 19 C3 9C 01 1E A4 6D B4 +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK +gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ +W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg +1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K +8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r +2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me +z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR +8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj +mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz +7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 ++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI +0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm +UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 +LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS +k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl +7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm +btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl +urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ +fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 +n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE +76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H +9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT +4PsJYGw= +-----END CERTIFICATE----- +# "Amazon Root CA 3" +# 18 CE 6C FE 7B F1 4E 60 B2 E3 47 B8 DF E8 68 CB +# 31 D0 2E BB 3A DA 27 15 69 F5 03 43 B4 6D B3 A4 +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl +ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr +ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr +BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM +YyRIHN8wfdVoOw== +-----END CERTIFICATE----- +# "Amazon Root CA 4" +# E3 5D 28 41 9E D0 20 25 CF A6 90 38 CD 62 39 62 +# 45 8D A5 C6 95 FB DE A3 C2 2B 0B FB 25 89 70 92 +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi +9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk +M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB +MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw +CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW +1KyLa2tJElMzrdfkviT8tQp21KW8EA== +-----END CERTIFICATE----- +# "ANF Global Root CA" +# E3 26 8F 61 06 BA 8B 66 5A 1A 96 2D DE A1 45 9D +# 2A 46 97 2F 1F 24 40 32 9B 39 0B 89 57 49 AD 45 +-----BEGIN CERTIFICATE----- +MIIIGDCCBgCgAwIBAgIGAT8vMXfmMA0GCSqGSIb3DQEBCwUAMIIBCjELMAkGA1UE +BhMCRVMxEjAQBgNVBAgMCUJhcmNlbG9uYTFYMFYGA1UEBwxPQmFyY2Vsb25hIChz +ZWUgY3VycmVudCBhZGRyZXNzIGF0IGh0dHA6Ly93d3cuYW5mLmVzL2VzL2FkZHJl +c3MtZGlyZWNjaW9uLmh0bWwgKTEnMCUGA1UECgweQU5GIEF1dG9yaWRhZCBkZSBD +ZXJ0aWZpY2FjaW9uMRcwFQYDVQQLDA5BTkYgQ2xhc2UgMSBDQTEaMBgGCSqGSIb3 +DQEJARYLaW5mb0BhbmYuZXMxEjAQBgNVBAUTCUc2MzI4NzUxMDEbMBkGA1UEAwwS +QU5GIEdsb2JhbCBSb290IENBMB4XDTEzMDYxMDE3NDUzOFoXDTMzMDYwNTE3NDUz +OFowggEKMQswCQYDVQQGEwJFUzESMBAGA1UECAwJQmFyY2Vsb25hMVgwVgYDVQQH +DE9CYXJjZWxvbmEgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgaHR0cDovL3d3dy5h +bmYuZXMvZXMvYWRkcmVzcy1kaXJlY2Npb24uaHRtbCApMScwJQYDVQQKDB5BTkYg +QXV0b3JpZGFkIGRlIENlcnRpZmljYWNpb24xFzAVBgNVBAsMDkFORiBDbGFzZSAx +IENBMRowGAYJKoZIhvcNAQkBFgtpbmZvQGFuZi5lczESMBAGA1UEBRMJRzYzMjg3 +NTEwMRswGQYDVQQDDBJBTkYgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDHPi9xy4wynbcUbWjorVUgQKeUAVh937J7P37XmsfH +ZLOBZKIIlhhCtRwnDlg7x+BUvtJOTkIbEGMujDygUQ2s3HDYr5I41hTyM2Pl0cq2 +EuSGEbPIHb3dEX8NAguFexM0jqNjrreN3hM2/+TOkAxSdDJP2aMurlySC5zwl47K +ZLHtcVrkZnkDa0o5iN24hJT4vBDT4t2q9khQ+qb1D8KgCOb02r1PxWXu3vfd6Ha2 +mkdB97iGuEh5gO2n4yOmFS5goFlVA2UdPbbhJsb8oKVKDd+YdCKGQDCkQyG4AjmC +YiNm3UPG/qtftTH5cWri67DlLtm6fyUFOMmO6NSh0RtR745pL8GyWJUanyq/Q4bF +HQB21E+WtTsCaqjGaoFcrBunMypmCd+jUZXl27TYENRFbrwNdAh7m2UztcIyb+Sg +VJFyfvVsBQNvnp7GPimVxXZNc4VpxEXObRuPWQN1oZN/90PcZVqTia/SHzEyTryL +ckhiLG3jZiaFZ7pTZ5I9wti9Pn+4kOHvE3Y/4nEnUo4mTxPX9pOlinF+VCiybtV2 +u1KSlc+YaIM7VmuyndDZCJRXm3v0/qTE7t5A5fArZl9lvibigMbWB8fpD+c1GpGH +Eo8NRY0lkaM+DkIqQoaziIsz3IKJrfdKaq9bQMSlIfameKBZ8fNYTBZrH9KZAIhz +YwIDAQABo4IBfjCCAXowHQYDVR0OBBYEFIf6nt9SdnXsSUogb1twlo+d77sXMB8G +A1UdIwQYMBaAFIf6nt9SdnXsSUogb1twlo+d77sXMA8GA1UdEwEB/wQFMAMBAf8w +DgYDVR0PAQH/BAQDAgEGMIIBFQYDVR0RBIIBDDCCAQiCEWh0dHA6Ly93d3cuYW5m +LmVzgQtpbmZvQGFuZi5lc6SB5TCB4jE0MDIGA1UECQwrR3JhbiBWaWEgZGUgbGVz +IENvcnRzIENhdGFsYW5lcy4gOTk2LiAwODAxODESMBAGA1UEBwwJQmFyY2Vsb25h +MScwJQYDVQQKDB5BTkYgQXV0b3JpZGFkIGRlIENlcnRpZmljYWNpb24xEjAQBgNV +BAUTCUc2MzI4NzUxMDFZMFcGA1UECwxQSW5zY3JpdGEgZW4gZWwgTWluaXN0ZXJp +byBkZWwgSW50ZXJpb3IgZGUgRXNwYcOxYSBjb24gZWwgbnVtZXJvIG5hY2lvbmFs +IDE3MS40NDMwDQYJKoZIhvcNAQELBQADggIBAIgR9tFTZ9BCYg+HViMxOfF0MHN2 +Pe/eC128ARdS+GH8A4thtbqiH/SOYbWofO/0zssHhNKa5iQEj45lCAb8BANpWJMD +nWkPr6jq2+50a6d0MMgSS2l1rvjSF+3nIrEuicshHXSTi3q/vBLKr7uGKMVFaM68 +XAropIwk6ndlA0JseARSPsbetv7ALESMIZAxlHV1TcctYHd0bB3c/Jz+PLszJQqs +Cg/kBPo2D111OXZkIY8W/fJuG9veR783khAK2gUnC0zLLCNsYzEbdGt8zUmBsAsM +cGxqGm6B6vDXd65OxWqw13xdq/24+5R8Ng1PF9tvfjZkUFBF30CxjWur7P90WiKI +G7IGfr6BE1NgXlhEQQu4F+HizB1ypEPzGWltecXQ4yOzO+H0WfFTjLTYX6VSveyW +DQV18ixF8M4tHP/SwNE+yyv2b2JJ3/3RpxjtFlLk+opJ574x0gD/dMJuWTH0JqVY +3PbRfE1jIxFpk164Qz/Xp7H7w7f6xh+tQCkBs3PUYmnGIZcPwq44Q6JHlCNsKx4K +hxfggTvRCk4w79cUID45c2qDsRCqTPoOo/cbOpcfVhbH9LdMORpmuLwNogRZEUSE +fWpqR9q+0kcQf4zGSWIURIyDrogdpDgoHDxktqgMgc+qA4ZE2WQl1D8hmev53A46 +lUSrWUiWfDXtK3ux +-----END CERTIFICATE----- +# "Apple Root CA" +# B0 B1 73 0E CB C7 FF 45 05 14 2C 49 F1 29 5E 6E +# DA 6B CA ED 7E 2C 68 C5 BE 91 B5 A1 10 01 F0 24 +-----BEGIN CERTIFICATE----- +MIIEuzCCA6OgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJVUzET +MBEGA1UEChMKQXBwbGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkxFjAUBgNVBAMTDUFwcGxlIFJvb3QgQ0EwHhcNMDYwNDI1MjE0 +MDM2WhcNMzUwMjA5MjE0MDM2WjBiMQswCQYDVQQGEwJVUzETMBEGA1UEChMKQXBw +bGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx +FjAUBgNVBAMTDUFwcGxlIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDkkakJH5HbHkdQ6wXtXnmELes2oldMVeyLGYne+Uts9QerIjAC6Bg+ ++FAJ039BqJj50cpmnCRrEdCju+QbKsMflZ56DKRHi1vUFjczy8QPTc4UadHJGXL1 +XQ7Vf1+b8iUDulWPTV0N8WQ1IxVLFVkds5T39pyez1C6wVhQZ48ItCD3y6wsIG9w +tj8BMIy3Q88PnT3zK0koGsj+zrW5DtleHNbLPbU6rfQPDgCSC7EhFi501TwN22IW +q6NxkkdTVcGvL0Gz+PvjcM3mo0xFfh9Ma1CWQYnEdGILEINBhzOKgbEwWOxaBDKM +aLOPHd5lc/9nXmW8Sdh2nzMUZaF3lMktAgMBAAGjggF6MIIBdjAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUK9BpR5R2Cf70a40uQKb3 +R01/CF4wHwYDVR0jBBgwFoAUK9BpR5R2Cf70a40uQKb3R01/CF4wggERBgNVHSAE +ggEIMIIBBDCCAQAGCSqGSIb3Y2QFATCB8jAqBggrBgEFBQcCARYeaHR0cHM6Ly93 +d3cuYXBwbGUuY29tL2FwcGxlY2EvMIHDBggrBgEFBQcCAjCBthqBs1JlbGlhbmNl +IG9uIHRoaXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFzc3VtZXMgYWNjZXB0 +YW5jZSBvZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5kYXJkIHRlcm1zIGFuZCBj +b25kaXRpb25zIG9mIHVzZSwgY2VydGlmaWNhdGUgcG9saWN5IGFuZCBjZXJ0aWZp +Y2F0aW9uIHByYWN0aWNlIHN0YXRlbWVudHMuMA0GCSqGSIb3DQEBBQUAA4IBAQBc +NplMLXi37Yyb3PN3m/J20ncwT8EfhYOFG5k9RzfyqZtAjizUsZAS2L70c5vu0mQP +y3lPNNiiPvl4/2vIB+x9OYOLUyDTOMSxv5pPCmv/K/xZpwUJfBdAVhEedNO3iyM7 +R6PVbyTi69G3cN8PReEnyvFteO3ntRcXqNx+IjXKJdXZD9Zr1KIkIxH3oayPc4Fg +xhtbCS+SsvhESPBgOJ4V9T0mZyCKM2r3DYLP3uujL/lTaltkwGMzd/c6ByxW69oP +IQ7aunMZT7XZNn/Bh1XZp5m5MkL72NVxnn6hUrcbvZNCJBIqxw8dtk2cXmPIS4AX +UKqK1drk/NAJBzewdXUh +-----END CERTIFICATE----- +# "Apple Root CA - G2" +# C2 B9 B0 42 DD 57 83 0E 7D 11 7D AC 55 AC 8A E1 +# 94 07 D3 8E 41 D8 8F 32 15 BC 3A 89 04 44 A0 50 +-----BEGIN CERTIFICATE----- +MIIFkjCCA3qgAwIBAgIIAeDltYNno+AwDQYJKoZIhvcNAQEMBQAwZzEbMBkGA1UE +AwwSQXBwbGUgUm9vdCBDQSAtIEcyMSYwJAYDVQQLDB1BcHBsZSBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMw +HhcNMTQwNDMwMTgxMDA5WhcNMzkwNDMwMTgxMDA5WjBnMRswGQYDVQQDDBJBcHBs +ZSBSb290IENBIC0gRzIxJjAkBgNVBAsMHUFwcGxlIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MRMwEQYDVQQKDApBcHBsZSBJbmMuMQswCQYDVQQGEwJVUzCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBANgREkhI2imKScUcx+xuM23+TfvgHN6s +XuI2pyT5f1BrTM65MFQn5bPW7SXmMLYFN14UIhHF6Kob0vuy0gmVOKTvKkmMXT5x +ZgM4+xb1hYjkWpIMBDLyyED7Ul+f9sDx47pFoFDVEovy3d6RhiPw9bZyLgHaC/Yu +OQhfGaFjQQscp5TBhsRTL3b2CtcM0YM/GlMZ81fVJ3/8E7j4ko380yhDPLVoACVd +J2LT3VXdRCCQgzWTxb+4Gftr49wIQuavbfqeQMpOhYV4SbHXw8EwOTKrfl+q04tv +ny0aIWhwZ7Oj8ZhBbZF8+NfbqOdfIRqMM78xdLe40fTgIvS/cjTf94FNcX1RoeKz +8NMoFnNvzcytN31O661A4T+B/fc9Cj6i8b0xlilZ3MIZgIxbdMYs0xBTJh0UT8TU +gWY8h2czJxQI6bR3hDRSj4n4aJgXv8O7qhOTH11UL6jHfPsNFL4VPSQ08prcdUFm +IrQB1guvkJ4M6mL4m1k8COKWNORj3rw31OsMiANDC1CvoDTdUE0V+1ok2Az6DGOe +HwOx4e7hqkP0ZmUoNwIx7wHHHtHMn23KVDpA287PT0aLSmWaasZobNfMmRtHsHLD +d4/E92GcdB/O/WuhwpyUgquUoue9G7q5cDmVF8Up8zlYNPXEpMZ7YLlmQ1A/bmH8 +DvmGqmAMQ0uVAgMBAAGjQjBAMB0GA1UdDgQWBBTEmRNsGAPCe8CjoA1/coB6HHcm +jTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQwF +AAOCAgEAUabz4vS4PZO/Lc4Pu1vhVRROTtHlznldgX/+tvCHM/jvlOV+3Gp5pxy+ +8JS3ptEwnMgNCnWefZKVfhidfsJxaXwU6s+DDuQUQp50DhDNqxq6EWGBeNjxtUVA +eKuowM77fWM3aPbn+6/Gw0vsHzYmE1SGlHKy6gLti23kDKaQwFd1z4xCfVzmMX3z +ybKSaUYOiPjjLUKyOKimGY3xn83uamW8GrAlvacp/fQ+onVJv57byfenHmOZ4VxG +/5IFjPoeIPmGlFYl5bRXOJ3riGQUIUkhOb9iZqmxospvPyFgxYnURTbImHy99v6Z +SYA7LNKmp4gDBDEZt7Y6YUX6yfIjyGNzv1aJMbDZfGKnexWoiIqrOEDCzBL/FePw +N983csvMmOa/orz6JopxVtfnJBtIRD6e/J/JzBrsQzwBvDR4yGn1xuZW7AYJNpDr +FEobXsmII9oDMJELuDY++ee1KG++P+w8j2Ud5cAeh6Squpj9kuNsJnfdBrRkBof0 +Tta6SqoWqPQFZ2aWuuJVecMsXUmPgEkrihLHdoBR37q9ZV0+N0djMenl9MU/S60E +inpxLK8JQzcPqOMyT/RFtm2XNuyE9QoB6he7hY1Ck3DDUOUUi78/w0EP3SIEIwiK +um1xRKtzCTrJ+VKACd+66eYWyi4uTLLT3OUEVLLUNIAytbwPF+E= +-----END CERTIFICATE----- +# "Apple Root CA - G3" +# 63 34 3A BF B8 9A 6A 03 EB B5 7E 9B 3F 5F A7 BE +# 7C 4F 5C 75 6F 30 17 B3 A8 C4 88 C3 65 3E 91 79 +-----BEGIN CERTIFICATE----- +MIICQzCCAcmgAwIBAgIILcX8iNLFS5UwCgYIKoZIzj0EAwMwZzEbMBkGA1UEAwwS +QXBwbGUgUm9vdCBDQSAtIEczMSYwJAYDVQQLDB1BcHBsZSBDZXJ0aWZpY2F0aW9u +IEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwHhcN +MTQwNDMwMTgxOTA2WhcNMzkwNDMwMTgxOTA2WjBnMRswGQYDVQQDDBJBcHBsZSBS +b290IENBIC0gRzMxJjAkBgNVBAsMHUFwcGxlIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRMwEQYDVQQKDApBcHBsZSBJbmMuMQswCQYDVQQGEwJVUzB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABJjpLz1AcqTtkyJygRMc3RCV8cWjTnHcFBbZDuWmBSp3ZHtf +TjjTuxxEtX/1H7YyYl3J6YRbTzBPEVoA/VhYDKX1DyxNB0cTddqXl5dvMVztK517 +IDvYuVTZXpmkOlEKMaNCMEAwHQYDVR0OBBYEFLuw3qFYM4iapIqZ3r6966/ayySr +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2gA +MGUCMQCD6cHEFl4aXTQY2e3v9GwOAEZLuN+yRhHFD/3meoyhpmvOwgPUnPWTxnS4 +at+qIxUCMG1mihDK1A3UT82NQz60imOlM27jbdoXt2QfyFMm+YhidDkLF1vLUagM +6BgD56KyKA== +-----END CERTIFICATE----- +# "Apple Root Certificate Authority" +# 0D 83 B6 11 B6 48 A1 A7 5E B8 55 84 00 79 53 75 +# CA D9 2E 26 4E D8 E9 D7 A7 57 C1 F5 EE 2B B2 2D +-----BEGIN CERTIFICATE----- +MIIFujCCBKKgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhjELMAkGA1UEBhMCVVMx +HTAbBgNVBAoTFEFwcGxlIENvbXB1dGVyLCBJbmMuMS0wKwYDVQQLEyRBcHBsZSBD +b21wdXRlciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxKTAnBgNVBAMTIEFwcGxlIFJv +b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTA1MDIxMDAwMTgxNFoXDTI1MDIx +MDAwMTgxNFowgYYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRBcHBsZSBDb21wdXRl +ciwgSW5jLjEtMCsGA1UECxMkQXBwbGUgQ29tcHV0ZXIgQ2VydGlmaWNhdGUgQXV0 +aG9yaXR5MSkwJwYDVQQDEyBBcHBsZSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 +eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOSRqQkfkdseR1DrBe1e +eYQt6zaiV0xV7IsZid75S2z1B6siMALoGD74UAnTf0GomPnRymacJGsR0KO75Bsq +wx+VnnoMpEeLW9QWNzPLxA9NzhRp0ckZcvVdDtV/X5vyJQO6VY9NXQ3xZDUjFUsV +WR2zlPf2nJ7PULrBWFBnjwi0IPfLrCwgb3C2PwEwjLdDzw+dPfMrSSgayP7OtbkO +2V4c1ss9tTqt9A8OAJILsSEWLnTVPA3bYharo3GSR1NVwa8vQbP4++NwzeajTEV+ +H0xrUJZBicR0YgsQg0GHM4qBsTBY7FoEMoxos48d3mVz/2deZbxJ2HafMxRloXeU +yS0CAwEAAaOCAi8wggIrMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ +MB0GA1UdDgQWBBQr0GlHlHYJ/vRrjS5ApvdHTX8IXjAfBgNVHSMEGDAWgBQr0GlH +lHYJ/vRrjS5ApvdHTX8IXjCCASkGA1UdIASCASAwggEcMIIBGAYJKoZIhvdjZAUB +MIIBCTBBBggrBgEFBQcCARY1aHR0cHM6Ly93d3cuYXBwbGUuY29tL2NlcnRpZmlj +YXRlYXV0aG9yaXR5L3Rlcm1zLmh0bWwwgcMGCCsGAQUFBwICMIG2GoGzUmVsaWFu +Y2Ugb24gdGhpcyBjZXJ0aWZpY2F0ZSBieSBhbnkgcGFydHkgYXNzdW1lcyBhY2Nl +cHRhbmNlIG9mIHRoZSB0aGVuIGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5k +IGNvbmRpdGlvbnMgb2YgdXNlLCBjZXJ0aWZpY2F0ZSBwb2xpY3kgYW5kIGNlcnRp +ZmljYXRpb24gcHJhY3RpY2Ugc3RhdGVtZW50cy4wRAYDVR0fBD0wOzA5oDegNYYz +aHR0cHM6Ly93d3cuYXBwbGUuY29tL2NlcnRpZmljYXRlYXV0aG9yaXR5L3Jvb3Qu +Y3JsMFUGCCsGAQUFBwEBBEkwRzBFBggrBgEFBQcwAoY5aHR0cHM6Ly93d3cuYXBw +bGUuY29tL2NlcnRpZmljYXRlYXV0aG9yaXR5L2Nhc2lnbmVycy5odG1sMA0GCSqG +SIb3DQEBBQUAA4IBAQCd2i0oWC99dgS5BNM+zrdmY06PL9T+S61yvaM5xlJNBZhS +9YlRASR5vhoy9+VEi0tEBzmC1lrKtCBe2a4VXR2MHTK/ODFiSF3H4ZCx+CRA+F9Y +m1FdV53B5f88zHIhbsTp6aF31ywXJsM/65roCwO66bNKcuszCVut5mIxauivL9Wv +Hld2j383LS4CXN1jyfJxuCZA3xWNdUQ/eb3mHZnhQyw+rW++uaT+DjUZUWOxw961 +kj5ReAFziqQjyqSI8R5cH0EWLX6VCqrpiUGYGxrdyyC/R14MJsVVNU3GMIuZZxTH +CR+6R8faAQmHJEKVvRNgGQrv6n8Obs3BREM6StXj +-----END CERTIFICATE----- +# "ApplicationCA2 Root" +# 12 6B F0 1C 10 94 D2 F0 CA 2E 35 23 80 B3 C7 24 +# 29 45 46 CC C6 55 97 BE F7 F1 2D 8A 17 1F 19 84 +-----BEGIN CERTIFICATE----- +MIID9zCCAt+gAwIBAgILMTI1MzcyODI4MjgwDQYJKoZIhvcNAQELBQAwWDELMAkG +A1UEBhMCSlAxHDAaBgNVBAoTE0phcGFuZXNlIEdvdmVybm1lbnQxDTALBgNVBAsT +BEdQS0kxHDAaBgNVBAMTE0FwcGxpY2F0aW9uQ0EyIFJvb3QwHhcNMTMwMzEyMTUw +MDAwWhcNMzMwMzEyMTUwMDAwWjBYMQswCQYDVQQGEwJKUDEcMBoGA1UEChMTSmFw +YW5lc2UgR292ZXJubWVudDENMAsGA1UECxMER1BLSTEcMBoGA1UEAxMTQXBwbGlj +YXRpb25DQTIgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKaq +rSVl1gAR1uh6dqr05rRL88zDUrSNrKZPtZJxb0a11a2LEiIXJc5F6BR6hZrkIxCo ++rFnUOVtR+BqiRPjrq418fRCxQX3TZd+PCj8sCaRHoweOBqW3FhEl2LjMsjRFUFN +dZh4vqtoqV7tR76kuo6hApfek3SZbWe0BSXulMjtqqS6MmxCEeu+yxcGkOGThchk +KM4fR8fAXWDudjbcMztR63vPctgPeKgZggiQPhqYjY60zxU2pm7dt+JNQCBT2XYq +0HisifBPizJtROouurCp64ndt295D6uBbrjmiykLWa+2SQ1RLKn9nShjZrhwlXOa +2Po7M7xCQhsyrLEy+z0CAwEAAaOBwTCBvjAdBgNVHQ4EFgQUVqesqgIdsqw9kA6g +by5Bxnbne9owDgYDVR0PAQH/BAQDAgEGMHwGA1UdEQR1MHOkcTBvMQswCQYDVQQG +EwJKUDEYMBYGA1UECgwP5pel5pys5Zu95pS/5bqcMRswGQYDVQQLDBLmlL/lupzo +qo3oqLzln7rnm6QxKTAnBgNVBAMMIOOCouODl+ODquOCseODvOOCt+ODp+ODs0NB +MiBSb290MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAH+aCXWs +B9FydC53VzDCBJzUgKaD56WgG5/+q/OAvdVKo6GPtkxgEefK4WCB10jBIFmlYTKL +nZ6X02aD2mUuWD7b5S+lzYxzplG+WCigeVxpL0PfY7KJR8q73rk0EWOgDiUX5Yf0 +HbCwpc9BqHTG6FPVQvSCLVMJEWgmcZR1E02qdog8dLHW40xPYsNJTE5t8XB+w3+m +Bcx4m+mB26jIx1ye/JKSLaaX8ji1bnOVDMA/zqaUMLX6BbfeniCq/BNkyYq6ZO/i +Y+TYmK5rtT6mVbgzPixy+ywRAPtbFi+E0hOe+gXFwctyTiLdhMpLvNIthhoEdlkf +SUJiOxMfFui61/0= +-----END CERTIFICATE----- +# "Atos TrustedRoot 2011" +# F3 56 BE A2 44 B7 A9 1E B3 5D 53 CA 9A D7 86 4A +# CE 01 8E 2D 35 D5 F8 F9 6D DF 68 A6 F4 1A A4 74 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE +AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG +EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM +FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC +REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp +Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM +VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+ +SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ +4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L +cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi +eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG +A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3 +DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j +vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP +DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc +maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D +lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv +KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- +# "Autoridad de Certificacion Firmaprofesional CIF A62634068" +# 04 04 80 28 BF 1F 28 64 D4 8F 9A D4 D8 32 94 36 +# 6A 82 88 56 55 3F 3B 14 30 3F 90 14 7F 5D 40 EF +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy +MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD +VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv +ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl +AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF +661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 +am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 +ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 +PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS +3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k +SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF +3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM +ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g +StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz +Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB +jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V +-----END CERTIFICATE----- +# "Autoridad de Certificacion Raiz del Estado Venezolano" +# 0E D3 FF AB 6C 14 9C 8B 4E 71 05 8E 86 68 D4 29 +# AB FD A6 81 C2 FF F5 08 20 76 41 F0 D7 51 A3 E5 +-----BEGIN CERTIFICATE----- +MIIJmzCCB4OgAwIBAgIBATANBgkqhkiG9w0BAQwFADCCAR4xPjA8BgNVBAMTNUF1 +dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIFJhaXogZGVsIEVzdGFkbyBWZW5lem9s +YW5vMQswCQYDVQQGEwJWRTEQMA4GA1UEBxMHQ2FyYWNhczEZMBcGA1UECBMQRGlz +dHJpdG8gQ2FwaXRhbDE2MDQGA1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0 +aWZpY2FjaW9uIEVsZWN0cm9uaWNhMUMwQQYDVQQLEzpTdXBlcmludGVuZGVuY2lh +IGRlIFNlcnZpY2lvcyBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMSUwIwYJ +KoZIhvcNAQkBFhZhY3JhaXpAc3VzY2VydGUuZ29iLnZlMB4XDTEwMTIyMjE4MDgy +MVoXDTMwMTIxNzIzNTk1OVowggEeMT4wPAYDVQQDEzVBdXRvcmlkYWQgZGUgQ2Vy +dGlmaWNhY2lvbiBSYWl6IGRlbCBFc3RhZG8gVmVuZXpvbGFubzELMAkGA1UEBhMC +VkUxEDAOBgNVBAcTB0NhcmFjYXMxGTAXBgNVBAgTEERpc3RyaXRvIENhcGl0YWwx +NjA0BgNVBAoTLVNpc3RlbWEgTmFjaW9uYWwgZGUgQ2VydGlmaWNhY2lvbiBFbGVj +dHJvbmljYTFDMEEGA1UECxM6U3VwZXJpbnRlbmRlbmNpYSBkZSBTZXJ2aWNpb3Mg +ZGUgQ2VydGlmaWNhY2lvbiBFbGVjdHJvbmljYTElMCMGCSqGSIb3DQEJARYWYWNy +YWl6QHN1c2NlcnRlLmdvYi52ZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBAME77xNS8ZlW47RsBeEaaRZhJoZ4rw785UAFCuPZOAVMqNS1wMYqzy95q6Gk +UO81ER/ugiQX/KMcq/4HBn83fwdYWxPZfwBfK7BP2p/JsFgzYeFP0BXOLmvoJIzl +Jb6FW+1MPwGBjuaZGFImWZsSmGUclb51mRYMZETh9/J5CLThR1exStxHQptwSzra +zNFpkQY/zmj7+YZNA9yDoroVFv6sybYOZ7OxNDo7zkSLo45I7gMwtxqWZ8VkJZkC +8+p0dX6mkhUT0QAV64Zc9HsZiH/oLhEkXjhrgZ28cF73MXIqLx1fyM4kPH1yOJi/ +R72nMwL7D+Sd6mZgI035TxuHXc2/uOwXfKrrTjaJDz8Jp6DdessOkxIgkKXRjP+F +K3ze3n4NUIRGhGRtyvEjK95/2g02t6PeYiYVGur6ruS49n0RAaSS0/LJb6XzaAAe +0mmO2evnEqxIKwy2mZRNPfAVW1l3wCnWiUwryBU6OsbFcFFrQm+00wOicXvOTHBM +aiCVAVZTb9RSLyi+LJ1llzJZO3pq3IRiiBj38Nooo+2ZNbMEciSgmig7YXaUcmud +SVQvLSL+Yw+SqawyezwZuASbp7d/0rutQ59d81zlbMt3J7yB567rT2IqIydQ8qBW +k+fmXzghX+/FidYsh/aK+zZ7Wy68kKHuzEw1Vqkat5DGs+VzAgMBAAGjggLeMIIC +2jASBgNVHRMBAf8ECDAGAQH/AgECMDcGA1UdEgQwMC6CD3N1c2NlcnRlLmdvYi52 +ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAzNi0wMB0GA1UdDgQWBBStuyIdxuDS +Aaj9dlBSk+2YwU2u0zCCAVAGA1UdIwSCAUcwggFDgBStuyIdxuDSAaj9dlBSk+2Y +wU2u06GCASakggEiMIIBHjE+MDwGA1UEAxM1QXV0b3JpZGFkIGRlIENlcnRpZmlj +YWNpb24gUmFpeiBkZWwgRXN0YWRvIFZlbmV6b2xhbm8xCzAJBgNVBAYTAlZFMRAw +DgYDVQQHEwdDYXJhY2FzMRkwFwYDVQQIExBEaXN0cml0byBDYXBpdGFsMTYwNAYD +VQQKEy1TaXN0ZW1hIE5hY2lvbmFsIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25p +Y2ExQzBBBgNVBAsTOlN1cGVyaW50ZW5kZW5jaWEgZGUgU2VydmljaW9zIGRlIENl +cnRpZmljYWNpb24gRWxlY3Ryb25pY2ExJTAjBgkqhkiG9w0BCQEWFmFjcmFpekBz +dXNjZXJ0ZS5nb2IudmWCAQEwDgYDVR0PAQH/BAQDAgEGMDcGA1UdEQQwMC6CD3N1 +c2NlcnRlLmdvYi52ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAzNi0wMFQGA1Ud +HwRNMEswJKAioCCGHmhodHA6Ly93d3cuc3VzY2VydGUuZ29iLnZlL2xjcjAjoCGg +H4YdbGRhcDovL2FjcmFpei5zdXNjZXJ0ZS5nb2IudmUwNwYIKwYBBQUHAQEEKzAp +MCcGCCsGAQUFBzABhhtoaHRwOi8vb2NzcC5zdXNjZXJ0ZS5nb2IudmUwQAYDVR0g +BDkwNzA1BgVghl4BAjAsMCoGCCsGAQUFBwIBFh5odHRwOi8vd3d3LnN1c2NlcnRl +LmdvYi52ZS9kcGMwDQYJKoZIhvcNAQEMBQADggIBAK4qy/zmZ9zBwfW3yOYtLcBT +Oy4szJyPz7/RhNH3bPVH7HbDTGpi6JZ4YXdXMBeJE5qBF4a590Kgj8Rlnltt+Rbo +OFQOU1UDqKuTdBsA//Zry5899fmn8jBUkg4nh09jhHHbLlaUScdz704Zz2+UVg7i +s/r3Legxap60KzmdrmTAE9VKte1TQRgavQwVX5/2mO/J+SCas//UngI+h8SyOucq +mjudYEgBrZaodUsagUfn/+AzFNrGLy+al+5nZeHb8JnCfLHWS0M9ZyhgoeO/czyn +99+5G93VWNv4zfc4KiavHZKrkn8F9pg0ycIZh+OwPT/RE2zq4gTazBMlP3ACIe/p +olkNaOEa8KvgzW96sjBZpMW49zFmyINYkcj+uaNCJrVGsXgdBmkuRGJNWFZ9r0cG +woIaxViFBypsz045r1ESfYPlfDOavBhZ/giR/Xocm9CHkPRY2BApMMR0DUCyGETg +Ql+L3kfdTKzuDjUp2DM9FqysQmaM81YDZufWkMhlZPfHwC7KbNougoLroa5Umeos +bqAXWmk46SwIdWRPLLqbUpDTKooynZKpSYIkkotdgJoVZUUCY+RCO8jsVPEU6ece +SxztNUm5UOta1OJPMwSAKRHOo3ilVb9c6lAixDdvV8MeNbqe6asM1mpCHWbJ/0rg +5Ls9Cxx8hracyp0ev7b0 +-----END CERTIFICATE----- +# "Baltimore CyberTrust Root" +# 16 AF 57 A9 F6 76 B0 AB 12 60 95 AA 5E BA DE F2 +# 2A B3 11 19 D6 44 AC 95 CD 4B 93 DB F3 F2 6A EB +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX +DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y +ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy +VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr +mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr +IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK +mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu +XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy +dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye +jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 +BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 +DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 +9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx +jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 +Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz +ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS +R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- +# "Belgium Root CA2" +# 9F 97 44 46 3B E1 37 14 75 4E 1A 3B EC F9 8C 08 +# CC 20 5E 4A B3 20 28 F4 E2 83 0C 4A 1B 27 75 B8 +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIIKv++n6Lw6YcwDQYJKoZIhvcNAQEFBQAwKDELMAkGA1UE +BhMCQkUxGTAXBgNVBAMTEEJlbGdpdW0gUm9vdCBDQTIwHhcNMDcxMDA0MTAwMDAw +WhcNMjExMjE1MDgwMDAwWjAoMQswCQYDVQQGEwJCRTEZMBcGA1UEAxMQQmVsZ2l1 +bSBSb290IENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMZzQh6S +/3UPi790hqc/7bIYLS2X+an7mEoj39WN4IzGMhwWLQdC1i22bi+n9fzGhYJdld61 +IgDMqFNAn68KNaJ6x+HK92AQZw6nUHMXU5WfIp8MXW+2QbyM69odRr2nlL/zGsvU ++40OHjPIltfsjFPekx40HopQcSZYtF3CiInaYNKJIT/e1wEYNm7hLHADBGXvmAYr +XR5i3FVr/mZkIV/4L+HXmymvb82fqgxG0YjFnaKVn6w/Fa7yYd/vw2uaItgscf1Y +HewApDgglVrH1Tdjuk+bqv5WRi5j2Qsj1Yr6tSPwiRuhFA0m2kHwOI8w7QUmecFL +TqG4flVSOmlGhHUCAwEAAaOBuzCBuDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zBCBgNVHSAEOzA5MDcGBWA4CQEBMC4wLAYIKwYBBQUHAgEWIGh0dHA6 +Ly9yZXBvc2l0b3J5LmVpZC5iZWxnaXVtLmJlMB0GA1UdDgQWBBSFiuv0xbu+DlkD +lN7WgAEV4xCcOTARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUhYrr9MW7 +vg5ZA5Te1oABFeMQnDkwDQYJKoZIhvcNAQEFBQADggEBAFHYhd27V2/MoGy1oyCc +UwnzSgEMdL8rs5qauhjyC4isHLMzr87lEwEnkoRYmhC598wUkmt0FoqW6FHvv/pK +JaeJtmMrXZRY0c8RcrYeuTlBFk0pvDVTC9rejg7NqZV3JcqUWumyaa7YwBO+mPyW +nIR/VRPmPIfjvCCkpDZoa01gZhz5v6yAlGYuuUGK02XThIAC71AdXkbc98m6tTR8 +KvPG2F9fVJ3bTc0R5/0UAoNmXsimABKgX77OFP67H6dh96tK8QYUn8pJQsKpvO2F +sauBQeYNxUJpU4c5nUwfAA4+Bw11V0SoU7Q2dmSZ3G7rPUZuFF1eR1ONeE3gJ7uO +hXY= +-----END CERTIFICATE----- +# "Buypass Class 2 Root CA" +# 9A 11 40 25 19 7C 5B B9 5D 94 E6 3D 55 CD 43 79 +# 08 47 B6 46 B2 3C DF 11 AD A4 A0 0E FF 15 FB 48 +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr +6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV +L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 +1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx +MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ +QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB +arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr +Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi +FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS +P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN +9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz +uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h +9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t +OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo ++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 +KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 +DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us +H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ +I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 +5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h +3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz +Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= +-----END CERTIFICATE----- +# "Buypass Class 3 Root CA" +# ED F7 EB BC A2 7A 2A 38 4D 38 7B 7D 40 10 C6 66 +# E2 ED B4 84 3E 4C 29 B4 AE 1D 5B 93 32 E6 B2 4D +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y +ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E +N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 +tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX +0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c +/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X +KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY +zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS +O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D +34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP +K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv +Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj +QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS +IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 +HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa +O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv +033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u +dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE +kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 +3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD +u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq +4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= +-----END CERTIFICATE----- +# "CA Disig Root R1" +# F9 6F 23 F4 C3 E7 9C 07 7A 46 98 8D 5A F5 90 06 +# 76 A0 F0 39 CB 64 5D D1 75 49 B2 16 C8 24 40 CE +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAMMDmu5QkG4oMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNV +BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu +MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIxMB4XDTEyMDcxOTA5MDY1NloXDTQy +MDcxOTA5MDY1NlowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx +EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjEw +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqw3j33Jijp1pedxiy3QRk +D2P9m5YJgNXoqqXinCaUOuiZc4yd39ffg/N4T0Dhf9Kn0uXKE5Pn7cZ3Xza1lK/o +OI7bm+V8u8yN63Vz4STN5qctGS7Y1oprFOsIYgrY3LMATcMjfF9DCCMyEtztDK3A +fQ+lekLZWnDZv6fXARz2m6uOt0qGeKAeVjGu74IKgEH3G8muqzIm1Cxr7X1r5OJe +IgpFy4QxTaz+29FHuvlglzmxZcfe+5nkCiKxLU3lSCZpq+Kq8/v8kiky6bM+TR8n +oc2OuRf7JT7JbvN32g0S9l3HuzYQ1VTW8+DiR0jm3hTaYVKvJrT1cU/J19IG32PK +/yHoWQbgCNWEFVP3Q+V8xaCJmGtzxmjOZd69fwX3se72V6FglcXM6pM6vpmumwKj +rckWtc7dXpl4fho5frLABaTAgqWjR56M6ly2vGfb5ipN0gTco65F97yLnByn1tUD +3AjLLhbKXEAz6GfDLuemROoRRRw1ZS0eRWEkG4IupZ0zXWX4Qfkuy5Q/H6MMMSRE +7cderVC6xkGbrPAXZcD4XW9boAo0PO7X6oifmPmvTiT6l7Jkdtqr9O3jw2Dv1fkC +yC2fg69naQanMVXVz0tv/wQFx1isXxYb5dKj6zHbHzMVTdDypVP1y+E9Tmgt2BLd +qvLmTZtJ5cUoobqwWsagtQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUiQq0OJMa5qvum5EY+fU8PjXQ04IwDQYJKoZI +hvcNAQEFBQADggIBADKL9p1Kyb4U5YysOMo6CdQbzoaz3evUuii+Eq5FLAR0rBNR +xVgYZk2C2tXck8An4b58n1KeElb21Zyp9HWc+jcSjxyT7Ff+Bw+r1RL3D65hXlaA +SfX8MPWbTx9BLxyE04nH4toCdu0Jz2zBuByDHBb6lM19oMgY0sidbvW9adRtPTXo +HqJPYNcHKfyyo6SdbhWSVhlMCrDpfNIZTUJG7L399ldb3Zh+pE3McgODWF3vkzpB +emOqfDqo9ayk0d2iLbYq/J8BjuIQscTK5GfbVSUZP/3oNn6z4eGBrxEWi1CXYBmC +AMBrTXO40RMHPuq2MU/wQppt4hF05ZSsjYSVPCGvxdpHyN85YmLLW1AL14FABZyb +7bq2ix4Eb5YgOe2kfSnbSM6C3NQCjR0EMVrHS/BsYVLXtFHCgWzN4funodKSds+x +DzdYpPJScWc/DIh4gInByLUfkmO+p3qKViwaqKactV2zY9ATIKHrkWzQjX2v3wvk +F7mGnjixlAxYjOBVqjtjbZqJYLhkKpLGN/R+Q0O3c+gB53+XD9fyexn9GtePyfqF +a3qdnom2piiZk4hA9z7NUaPK6u95RyG1/jLix8NRb76AdPCkwzryT+lf3xkK8jsT +Q6wxpLPn6/wY1gGp8yqPNg7rtLG8t0zJa7+h89n07eLw4+1knj0vllJPgFOL +-----END CERTIFICATE----- +# "CA Disig Root R2" +# E2 3D 4A 03 6D 7B 70 E9 F5 95 B1 42 20 79 D2 B9 +# 1E DF BB 1F B6 51 A0 63 3E AA 8A 9D C5 F8 07 03 +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV +BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu +MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy +MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx +EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe +NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH +PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I +x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe +QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR +yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO +QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 +H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ +QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD +i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs +nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 +rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI +hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf +GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb +lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka ++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal +TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i +nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 +gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr +G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os +zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x +L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- +# "Certigna" +# E3 B6 A2 DB 2E D7 CE 48 84 2F 7A C5 32 41 C7 B7 +# 1D 54 14 4B FB 40 C1 1F 3F 1D 0B 42 F5 EE A1 2D +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X +DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ +BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4 +QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny +gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw +zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q +130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2 +JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw +ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT +AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj +AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG +9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h +bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc +fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu +HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w +t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- +# "Certinomis - Autorité Racine" +# FC BF E2 88 62 06 F7 2B 27 59 3C 8B 07 02 97 E1 +# 2D 76 9E D1 0E D7 93 07 05 A8 09 8E FF C1 4D 17 +-----BEGIN CERTIFICATE----- +MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjET +MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAk +BgNVBAMMHUNlcnRpbm9taXMgLSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4 +Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNl +cnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYwJAYDVQQDDB1DZXJ0 +aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jY +F1AMnmHawE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N +8y4oH3DfVS9O7cdxbwlyLu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWe +rP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K +/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92NjMD2AR5vpTESOH2VwnHu +7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9qc1pkIuVC +28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6 +lSTClrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1E +nn1So2+WLhl+HPNbxxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB +0iSVL1N6aaLwD4ZFjliCK0wi1F6g530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql09 +5gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna4NH4+ej9Uji29YnfAgMBAAGj +WzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQN +jLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ +KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9s +ov3/4gbIOZ/xWqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZM +OH8oMDX/nyNTt7buFHAAQCvaR6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q +619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40nJ+U8/aGH88bc62UeYdocMMzpXDn +2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1BCxMjidPJC+iKunqj +o3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjvJL1v +nxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG +5ERQL1TEqkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWq +pdEdnV1j6CTmNhTih60bWfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZb +dsLLO7XSAPCjDuGtbkD326C00EauFddEwk01+dIL8hf2rGbVJLJP0RyZwG71fet0 +BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/vgt2Fl43N+bYdJeimUV5 +-----END CERTIFICATE----- +# "Certinomis - Root CA" +# 2A 99 F5 BC 11 74 B7 3C BB 1D 62 08 84 E0 1C 34 +# E5 1C CB 39 78 DA 12 5F 0E 33 26 88 83 BF 41 58 +-----BEGIN CERTIFICATE----- +MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjET +MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAb +BgNVBAMTFENlcnRpbm9taXMgLSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMz +MTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMx +FzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRDZXJ0aW5vbWlzIC0g +Um9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQosP5L2 +fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJfl +LieY6pOod5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQV +WZUKxkd8aRi5pwP5ynapz8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDF +TKWrteoB4owuZH9kb/2jJZOLyKIOSY008B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb +5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09xRLWtwHkziOC/7aOgFLSc +CbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE6OXWk6Ri +wsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJ +wx3tFvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SG +m/lg0h9tkQPTYKbVPZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4 +F2iw4lNVYC2vPsKD2NkJK/DAZNuHi5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZng +WVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I6tNxIqSSaHh0 +2TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF +AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/ +0KGRHCwPT5iVWVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWw +F6YSjNRieOpWauwK0kDDPAUwPk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZS +g081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAXlCOotQqSD7J6wWAsOMwaplv/8gzj +qh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJy29SWwNyhlCVCNSN +h4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9Iff/ +ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8V +btaw5BngDwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwj +Y/M50n92Uaf0yKHxDHYiI0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ +8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nMcyrDflOR1m749fPH0FFNjkulW+YZFzvW +gQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVrhkIGuUE= +-----END CERTIFICATE----- +# "Certplus Root CA G1" +# 15 2A 40 2B FC DF 2C D5 48 05 4D 22 75 B3 9C 7F +# CA 3E C0 97 80 78 B0 F0 EA 76 E5 61 A6 C7 43 3E +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgISESBVg+QtPlRWhS2DN7cs3EYRMA0GCSqGSIb3DQEBDQUA +MD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2Vy +dHBsdXMgUm9vdCBDQSBHMTAeFw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBa +MD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2Vy +dHBsdXMgUm9vdCBDQSBHMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +ANpQh7bauKk+nWT6VjOaVj0W5QOVsjQcmm1iBdTYj+eJZJ+622SLZOZ5KmHNr49a +iZFluVj8tANfkT8tEBXgfs+8/H9DZ6itXjYj2JizTfNDnjl8KvzsiNWI7nC9hRYt +6kuJPKNxQv4c/dMcLRC4hlTqQ7jbxofaqK6AJc96Jh2qkbBIb6613p7Y1/oA/caP +0FG7Yn2ksYyy/yARujVjBYZHYEMzkPZHogNPlk2dT8Hq6pyi/jQu3rfKG3akt62f +6ajUeD94/vI4CTYd0hYCyOwqaK/1jpTvLRN6HkJKHRUxrgwEV/xhc/MxVoYxgKDE +EW4wduOU8F8ExKyHcomYxZ3MVwia9Az8fXoFOvpHgDm2z4QTd28n6v+WZxcIbekN +1iNQMLAVdBM+5S//Ds3EC0pd8NgAM0lm66EYfFkuPSi5YXHLtaW6uOrc4nBvCGrc +h2c0798wct3zyT8j/zXhviEpIDCB5BmlIOklynMxdCm+4kLV87ImZsdo/Rmz5yCT +mehd4F6H50boJZwKKSTUzViGUkAksnsPmBIgJPaQbEfIDbsYIC7Z/fyL8inqh3SV +4EJQeIQEQWGw9CEjjy3LKCHyamz0GqbFFLQ3ZU+V/YDI+HLlJWvEYLF7bY5KinPO +WftwenMGE9nTdDckQQoRb5fc5+R+ob0V8rqHDz1oihYHAgMBAAGjYzBhMA4GA1Ud +DwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSowcCbkahDFXxd +Bie0KlHYlwuBsTAfBgNVHSMEGDAWgBSowcCbkahDFXxdBie0KlHYlwuBsTANBgkq +hkiG9w0BAQ0FAAOCAgEAnFZvAX7RvUz1isbwJh/k4DgYzDLDKTudQSk0YcbX8ACh +66Ryj5QXvBMsdbRX7gp8CXrc1cqh0DQT+Hern+X+2B50ioUHj3/MeXrKls3N/U/7 +/SMNkPX0XtPGYX2eEeAC7gkE2Qfdpoq3DIMku4NQkv5gdRE+2J2winq14J2by5BS +S7CTKtQ+FjPlnsZlFT5kOwQ/2wyPX1wdaR+v8+khjPPvl/aatxm2hHSco1S1cE5j +2FddUyGbQJJD+tZ3VTNPZNX70Cxqjm0lpu+F6ALEUz65noe8zDUa3qHpimOHZR4R +Kttjd5cUvpoUmRGywO6wT/gUITJDT5+rosuoD6o7BlXGEilXCNQ314cnrUlZp5Gr +RHpejXDbl85IULFzk/bwg2D5zfHhMf1bfHEhYxQUqq/F3pN+aLHsIqKqkHWetUNy +6mSjhEv9DKgma3GX7lZjZuhCVPnHHd/Qj1vfyDBviP4NxDMcU6ij/UgQ8uQKTuEV +V/xuZDDCVRHc6qnNSlSsKWNEz0pAoNZoWRsz+e86i9sgktxChL8Bq4fA1SCC28a5 +g4VCXA9DO2pJNdWY9BW/+mGBDAkgGNLQFwzLSABQ6XaCjGTXOqAHVcweMcDvOrRl +++O/QmueD6i9a5jc2NvLi6Td11n0bt3+qsOR0C5CB8AMTVPNJLFMWx5R9N/pkvo= +-----END CERTIFICATE----- +# "Certplus Root CA G2" +# 6C C0 50 41 E6 44 5E 74 69 6C 4C FB C9 F8 0F 54 +# 3B 7E AB BB 44 B4 CE 6F 78 7C 6A 99 71 C4 2F 17 +-----BEGIN CERTIFICATE----- +MIICHDCCAaKgAwIBAgISESDZkc6uo+jF5//pAq/Pc7xVMAoGCCqGSM49BAMDMD4x +CzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBs +dXMgUm9vdCBDQSBHMjAeFw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4x +CzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBs +dXMgUm9vdCBDQSBHMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABM0PW1aC3/BFGtat +93nwHcmsltaeTpwftEIRyoa/bfuFo8XlGVzX7qY/aWfYeOKmycTbLXku54uNAm8x +Ik0G42ByRZ0OQneezs/lf4WbGOT8zC5y0xaTTsqZY1yhBSpsBqNjMGEwDgYDVR0P +AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNqDYwJ5jtpMxjwj +FNiPwyCrKGBZMB8GA1UdIwQYMBaAFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMAoGCCqG +SM49BAMDA2gAMGUCMHD+sAvZ94OX7PNVHdTcswYO/jOYnYs5kGuUIe22113WTNch +p+e/IQ8rzfcq3IUHnQIxAIYUFuXcsGXCwI4Un78kFmjlvPl5adytRSv3tjFzzAal +U5ORGpOucGpnutee5WEaXw== +-----END CERTIFICATE----- +# "certSIGN ROOT CA" +# EA A9 62 C4 FA 4A 6B AF EB E4 15 19 6D 35 1C CD +# 88 8D 4F 53 F3 FA 8A E6 D7 C4 66 A9 4E 60 42 BB +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT +AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD +QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP +MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do +0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ +UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d +RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ +OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv +JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C +AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O +BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ +LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY +MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ +44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I +Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw +i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN +9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- +# "Certum CA" +# D8 E0 FE BC 1D B2 E3 8D 00 94 0F 37 D2 7D 41 34 +# 4D 99 3E 73 4B 99 D5 65 6D 97 78 D4 D8 14 36 24 +-----BEGIN CERTIFICATE----- +MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM +MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD +QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM +MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD +QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E +jG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo +ePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI +ULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu +Ob7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg +AKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7 +HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA +uI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa +TOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg +xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q +CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x +O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs +6GAqm4VKQPNriiTsBhYscw== +-----END CERTIFICATE----- +# "Certum Trusted Network CA" +# 5C 58 46 8D 55 F5 8E 49 7E 74 39 82 D2 B5 00 10 +# B6 D1 65 37 4A CF 83 A7 D4 A3 2D B7 68 C4 40 8E +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM +MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D +ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU +cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 +WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg +Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw +IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH +UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM +TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU +BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM +kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x +AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y +sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL +I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 +J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY +VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- +# "Certum Trusted Network CA 2" +# B6 76 F2 ED DA E8 77 5C D3 6C B0 F6 3C D1 D4 60 +# 39 61 F4 9E 62 65 BA 01 3A 2F 03 07 B6 D0 B8 04 +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB +gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu +QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG +A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz +OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ +VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 +b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA +DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn +0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB +OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE +fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E +Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m +o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i +sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW +OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez +Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS +adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n +3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ +F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf +CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 +XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm +djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ +WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb +AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq +P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko +b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj +XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P +5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi +DrW5viSP +-----END CERTIFICATE----- +# "CFCA EV ROOT" +# 5C C3 D7 8E 4E 1D 5E 45 54 7A 04 E6 87 3E 64 F9 +# 0C F9 53 6D 1C CC 2E F8 00 F3 55 C4 C5 FD 70 FD +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx +MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j +aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP +T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 +sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL +TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 +/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp +7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz +EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt +hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP +a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot +aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg +TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV +PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv +cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL +tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT +ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL +jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS +ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy +P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 +xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d +Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN +5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe +/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z +AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ +5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- +# "Chambers of Commerce Root" +# 0C 25 8A 12 A5 67 4A EF 25 F2 8B A7 DC FA EC EE +# A3 48 E5 41 E6 F5 CC 4E E6 3B 71 B3 61 60 6A C3 +-----BEGIN CERTIFICATE----- +MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn +MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL +ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg +b2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAxNjEzNDNaFw0zNzA5MzAxNjEzNDRa +MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBB +ODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIw +IAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0B +AQEFAAOCAQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtb +unXF/KGIJPov7coISjlUxFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0d +BmpAPrMMhe5cG3nCYsS4No41XQEMIwRHNaqbYE6gZj3LJgqcQKH0XZi/caulAGgq +7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jWDA+wWFjbw2Y3npuRVDM3 +0pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFVd9oKDMyX +roDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIG +A1UdEwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5j +aGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p +26EpW1eLTXYGduHRooowDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIA +BzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24ub3JnMCcGA1Ud +EgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYDVR0gBFEwTzBN +BgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz +aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEB +AAxBl8IahsAifJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZd +p0AJPaxJRUXcLo0waLIJuvvDL8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi +1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wNUPf6s+xCX6ndbcj0dc97wXImsQEc +XCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0 +eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu +tGWaIZDgqtCYvDi1czyL+Nw= +-----END CERTIFICATE----- +# "Chambers of Commerce Root - 2008" +# 06 3E 4A FA C4 91 DF D3 32 F3 08 9B 85 42 E9 46 +# 17 D8 93 D7 FE 94 4E 10 A7 93 7E E2 9D 96 93 C0 +-----BEGIN CERTIFICATE----- +MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz +IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz +MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj +dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw +EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp +MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9 +28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq +VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q +DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR +5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL +ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a +Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl +UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s ++12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5 +Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj +ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx +hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV +HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1 ++HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN +YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t +L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy +ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt +IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV +HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w +DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW +PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF +5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1 +glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH +FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2 +pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD +xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG +tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq +jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De +fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg +OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ +d0jQ +-----END CERTIFICATE----- +# "Cisco Root CA 2048" +# 83 27 BC 8C 9D 69 94 7B 3D E3 C2 75 11 53 72 67 +# F5 9C 21 B9 FA 7B 61 3F AF BC CD 53 B7 02 40 00 +-----BEGIN CERTIFICATE----- +MIIDQzCCAiugAwIBAgIQX/h7KCtU3I1CoxW1aMmt/zANBgkqhkiG9w0BAQUFADA1 +MRYwFAYDVQQKEw1DaXNjbyBTeXN0ZW1zMRswGQYDVQQDExJDaXNjbyBSb290IENB +IDIwNDgwHhcNMDQwNTE0MjAxNzEyWhcNMjkwNTE0MjAyNTQyWjA1MRYwFAYDVQQK +Ew1DaXNjbyBTeXN0ZW1zMRswGQYDVQQDExJDaXNjbyBSb290IENBIDIwNDgwggEg +MA0GCSqGSIb3DQEBAQUAA4IBDQAwggEIAoIBAQCwmrmrp68Kd6ficba0ZmKUeIhH +xmJVhEAyv8CrLqUccda8bnuoqrpu0hWISEWdovyD0My5jOAmaHBKeN8hF570YQXJ +FcjPFto1YYmUQ6iEqDGYeJu5Tm8sUxJszR2tKyS7McQr/4NEb7Y9JHcJ6r8qqB9q +VvYgDxFUl4F1pyXOWWqCZe+36ufijXWLbvLdT6ZeYpzPEApk0E5tzivMW/VgpSdH +jWn0f84bcN5wGyDWbs2mAag8EtKpP6BrXruOIIt6keO1aO6g58QBdKhTCytKmg9l +Eg6CTY5j/e/rmxrbU6YTYK/CfdfHbBcl1HP7R2RQgYCUTOG/rksc35LtLgXfAgED +o1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUJ/PI +FR5umgIJFq0roIlgX9p7L6owEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEF +BQADggEBAJ2dhISjQal8dwy3U8pORFBi71R803UXHOjgxkhLtv5MOhmBVrBW7hmW +Yqpao2TB9k5UM8Z3/sUcuuVdJcr18JOagxEu5sv4dEX+5wW4q+ffy0vhN4TauYuX +cB7w4ovXsNgOnbFp1iqRe6lJT37mjpXYgyc81WhJDtSd9i7rp77rMKSsH0T8lasz +Bvt9YAretIpjsJyp8qS5UwGH0GikJ3+r/+n6yUA4iGe0OcaEb1fJU9u6ju7AQ7L4 +CYNu/2bPPu8Xs1gYJQk0XuPL1hS27PKSb3TkL4Eq1ZKR4OCXPDJoBYVL0fdX4lId +kxpUnwVwwEpxYB5DC2Ae/qPOgRnhCzU= +-----END CERTIFICATE----- +# "Class 2 Primary CA" +# 0F 99 3C 8A EF 97 BA AF 56 87 14 0E D5 9A D1 82 +# 1B B4 AF AC F0 AA 9A 58 B5 D5 7A 33 8A 3A FB CB +-----BEGIN CERTIFICATE----- +MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw +PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz +cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9 +MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz +IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ +ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR +VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL +kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd +EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas +H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0 +HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud +DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4 +QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu +Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/ +AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8 +yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR +FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA +ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB +kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 +l7+ijrRU +-----END CERTIFICATE----- +# "COMODO Certification Authority" +# 0C 2C D6 3D F7 80 6F A3 99 ED E8 09 11 6B 57 5B +# F8 79 89 F0 65 18 F9 80 8C 86 05 03 17 8B AF 66 +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB +gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV +BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw +MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl +YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P +RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 +UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI +2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 +Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp ++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ +DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O +nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW +/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g +PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u +QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY +SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv +IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 +zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd +BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB +ZQ== +-----END CERTIFICATE----- +# "COMODO ECC Certification Authority" +# 17 93 92 7A 06 14 54 97 89 AD CE 2F 8F 34 F7 F0 +# B6 6D 0F 3A E3 A3 B8 4D 21 EC 15 DB BA 4F AD C7 +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT +IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw +MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy +ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N +T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR +FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J +cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW +BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm +fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv +GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- +# "COMODO RSA Certification Authority" +# 52 F0 E1 C4 E5 8E C6 29 29 1B 60 31 7F 07 46 71 +# B8 5D 7E A8 0D 5B 07 27 34 63 53 4B 32 B4 02 34 +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR +6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X +pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC +9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV +/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf +Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z ++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w +qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah +SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC +u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf +Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq +crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB +/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl +wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM +4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV +2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna +FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ +CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK +boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke +jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL +S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb +QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl +0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB +NVOFBkpdn627G190 +-----END CERTIFICATE----- +# "ComSign CA" +# AE 44 57 B4 0D 9E DA 96 67 7B 0D 3C 92 D5 7B 51 +# 77 AB D7 AC 10 37 95 83 56 D1 E0 94 51 8B E5 F2 +-----BEGIN CERTIFICATE----- +MIIDkzCCAnugAwIBAgIQFBOWgxRVjOp7Y+X8NId3RDANBgkqhkiG9w0BAQUFADA0 +MRMwEQYDVQQDEwpDb21TaWduIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQG +EwJJTDAeFw0wNDAzMjQxMTMyMThaFw0yOTAzMTkxNTAyMThaMDQxEzARBgNVBAMT +CkNvbVNpZ24gQ0ExEDAOBgNVBAoTB0NvbVNpZ24xCzAJBgNVBAYTAklMMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8ORUaSvTx49qROR+WCf4C9DklBKK +8Rs4OC8fMZwG1Cyn3gsqrhqg455qv588x26i+YtkbDqthVVRVKU4VbirgwTyP2Q2 +98CNQ0NqZtH3FyrV7zb6MBBC11PN+fozc0yz6YQgitZBJzXkOPqUm7h65HkfM/sb +2CEJKHxNGGleZIp6GZPKfuzzcuc3B1hZKKxC+cX/zT/npfo4sdAMx9lSGlPWgcxC +ejVb7Us6eva1jsz/D3zkYDaHL63woSV9/9JLEYhwVKZBqGdTUkJe5DSe5L6j7Kpi +Xd3DTKaCQeQzC6zJMw9kglcq/QytNuEMrkvF7zuZ2SOzW120V+x0cAwqTwIDAQAB +o4GgMIGdMAwGA1UdEwQFMAMBAf8wPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDovL2Zl +ZGlyLmNvbXNpZ24uY28uaWwvY3JsL0NvbVNpZ25DQS5jcmwwDgYDVR0PAQH/BAQD +AgGGMB8GA1UdIwQYMBaAFEsBmz5WGmU2dst7l6qSBe4y5ygxMB0GA1UdDgQWBBRL +AZs+VhplNnbLe5eqkgXuMucoMTANBgkqhkiG9w0BAQUFAAOCAQEA0Nmlfv4pYEWd +foPPbrxHbvUanlR2QnG0PFg/LUAlQvaBnPGJEMgOqnhPOAlXsDzACPw1jvFIUY0M +cXS6hMTXcpuEfDhOZAYnKuGntewImbQKDdSFc8gS4TXt8QUxHXOZDOuWyt3T5oWq +8Ir7dcHyCTxlZWTzTNity4hp8+SDtwy9F1qWF8pb/627HOkthIDYIb6FUtnUdLlp +hbpN7Sgy6/lhSuTENh4Z3G+EER+V9YMoGKgzkkMn3V0TBEVPh9VGzT2ouvDzuFYk +Res3x+F2T3I5GN9+dHLHcy056mDmrRGiVod7w2ia/viMcKjfZTL0pECMocJEAw6U +AGegcQCCSA== +-----END CERTIFICATE----- +# "ComSign Global Root CA" +# 26 05 87 5A FC C1 76 B2 D6 6D D6 6A 99 5D 7F 8D +# 5E BB 86 CE 12 0D 0E 7E 9E 7C 6E F2 94 A2 7D 4C +-----BEGIN CERTIFICATE----- +MIIGATCCA+mgAwIBAgIRAI9hcRW6eVgXjH0ROqzW264wDQYJKoZIhvcNAQELBQAw +RTEfMB0GA1UEAxMWQ29tU2lnbiBHbG9iYWwgUm9vdCBDQTEVMBMGA1UEChMMQ29t +U2lnbiBMdGQuMQswCQYDVQQGEwJJTDAeFw0xMTA3MTgxMDI0NTRaFw0zNjA3MTYx +MDI0NTVaMEUxHzAdBgNVBAMTFkNvbVNpZ24gR2xvYmFsIFJvb3QgQ0ExFTATBgNV +BAoTDENvbVNpZ24gTHRkLjELMAkGA1UEBhMCSUwwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQCyKClzKh3rm6n1nvigmV/VU1D4hSwYW2ro3VqpzpPo0Ph3 +3LguqjXd5juDwN4mpxTpD99d7Xu5X6KGTlMVtfN+bTbA4t3x7DU0Zqn0BE5XuOgs +3GLH41Vmr5wox1bShVpM+IsjcN4E/hMnDtt/Bkb5s33xCG+ohz5dlq0gA9qfr/g4 +O9lkHZXTCeYrmVzd/il4x79CqNvGkdL3um+OKYl8rg1dPtD8UsytMaDgBAopKR+W +igc16QJzCbvcinlETlrzP/Ny76BWPnAQgaYBULax/Q5thVU+N3sEOKp6uviTdD+X +O6i96gARU4H0xxPFI75PK/YdHrHjfjQevXl4J37FJfPMSHAbgPBhHC+qn/014DOx +46fEGXcdw2BFeIIIwbj2GH70VyJWmuk/xLMCHHpJ/nIF8w25BQtkPpkwESL6esaU +b1CyB4Vgjyf16/0nRiCAKAyC/DY/Yh+rDWtXK8c6QkXD2XamrVJo43DVNFqGZzbf +5bsUXqiVDOz71AxqqK+p4ek9374xPNMJ2rB5MLPAPycwI0bUuLHhLy6nAIFHLhut +TNI+6Y/soYpi5JSaEjcY7pxI8WIkUAzr2r+6UoT0vAdyOt7nt1y8844a7szo/aKf +woziHl2O1w6ZXUC30K+ptXVaOiW79pBDcbLZ9ZdbONhS7Ea3iH4HJNwktrBJLQID +AQABo4HrMIHoMA8GA1UdEwEB/wQFMAMBAf8wgYQGA1UdHwR9MHswPKA6oDiGNmh0 +dHA6Ly9mZWRpci5jb21zaWduLmNvLmlsL2NybC9jb21zaWduZ2xvYmFscm9vdGNh +LmNybDA7oDmgN4Y1aHR0cDovL2NybDEuY29tc2lnbi5jby5pbC9jcmwvY29tc2ln +bmdsb2JhbHJvb3RjYS5jcmwwDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBQCRZPY +DUhirGm6rgZbPvuqJpFQsTAfBgNVHSMEGDAWgBQCRZPYDUhirGm6rgZbPvuqJpFQ +sTANBgkqhkiG9w0BAQsFAAOCAgEAk1V5V9701xsfy4mfX+tP9Ln5e9h3N+QMwUfj +kr+k3e8iXOqADjTpUHeBkEee5tJq09ZLp/43F5tZ2eHdYq2ZEX7iWHCnOQet6Yw9 +SU1TahsrGDA6JJD9sdPFnNZooGsU1520e0zNB0dNWwxrWAmu4RsBxvEpWCJbvzQL +dOfyX85RWwli81OiVMBc5XvJ1mxsIIqli45oRynKtsWP7E+b0ISJ1n+XFLdQo/Nm +WA/5sDfT0F5YPzWdZymudMbXitimxC+n4oQE4mbQ4Zm718Iwg3pP9gMMcSc7Qc1J +kJHPH9O7gVubkKHuSYj9T3Ym6c6egL1pb4pz/uT7cT26Fiopc/jdqbe2EAfoJZkv +hlp/zdzOoXTWjiKNA5zmgWnZn943FuE9KMRyKtyi/ezJXCh8ypnqLIKxeFfZl69C +BwJsPXUTuqj8Fic0s3aZmmr7C4jXycP+Q8V+akMEIoHAxcd960b4wVWKqOcI/kZS +Q0cYqWOY1LNjznRt9lweWEfwDBL3FhrHOmD4++1N3FkkM4W+Q1b2WOL24clDMj+i +2n9Iw0lc1llHMSMvA5D0vpsXZpOgcCVahfXczQKi9wQ3oZyonJeWx4/rXdMtagAB +VBYGFuMEUEQtybI+eIbnp5peO2WAAblQI4eTy/jMVowe5tfMEXovV3sz9ULgmGb3 +DscLP1I= +-----END CERTIFICATE----- +# "ComSign Secured CA" +# 50 79 41 C7 44 60 A0 B4 70 86 22 0D 4E 99 32 57 +# 2A B5 D1 B5 BB CB 89 80 AB 1C B1 76 51 A8 44 D2 +-----BEGIN CERTIFICATE----- +MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAw +PDEbMBkGA1UEAxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWdu +MQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwx +GzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjEL +MAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGtWhf +HZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs49oh +gHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sW +v+bznkqH7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ue +Mv5WJDmyVIRD9YTC2LxBkMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr +9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d19guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt +6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUwAwEB/zBEBgNVHR8EPTA7 +MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29tU2lnblNl +Y3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58 +ADsAj8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkq +hkiG9w0BAQUFAAOCAQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7p +iL1DRYHjZiM/EoZNGeQFsOY3wo3aBijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtC +dsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtpFhpFfTMDZflScZAmlaxMDPWL +kz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP51qJThRv4zdL +hfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz +OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw== +-----END CERTIFICATE----- +# "D-TRUST Root CA 3 2013" +# A1 A8 6D 04 12 1E B8 7F 02 7C 66 F5 33 03 C2 8E +# 57 39 F9 43 FC 84 B3 8A D6 AF 00 90 35 DD 94 57 +-----BEGIN CERTIFICATE----- +MIIEDjCCAvagAwIBAgIDD92sMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxHzAdBgNVBAMMFkQtVFJVU1QgUm9vdCBD +QSAzIDIwMTMwHhcNMTMwOTIwMDgyNTUxWhcNMjgwOTIwMDgyNTUxWjBFMQswCQYD +VQQGEwJERTEVMBMGA1UECgwMRC1UcnVzdCBHbWJIMR8wHQYDVQQDDBZELVRSVVNU +IFJvb3QgQ0EgMyAyMDEzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +xHtCkoIf7O1UmI4SwMoJ35NuOpNcG+QQd55OaYhs9uFp8vabomGxvQcgdJhl8Ywm +CM2oNcqANtFjbehEeoLDbF7eu+g20sRoNoyfMr2EIuDcwu4QRjltr5M5rofmw7wJ +ySxrZ1vZm3Z1TAvgu8XXvD558l++0ZBX+a72Zl8xv9Ntj6e6SvMjZbu376Ml1wrq +WLbviPr6ebJSWNXwrIyhUXQplapRO5AyA58ccnSQ3j3tYdLl4/1kR+W5t0qp9x+u +loYErC/jpIF3t1oW/9gPP/a3eMykr/pbPBJbqFKJcu+I89VEgYaVI5973bzZNO98 +lDyqwEHC451QGsDkGSL8swIDAQABo4IBBTCCAQEwDwYDVR0TAQH/BAUwAwEB/zAd +BgNVHQ4EFgQUP5DIfccVb/Mkj6nDL0uiDyGyL+cwDgYDVR0PAQH/BAQDAgEGMIG+ +BgNVHR8EgbYwgbMwdKByoHCGbmxkYXA6Ly9kaXJlY3RvcnkuZC10cnVzdC5uZXQv +Q049RC1UUlVTVCUyMFJvb3QlMjBDQSUyMDMlMjAyMDEzLE89RC1UcnVzdCUyMEdt +YkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MDugOaA3hjVodHRwOi8v +Y3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2FfM18yMDEzLmNybDAN +BgkqhkiG9w0BAQsFAAOCAQEADlkOWOR0SCNEzzQhtZwUGq2aS7eziG1cqRdw8Cqf +jXv5e4X6xznoEAiwNStfzwLS05zICx7uBVSuN5MECX1sj8J0vPgclL4xAUAt8yQg +t4RVLFzI9XRKEBmLo8ftNdYJSNMOwLo5qLBGArDbxohZwr78e7Erz35ih1WWzAFv +m2chlTWL+BD8cRu3SzdppjvW7IvuwbDzJcmPkn2h6sPKRL8mpXSSnON065102ctN +h9j8tGlsi6BDB2B4l+nZk3zCRrybN1Kj7Yo8E6l7U0tJmhEFLAtuVqwfLoJs4Gln +tQ5tLdnkwBXxP/oYcuEVbSdbLTAoK59ImmQrme/ydUlfXA== +-----END CERTIFICATE----- +# "D-TRUST Root Class 3 CA 2 2009" +# 49 E7 A4 42 AC F0 EA 62 87 05 00 54 B5 25 64 B6 +# 50 E4 F4 9E 42 E3 48 D6 AA 38 E0 39 E9 57 B1 C1 +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha +ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM +HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 +UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 +tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R +ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM +lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp +/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G +A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy +MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl +cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js +L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL +BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni +acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K +zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 +PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y +Johw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- +# "D-TRUST Root Class 3 CA 2 EV 2009" +# EE C5 49 6B 98 8C E9 86 25 B9 34 09 2E EC 29 08 +# BE D0 B0 F3 16 C2 D4 73 0C 84 EA F1 F3 D3 48 81 +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw +NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV +BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn +ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 +3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z +qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR +p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 +HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw +ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea +HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw +Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh +c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E +RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt +dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku +Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp +3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF +CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na +xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX +KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- +# "Deutsche Telekom Root CA 2" +# B6 19 1A 50 D0 C3 97 7F 7D A9 9B CD AA C8 6A 22 +# 7D AE B9 67 9E C7 0B A3 B0 C9 D9 22 71 C1 70 D3 +-----BEGIN CERTIFICATE----- +MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc +MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj +IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB +IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE +RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl +U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290 +IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU +ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC +QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr +rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S +NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc +QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH +txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP +BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC +AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp +tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa +IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl +6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+ +xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU +Cm26OWMohpLzGITY+9HPBVZkVw== +-----END CERTIFICATE----- +# "Developer ID Certification Authority" +# 7A FC 9D 01 A6 2F 03 A2 DE 96 37 93 6D 4A FE 68 +# 09 0D 2D E1 8D 03 F2 9C 88 CF B0 B1 BA 63 58 7F +-----BEGIN CERTIFICATE----- +MIIEBDCCAuygAwIBAgIIGHqpqMKWIQwwDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE +BhMCVVMxEzARBgNVBAoTCkFwcGxlIEluYy4xJjAkBgNVBAsTHUFwcGxlIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1BcHBsZSBSb290IENBMB4XDTEy +MDIwMTIyMTIxNVoXDTI3MDIwMTIyMTIxNVoweTEtMCsGA1UEAwwkRGV2ZWxvcGVy +IElEIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSYwJAYDVQQLDB1BcHBsZSBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UE +BhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCJdk8GW5pB7qUj +KwKjX9dzP8A1sIuECj8GJH+nlT/rTw6Tr7QO0Mg+5W0Ysx/oiUe/1wkI5P9WmCkV +55SduTWjCs20wOHiYPTK7Cl4RWlpYGtfipL8niPmOsIiszFPHLrytjRZQu6wqQID +GJEEtrN4LjMfgEUNRW+7Dlpbfzrn2AjXCw4ybfuGNuRsq8QRinCEJqqfRNHxuMZ7 +lBebSPcLWBa6I8WfFTl+yl3DMl8P4FJ/QOq+rAhklVvJGpzlgMofakQcbD7EsCYf +Hex7r16gaj1HqVgSMT8gdihtHRywwk4RaSaLy9bQEYLJTg/xVnTQ2QhLZniiq6yn +4tJMh1nJAgMBAAGjgaYwgaMwHQYDVR0OBBYEFFcX7aLP3HyYoRDg/L6HLSzy4xdU +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUK9BpR5R2Cf70a40uQKb3R01/ +CF4wLgYDVR0fBCcwJTAjoCGgH4YdaHR0cDovL2NybC5hcHBsZS5jb20vcm9vdC5j +cmwwDgYDVR0PAQH/BAQDAgGGMBAGCiqGSIb3Y2QGAgYEAgUAMA0GCSqGSIb3DQEB +CwUAA4IBAQBCOXRrodzGpI83KoyzHQpEvJUsf7xZuKxh+weQkjK51L87wVA5akR0 +ouxbH3Dlqt1LbBwjcS1f0cWTvu6binBlgp0W4xoQF4ktqM39DHhYSQwofzPuAHob +tHastrW7T9+oG53IGZdKC1ZnL8I+trPEgzrwd210xC4jUe6apQNvYPSlSKcGwrta +4h8fRkV+5Jf1JxC3ICJyb3LaxlB1xT0lj12jAOmfNoxIOY+zO+qQgC6VmmD0eM70 +DgpTPqL6T9geroSVjTK8Vk2J6XgY4KyaQrp6RhuEoonOFOiI0ViL9q5WxCwFKkWv +C9lLqQIPNKyIx2FViUTJJ3MH7oLlTvVw +-----END CERTIFICATE----- +# "DigiCert Assured ID Root CA" +# 3E 90 99 B5 01 5E 8F 48 6C 00 BC EA 9D 11 1E E7 +# 21 FA BA 35 5A 89 BC F1 DF 69 56 1E 3D C6 32 5C +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c +JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP +mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ +wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 +VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ +AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB +AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun +pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC +dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf +fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm +NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx +H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- +# "DigiCert Assured ID Root G2" +# 7D 05 EB B6 82 33 9F 8C 94 51 EE 09 4E EB FE FA +# 79 53 A1 14 ED B2 F4 49 49 45 2F AB 7D 2F C1 85 +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA +n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc +biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp +EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA +bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu +YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW +BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI +QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I +0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni +lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 +B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv +ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- +# "DigiCert Assured ID Root G3" +# 7E 37 CB 8B 4C 47 09 0C AB 36 55 1B A6 F4 5D B8 +# 40 68 0F BA 16 6A 95 2D B1 00 71 7F 43 05 3F C2 +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg +RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf +Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q +RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD +AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY +JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv +6pZjamVFkpUBtA== +-----END CERTIFICATE----- +# "DigiCert Global Root CA" +# 43 48 A0 E9 44 4C 78 CB 26 5E 05 8D 5E 89 44 B4 +# D8 4F 96 62 BD 26 DB 25 7F 89 34 A4 43 C7 01 61 +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- +# "DigiCert Global Root G2" +# CB 3C CB B7 60 31 E5 E0 13 8F 8D D3 9A 23 F9 DE +# 47 FF C3 5E 43 C1 14 4C EA 27 D4 6A 5A B1 CB 5F +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- +# "DigiCert Global Root G3" +# 31 AD 66 48 F8 10 41 38 C7 38 F3 9E A4 32 01 33 +# 39 3E 3A 18 CC 02 29 6E F9 7C 2A C9 EF 67 31 D0 +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe +Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw +EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG +fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO +Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx +AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ +oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 +sycX +-----END CERTIFICATE----- +# "DigiCert High Assurance EV Root CA" +# 74 31 E5 F4 C3 C1 CE 46 90 77 4F 0B 61 E0 54 40 +# 88 3B A9 A0 1E D0 0B A6 AB D7 80 6E D3 B1 18 CF +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- +# "DigiCert Trusted Root G4" +# 55 2F 7B DC F1 A7 AF 9E 6C E6 72 01 7F 4F 12 AB +# F7 72 40 C7 8E 76 1A C2 03 D1 D9 D2 0A C8 99 88 +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg +RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y +ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If +xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV +ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO +DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ +jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ +CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi +EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM +fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY +uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK +chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t +9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 +SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd ++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc +fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa +sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N +cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N +0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie +4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI +r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 +/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm +gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ +-----END CERTIFICATE----- +# "DST Root CA X3" +# 06 87 26 03 31 A7 24 03 D9 09 F1 05 E6 9B CF 0D +# 32 E1 BD 24 93 FF C6 D9 20 6D 11 BC D6 77 07 39 +-----BEGIN CERTIFICATE----- +MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ +MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT +DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow +PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD +Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O +rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq +OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b +xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw +7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD +aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG +SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69 +ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr +AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz +R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 +JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo +Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ +-----END CERTIFICATE----- +# "DST Root CA X4" +# 9A 73 92 9A 50 0F 1A 0B F4 9D CB 04 6E 80 39 16 +# 96 96 55 73 45 E9 F8 13 F1 0F F9 38 0D B2 26 95 +-----BEGIN CERTIFICATE----- +MIIDOzCCAiOgAwIBAgIRANAeRlAAACmMAAAAAgAAAAIwDQYJKoZIhvcNAQEFBQAw +PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD +Ew5EU1QgUm9vdCBDQSBYNDAeFw0wMDA5MTMwNjIyNTBaFw0yMDA5MTMwNjIyNTBa +MD8xJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjEXMBUGA1UE +AxMORFNUIFJvb3QgQ0EgWDQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCthX3OFEYY8gSeIYur0O4ypOT68HnDrjLfIutL5PZHRwQGjzCPb9PFo/ihboJ8 +RvfGhBAqpQCo47zwYEhpWm1jB+L/OE/dBBiyn98krfU2NiBKSom2J58RBeAwHGEy +cO+lewyjVvbDDLUy4CheY059vfMjPAftCRXjqSZIolQb9FdPcAoa90mFwB7rKniE +J7vppdrUScSS0+eBrHSUPLdvwyn4RGp+lSwbWYcbg5EpSpE0GRJdchic0YDjvIoC +YHpe7Rkj93PYRTQyU4bhC88ck8tMqbvRYqMRqR+vobbkrj5LLCOQCHV5WEoxWh+0 +E2SpIFe7RkV++MmpIAc0h1tZAgMBAAGjMjAwMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFPCD6nPIP1ubWzdf9UyPWvf0hki9MA0GCSqGSIb3DQEBBQUAA4IBAQCE +G85wl5eEWd7adH6XW/ikGN5salvpq/Fix6yVTzE6CrhlP5LBdkf6kx1bSPL18M45 +g0rw2zA/MWOhJ3+S6U+BE0zPGCuu8YQaZibR7snm3HiHUaZNMu5c8D0x0bcMxDjY +AVVcHCoNiL53Q4PLW27nbY6wwG0ffFKmgV3blxrYWfuUDgGpyPwHwkfVFvz9qjaV +mf12VJffL6W8omBPtgteb6UaT/k1oJ7YI0ldGf+ngpVbRhD+LC3cUtT6GO/BEPZu +8YTV/hbiDH5v3khVqMIeKT6o8IuXGG7F6a6vKwP1F1FwTXf4UC/ivhme7vdUH7B/ +Vv4AEbT8dNfEeFxrkDbh +-----END CERTIFICATE----- +# "E-Tugra Certification Authority" +# B0 BF D5 2B B0 D7 D9 BD 92 BF 5D 4D C1 3D A2 55 +# C0 2C 54 2F 37 83 65 EA 89 39 11 F5 5E 55 F2 3C +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV +BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC +aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV +BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 +Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz +MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ +BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp +em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN +ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY +B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH +D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF +Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo +q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D +k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH +fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut +dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM +ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 +zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn +rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX +U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 +Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 +XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF +Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR +HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY +GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c +77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 ++GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK +vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 +FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl +yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P +AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD +y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d +NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== +-----END CERTIFICATE----- +# "Echoworx Root CA2" +# 66 39 D1 3C AB 85 DF 1A D9 A2 3C 44 3B 3A 60 90 +# 1E 2B 13 8D 45 6F A7 11 83 57 81 08 88 4E C6 BF +-----BEGIN CERTIFICATE----- +MIIE5zCCA8+gAwIBAgIBADANBgkqhkiG9w0BAQUFADCBjTELMAkGA1UEBhMCQ0Ex +EDAOBgNVBAgTB09udGFyaW8xEDAOBgNVBAcTB1Rvcm9udG8xHTAbBgNVBAoTFEVj +aG93b3J4IENvcnBvcmF0aW9uMR8wHQYDVQQLExZDZXJ0aWZpY2F0aW9uIFNlcnZp +Y2VzMRowGAYDVQQDExFFY2hvd29yeCBSb290IENBMjAeFw0wNTEwMDYxMDQ5MTNa +Fw0zMDEwMDcxMDQ5MTNaMIGNMQswCQYDVQQGEwJDQTEQMA4GA1UECBMHT250YXJp +bzEQMA4GA1UEBxMHVG9yb250bzEdMBsGA1UEChMURWNob3dvcnggQ29ycG9yYXRp +b24xHzAdBgNVBAsTFkNlcnRpZmljYXRpb24gU2VydmljZXMxGjAYBgNVBAMTEUVj +aG93b3J4IFJvb3QgQ0EyMIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEA +utU/5BkV15UBf+s+JQruKQxr77s3rjp/RpOtmhHILIiO5gsEWP8MMrfrVEiidjI6 +Qh6ans0KAWc2Dw0/j4qKAQzOSyAZgjcdypNTBZ7muv212DA2Pu41rXqwMrlBrVi/ +KTghfdLlNRu6JrC5y8HarrnRFSKF1Thbzz921kLDRoCi+FVs5eVuK5LvIfkhNAqA +byrTgO3T9zfZgk8upmEkANPDL1+8y7dGPB/d6lk0I5mv8PESKX02TlvwgRSIiTHR +k8++iOPLBWlGp7ZfqTEXkPUZhgrQQvxcrwCUo6mk8TqgxCDP5FgPoHFiPLef5szP +ZLBJDWp7GLyE1PmkQI6WiwIBA6OCAVAwggFMMA8GA1UdEwEB/wQFMAMBAf8wCwYD +VR0PBAQDAgEGMB0GA1UdDgQWBBQ74YEboKs/OyGC1eISrq5QqxSlEzCBugYDVR0j +BIGyMIGvgBQ74YEboKs/OyGC1eISrq5QqxSlE6GBk6SBkDCBjTELMAkGA1UEBhMC +Q0ExEDAOBgNVBAgTB09udGFyaW8xEDAOBgNVBAcTB1Rvcm9udG8xHTAbBgNVBAoT +FEVjaG93b3J4IENvcnBvcmF0aW9uMR8wHQYDVQQLExZDZXJ0aWZpY2F0aW9uIFNl +cnZpY2VzMRowGAYDVQQDExFFY2hvd29yeCBSb290IENBMoIBADBQBgNVHSAESTBH +MEUGCysGAQQB+REKAQMBMDYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuZWNob3dv +cnguY29tL2NhL3Jvb3QyL2Nwcy5wZGYwDQYJKoZIhvcNAQEFBQADggEBAG+nrPi/ +0RpfEzrj02C6JGPUar4nbjIhcY6N7DWNeqBoUulBSIH/PYGNHYx7/lnJefiixPGE +7TQ5xPgElxb9bK8zoAApO7U33OubqZ7M7DlHnFeCoOoIAZnG1kuwKwD5CXKB2a74 +HzcqNnFW0IsBFCYqrVh/rQgJOzDA8POGbH0DeD0xjwBBooAolkKT+7ZItJF1Pb56 +QpDL9G+16F7GkmnKlAIYT3QTS3yFGYChnJcd+6txUPhKi9sSOOmAIaKHnkH9Scz+ +A2cSi4A3wUYXVatuVNHpRb2lygfH3SuCX9MU8Ure3zBlSU1LALtMqI4JmcQmQpIq +zIzvO2jHyu9PQqo= +-----END CERTIFICATE----- +# "EE Certification Centre Root CA" +# 3E 84 BA 43 42 90 85 16 E7 75 73 C0 99 2F 09 79 +# CA 08 4E 46 85 68 1F F1 95 CC BA 8A 22 9B 8A 76 +-----BEGIN CERTIFICATE----- +MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1 +MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1 +czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG +CSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy +MTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl +ZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS +b290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy +euuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO +bntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw +WFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d +MtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE +1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/ +zQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB +BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF +BQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV +v9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG +E5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u +uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW +iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v +GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0= +-----END CERTIFICATE----- +# "Entrust Root Certification Authority" +# 73 C1 76 43 4F 1B C6 D5 AD F4 5B 0E 76 E7 27 28 +# 7C 8D E5 76 16 C1 E6 E6 14 1A 2B 2C BC 7D 8E 4C +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 +Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW +KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw +NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw +NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy +ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV +BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo +Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 +4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 +KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI +rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi +94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB +sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi +gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo +kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE +vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t +O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua +AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP +9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ +eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m +0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- +# "Entrust Root Certification Authority - EC1" +# 02 ED 0E B2 8C 14 DA 45 16 5C 56 67 91 70 0D 64 +# 51 D7 FB 56 F0 B2 AB 1D 3B 8E B0 70 E5 6E DF F5 +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 +d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu +dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq +RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy +MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD +VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g +Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi +A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt +ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH +Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC +R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX +hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- +# "Entrust Root Certification Authority - G2" +# 43 DF 57 74 B0 3E 7F EF 5F E4 0D 93 1A 7B ED F1 +# BB 2E 6B 42 73 8C 4E 6D 38 41 10 3D 3A A7 F3 39 +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== +-----END CERTIFICATE----- +# "Entrust.net Certification Authority (2048)" +# D1 C3 39 EA 27 84 EB 87 0F 93 4F C5 63 4E 4A A9 +# AD 55 05 01 64 01 F2 64 65 D3 7A 57 46 63 35 9F +-----BEGIN CERTIFICATE----- +MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0xOTEy +MjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 +LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp +YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG +A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq +K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe +sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX +MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT +XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ +HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH +4QIDAQABo3QwcjARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGA +vtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJFrlwMB0G +CSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA +WUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo +oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQ +h7A6tcOdBTcSo8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18 +f3v/rxzP5tsHrV7bhZ3QKw0z2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfN +B/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVy +vUxFnmG6v4SBkgPR0ml8xQ== +-----END CERTIFICATE----- +# "Entrust.net Certification Authority (2048)" +# 6D C4 71 72 E0 1C BC B0 BF 62 58 0D 89 5F E2 B8 +# AC 9A D4 F8 73 80 1E 0C 10 B9 C8 37 D2 1E B1 77 +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 +MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 +LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp +YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG +A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq +K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe +sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX +MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT +XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ +HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH +4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub +j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo +U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b +u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ +bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er +fF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- +# "ePKI Root Certification Authority" +# C0 A6 F4 DC 63 A2 4B FD CF 54 EF 2A 6A 08 2A 0A +# 72 DE 35 80 3E 2F F5 FF 52 7A E5 D8 72 06 DF D5 +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw +IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL +SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH +SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh +ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X +DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 +TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ +fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA +sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU +WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS +nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH +dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip +NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC +AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF +MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB +uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl +PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP +JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ +gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 +j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 +5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB +o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS +/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z +Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE +W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D +hNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- +# "GDCA TrustAUTH R5 ROOT" +# BF FF 8F D0 44 33 48 7D 6A 8A A6 0C 1A 29 76 7A +# 9F C2 BB B0 5E 42 0F 71 3A 13 B9 92 89 1D 38 93 +-----BEGIN CERTIFICATE----- +MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE +BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ +IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 +MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV +BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w +HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj +Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj +TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u +KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj +qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm +MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 +ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP +zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk +L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC +jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA +HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC +AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg +p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm +DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 +COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry +L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf +JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg +IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io +2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV +09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ +XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq +T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe +MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== +-----END CERTIFICATE----- +# "GeoTrust Global CA" +# FF 85 6A 2D 25 1D CD 88 D3 66 56 F4 50 12 67 98 +# CF AB AA DE 40 79 9C 72 2D E4 D2 B5 DB 36 A7 3A +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg +R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 +9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq +fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv +iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU +1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ +bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW +MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA +ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l +uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn +Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS +tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF +PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un +hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV +5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== +-----END CERTIFICATE----- +# "GeoTrust Primary Certification Authority" +# 37 D5 10 06 C5 12 EA AB 62 64 21 F1 EC 8C 92 01 +# 3F C5 F8 2A E9 8E E5 33 EB 46 19 B8 DE B4 D0 6C +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY +MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo +R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx +MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK +Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9 +AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA +ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0 +7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W +kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI +mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ +KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1 +6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl +4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K +oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj +UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU +AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= +-----END CERTIFICATE----- +# "GeoTrust Primary Certification Authority - G2" +# 5E DB 7A C4 3B 82 A0 6A 87 61 E8 D7 BE 49 79 EB +# F2 61 1F 7D D7 9B F9 1C 1C 6B 56 6A 21 9E D7 66 +-----BEGIN CERTIFICATE----- +MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL +MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj +KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 +MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw +NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV +BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH +MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL +So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal +tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG +CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT +qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz +rD6ogRLQy7rQkgu2npaqBA+K +-----END CERTIFICATE----- +# "GeoTrust Primary Certification Authority - G3" +# B4 78 B8 12 25 0D F8 78 63 5C 2A A7 EC 7D 15 5E +# AA 62 5E E8 29 16 E2 CD 29 43 61 88 6C D1 FB D4 +-----BEGIN CERTIFICATE----- +MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB +mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT +MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv +cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ +BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg +MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0 +BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz ++uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm +hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn +5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W +JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL +DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC +huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw +HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB +AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB +zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN +kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD +AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH +SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G +spki4cErx5z481+oghLrGREt +-----END CERTIFICATE----- +# "Global Chambersign Root" +# EF 3C B4 17 FC 8E BF 6F 97 87 6C 9E 4E CE 39 DE +# 1E A5 FE 64 91 41 D1 02 8B 7D 11 C0 B2 29 8C ED +-----BEGIN CERTIFICATE----- +MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEn +MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL +ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENo +YW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYxNDE4WhcNMzcwOTMwMTYxNDE4WjB9 +MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgy +NzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4G +A1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUA +A4IBDQAwggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0 +Mi+ITaFgCPS3CU6gSS9J1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/s +QJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8Oby4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpV +eAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl6DJWk0aJqCWKZQbua795 +B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c8lCrEqWh +z0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0T +AQH/BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1i +ZXJzaWduLm9yZy9jaGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4w +TcbOX60Qq+UDpfqpFDAOBgNVHQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAH +MCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBjaGFtYmVyc2lnbi5vcmcwKgYD +VR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9yZzBbBgNVHSAE +VDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh +bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0B +AQUFAAOCAQEAPDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUM +bKGKfKX0j//U2K0X1S0E0T9YgOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXi +ryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJPJ7oKXqJ1/6v/2j1pReQvayZzKWG +VwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4IBHNfTIzSJRUTN3c +ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/ +AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A== +-----END CERTIFICATE----- +# "Global Chambersign Root - 2008" +# 13 63 35 43 93 34 A7 69 80 16 A0 D3 24 DE 72 28 +# 4E 07 9D 7B 52 20 BB 8F BD 74 78 16 EE BE BA CA +-----BEGIN CERTIFICATE----- +MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD +aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx +MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy +cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG +A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl +BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed +KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7 +G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2 +zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4 +ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG +HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2 +Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V +yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e +beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r +6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh +wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog +zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW +BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr +ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp +ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk +cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt +YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC +CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow +KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI +hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ +UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz +X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x +fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz +a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd +Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd +SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O +AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso +M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge +v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z +09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B +-----END CERTIFICATE----- +# "GlobalSign" +# CA 42 DD 41 74 5F D0 B8 1E B9 02 36 2C F9 D8 BF +# 71 9D A1 BD 1B 1E FC 94 6F 5B 4C 99 F4 2C 1B 9E +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 +MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL +v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 +eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq +tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd +C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa +zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB +mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH +V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n +bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG +3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs +J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO +291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS +ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd +AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 +TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== +-----END CERTIFICATE----- +# "GlobalSign" +# CB B5 22 D7 B7 F1 27 AD 6A 01 13 86 5B DF 1C D4 +# 10 2E 7D 07 59 AF 63 5A 7C F4 72 0D C9 63 C5 3B +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 +MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 +RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT +gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm +KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd +QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ +XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o +LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU +RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp +jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK +6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX +mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs +Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH +WD9f +-----END CERTIFICATE----- +# "GlobalSign" +# BE C9 49 11 C2 95 56 76 DB 6C 0A 55 09 86 D7 6E +# 3B A0 05 66 7C 44 2C 97 62 B4 FB B7 73 DE 22 8C +-----BEGIN CERTIFICATE----- +MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ +FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F +uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX +kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs +ewv4n4Q= +-----END CERTIFICATE----- +# "GlobalSign" +# 17 9F BC 14 8A 3D D0 0F D2 4E A1 34 58 CC 43 BF +# A7 F5 9C 81 82 D7 83 A5 13 F6 EB EC 10 0C 89 24 +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc +8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke +hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI +KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg +515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO +xwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- +# "GlobalSign Root CA" +# EB D4 10 40 E4 BB 3E C7 42 C9 E3 81 D3 1E F2 A4 +# 1A 48 B6 68 5C 96 E7 CE F3 C1 DF 6C D4 33 1C 99 +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw +MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i +YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT +aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ +jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp +xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp +1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG +snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ +U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 +9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B +AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz +yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE +38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP +AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad +DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME +HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- +# "Go Daddy Class 2 Certification Authority" +# C3 84 6B F2 4B 9E 93 CA 64 27 4C 0E C6 7C 1E CC +# 5E 02 4F FC AC D2 D7 40 19 35 0E 81 FE 54 6A E4 +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh +MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE +YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 +MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo +ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg +MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN +ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA +PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w +wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi +EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY +avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ +YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE +sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h +/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 +IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD +ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy +OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P +TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER +dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf +ReYNnyicsbkqWletNw+vHX/bvZ8= +-----END CERTIFICATE----- +# "Go Daddy Root Certificate Authority - G2" +# 45 14 0B 32 47 EB 9C C8 C5 B4 F0 D7 B5 30 91 F7 +# 32 92 08 9E 6E 5A 63 E2 74 9D D3 AC A9 19 8E DA +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz +NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE +AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD +E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH +/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy +DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh +GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR +tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX +WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu +9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr +gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo +2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI +4uJEvlz36hz1 +-----END CERTIFICATE----- +# "Government Root Certification Authority" +# 70 B9 22 BF DA 0E 3F 4A 34 2E 4E E2 2D 57 9A E5 +# 98 D0 71 CC 5E C9 C3 0F 12 36 80 34 03 88 AE A5 +-----BEGIN CERTIFICATE----- +MIIFSzCCAzOgAwIBAgIRALZLiAfiI+7IXBKtpg4GofIwDQYJKoZIhvcNAQELBQAw +PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTAeFw0xMjA5MjgwODU4NTFaFw0zNzEyMzExNTU5NTla +MD8xCzAJBgNVBAYTAlRXMTAwLgYDVQQKDCdHb3Zlcm5tZW50IFJvb3QgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQC2/5c8gb4BWCQnr44BK9ZykjAyG1+bfNTUf+ihYHMwVxAA+lCWJP5Q5ow6ldFX +eYTVZ1MMKoI+GFy4MCYa1l7GLbIEUQ7v3wxjR+vEEghRK5lxXtVpe+FdyXcdIOxW +juVhYC386RyA3/pqg7sFtR4jEpyCygrzFB0g5AaPQySZn7YKk1pzGxY5vgW28Yyl +ZJKPBeRcdvc5w88tvQ7Yy6gOMZvJRg9nU0MEj8iyyIOAX7ryD6uBNaIgIZfOD4k0 +eA/PH07p+4woPN405+2f0mb1xcoxeNLOUNFggmOd4Ez3B66DNJ1JSUPUfr0t4urH +cWWACOQ2nnlwCjyHKenkkpTqBpIpJ3jmrdc96QoLXvTg1oadLXLLi2RW5vSueKWg +OTNYPNyoj420ai39iHPplVBzBN8RiD5C1gJ0+yzEb7xs1uCAb9GGpTJXA9ZN9E4K +mSJ2fkpAgvjJ5E7LUy3Hsbbi08J1J265DnGyNPy/HE7CPfg26QrMWJqhGIZO4uGq +s3NZbl6dtMIIr69c/aQCb/+4DbvVq9dunxpPkUDwH0ZVbaCSw4nNt7H/HLPLo5wK +4/7NqrwB7N1UypHdTxOHpPaY7/1J1lcqPKZc9mA3v9g+fk5oKiMyOr5u5CI9ByTP +isubXVGzMNJxbc5Gim18SjNE2hIvNkvy6fFRCW3bapcOFwIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBTVZx3gnHosnMvFmOcdByYqhux0zTAOBgNV +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAJA75cJTQijq9TFOjj2Rnk0J +89ixUuZPrAwxIbvx6pnMg/y2KOTshAcOD06Xu29oRo8OURWV+Do7H1+CDgxxDryR +T64zLiNB9CZrTxOH+nj2LsIPkQWXqmrBap+8hJ4IKifd2ocXhuGzyl3tOKkpboTe +Rmv8JxlQpRJ6jH1i/NrnzLyfSa8GuCcn8on3Fj0Y5r3e9YwSkZ/jBI3+BxQaWqw5 +ghvxOBnhY+OvbLamURfr+kvriyL2l/4QOl+UoEtTcT9a4RD4co+WgN2NApgAYT2N +vC2xR8zaXeEgp4wxXPHj2rkKhkfIoT0Hozymc26Uke1uJDr5yTDRB6iBfSZ9fYTf +hsmL5a4NHr6JSFEVg5iWL0rrczTXdM3Jb9DCuiv2mv6Z3WAUjhv5nDk8f0OJU+jl +wqu+Iq0nOJt3KLejY2OngeepaUXrjnhWzAWEx/uttjB8YwWfLYwkf0uLkvw4Hp+g +pVezbp3YZLhwmmBScMip0P/GnO0QYV7Ngw5u6E0CQUridgR51lQ/ipgyFKDdLZzn +uoJxo4ZVKZnSKdt1OvfbQ/+2W/u3fjWAjg1srnm3Ni2XUqGwB5wH5Ss2zQOXlL0t +DjQG/MAWifw3VOTWzz0TBPKR2ck2Lj7FWtClTILD/y58Jnb38/1FoqVuVa4uzM8s +iTTa9g3nkagQ6hed8vbs +-----END CERTIFICATE----- +# "GTS Root R1" +# 2A 57 54 71 E3 13 40 BC 21 58 1C BD 2C F1 3E 15 +# 84 63 20 3E CE 94 BC F9 D3 CC 19 6B F0 9A 54 72 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH +MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM +QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy +MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl +cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM +f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX +mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7 +zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P +fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc +vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4 +Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp +zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO +Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW +k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+ +DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF +lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW +Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1 +d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z +XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR +gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3 +d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv +J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg +DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM ++SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy +F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9 +SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws +E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl +-----END CERTIFICATE----- +# "GTS Root R2" +# C4 5D 7B B0 8E 6D 67 E6 2E 42 35 11 0B 56 4E 5F +# 78 FD 92 EF 05 8C 84 0A EA 4E 64 55 D7 58 5C 60 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH +MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM +QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy +MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl +cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv +CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg +GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu +XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd +re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu +PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1 +mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K +8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj +x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR +nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0 +kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok +twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp +8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT +vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT +z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA +pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb +pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB +R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R +RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk +0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC +5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF +izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn +yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC +-----END CERTIFICATE----- +# "GTS Root R3" +# 15 D5 B8 77 46 19 EA 7D 54 CE 1C A6 D0 B0 C4 03 +# E0 37 A9 17 F1 31 E8 A0 4E 1E 6B 7A 71 BA BC E5 +-----BEGIN CERTIFICATE----- +MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout +736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A +DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk +fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA +njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd +-----END CERTIFICATE----- +# "GTS Root R4" +# 71 CC A5 39 1F 9E 79 4B 04 80 25 30 B3 63 E1 21 +# DA 8A 30 43 BB 26 66 2F EA 4D CA 7F C9 51 A4 BD +-----BEGIN CERTIFICATE----- +MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu +hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l +xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0 +CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx +sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w== +-----END CERTIFICATE----- +# "Hellenic Academic and Research Institutions ECC RootCA 2015" +# 44 B5 45 AA 8A 25 E6 5A 73 CA 15 DC 27 FC 36 D2 +# 4C 1C B9 95 3A 06 65 39 B1 15 82 DC 48 7B 48 33 +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN +BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl +bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv +b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ +BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj +YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 +MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 +dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg +QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa +jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi +C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep +lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof +TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- +# "Hellenic Academic and Research Institutions RootCA 2011" +# BC 10 4F 15 A4 8B E7 09 DC A5 42 A7 E1 D4 B9 DF +# 6F 05 45 27 E8 02 EA A9 2D 59 54 44 25 8A FE 71 +-----BEGIN CERTIFICATE----- +MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix +RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p +YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw +NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK +EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl +cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz +dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ +fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns +bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD +75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP +FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV +HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp +5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu +b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA +A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p +6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 +TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7 +dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys +Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI +l7WdmplNsDz4SgCbZN2fOUvRJ9e4 +-----END CERTIFICATE----- +# "Hellenic Academic and Research Institutions RootCA 2015" +# A0 40 92 9A 02 CE 53 B4 AC F4 F2 FF C6 98 1C E4 +# 49 6F 75 5E 6D 45 FE 0B 2A 69 2B CD 52 52 3F 36 +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix +DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k +IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT +N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v +dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG +A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh +ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx +QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA +4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 +AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 +4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C +ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV +9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD +gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 +Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq +NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko +LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd +ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I +XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI +M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot +9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V +Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea +j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh +X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ +l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf +bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 +pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK +e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 +vm9qp/UsQu0yrbYhnr68 +-----END CERTIFICATE----- +# "Hongkong Post Root CA 1" +# F9 E6 7D 33 6C 51 00 2A C0 54 C6 32 02 2D 66 DD +# A2 E7 E3 FF F1 0A D0 61 ED 31 D8 BB B4 10 CF B2 +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx +FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg +Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG +A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr +b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ +jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn +PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh +ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9 +nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h +q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED +MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC +mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3 +7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB +oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs +EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO +fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi +AmvZWg== +-----END CERTIFICATE----- +# "I.CA - Qualified Certification Authority, 09/2009" +# C0 C0 5A 8D 8D A5 5E AF 27 AA 9B 91 0B 0A 6E F0 +# D8 BB DE D3 46 92 8D B8 72 E1 82 C2 07 3E 98 02 +-----BEGIN CERTIFICATE----- +MIIFHjCCBAagAwIBAgIEAKA3oDANBgkqhkiG9w0BAQsFADCBtzELMAkGA1UEBhMC +Q1oxOjA4BgNVBAMMMUkuQ0EgLSBRdWFsaWZpZWQgQ2VydGlmaWNhdGlvbiBBdXRo +b3JpdHksIDA5LzIwMDkxLTArBgNVBAoMJFBydm7DrSBjZXJ0aWZpa2HEjW7DrSBh +dXRvcml0YSwgYS5zLjE9MDsGA1UECww0SS5DQSAtIEFjY3JlZGl0ZWQgUHJvdmlk +ZXIgb2YgQ2VydGlmaWNhdGlvbiBTZXJ2aWNlczAeFw0wOTA5MDEwMDAwMDBaFw0x +OTA5MDEwMDAwMDBaMIG3MQswCQYDVQQGEwJDWjE6MDgGA1UEAwwxSS5DQSAtIFF1 +YWxpZmllZCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSwgMDkvMjAwOTEtMCsGA1UE +CgwkUHJ2bsOtIGNlcnRpZmlrYcSNbsOtIGF1dG9yaXRhLCBhLnMuMT0wOwYDVQQL +DDRJLkNBIC0gQWNjcmVkaXRlZCBQcm92aWRlciBvZiBDZXJ0aWZpY2F0aW9uIFNl +cnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtTaEy0KC8M9l +4lSaWHMs4+sVV1LwzyJYiIQNeCrv1HHm/YpGIdY/Z640ceankjQvIX7m23BK4OSC +6KO8kZYA3zopOz6GFCOKV2PvLukbc+c2imF6kLHEv6qNA8WxhPbR3xKwlHDwB2yh +Wzo7V3QVgDRG83sugqQntKYC3LnlTGbJpNP+Az72gpO9AHUn/IBhFk4ksc8lYS2L +9GCy9CsmdKSBP78p9w8Lx7vDLqkDgt1/zBrcUWmSSb7AE/BPEeMryQV1IdI6nlGn +BhWkXOYf6GSdayJw86btuxC7viDKNrbp44HjQRaSxnp6O3eto1x4DfiYdw/YbJFe +7EjkxSQBywIDAQABo4IBLjCCASowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E +BAMCAQYwgecGA1UdIASB3zCB3DCB2QYEVR0gADCB0DCBzQYIKwYBBQUHAgIwgcAa +gb1UZW50byBjZXJ0aWZpa2F0IGplIHZ5ZGFuIGpha28ga3ZhbGlmaWtvdmFueSBz +eXN0ZW1vdnkgY2VydGlmaWthdCBwb2RsZSB6YWtvbmEgYy4gMjI3LzIwMDAgU2Iu +IHYgcGxhdG5lbSB6bmVuaS9UaGlzIGlzIHF1YWxpZmllZCBzeXN0ZW0gY2VydGlm +aWNhdGUgYWNjb3JkaW5nIHRvIEN6ZWNoIEFjdCBOby4gMjI3LzIwMDAgQ29sbC4w +HQYDVR0OBBYEFHnL0CPpOmdwkXRP01Hi4CD94Sj7MA0GCSqGSIb3DQEBCwUAA4IB +AQB9laU214hYaBHPZftbDS/2dIGLWdmdSbj1OZbJ8LIPBMxYjPoEMqzAR74tw96T +i6aWRa5WdOWaS6I/qibEKFZhJAVXX5mkx2ewGFLJ+0Go+eTxnjLOnhVF2V2s+57b +m8c8j6/bS6Ij6DspcHEYpfjjh64hE2r0aSpZDjGzKFM6YpqsCJN8qYe2X1qmGMLQ +wvNdjG+nPzCJOOuUEypIWt555ZDLXqS5F7ZjBjlfyDZjEfS2Es9Idok8alf563Mi +9/o+Ba46wMYOkk3P1IlU0RqCajdbliioACKDztAqubONU1guZVzV8tuMASVzbJeL +/GAB7ECTwe1RuKrLYtglMKI9 +-----END CERTIFICATE----- +# "IdenTrust Commercial Root CA 1" +# 5D 56 49 9B E4 D2 E0 8B CF CA D0 8A 3E 38 72 3D +# 50 50 3B DE 70 69 48 E4 2F 55 60 30 19 E5 28 AE +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu +VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw +MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw +JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT +3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU ++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp +S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 +bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi +T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL +vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK +Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK +dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT +c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv +l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N +iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD +ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt +LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 +nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 ++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK +W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT +AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq +l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG +4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ +mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A +7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- +# "IdenTrust Public Sector Root CA 1" +# 30 D0 89 5A 9A 44 8A 26 20 91 63 55 22 D1 F5 20 +# 10 B5 86 7A CA E1 2C 78 EF 95 8F D4 F4 38 9F 2F +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu +VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN +MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 +MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 +ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy +RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS +bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF +/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R +3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw +EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy +9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V +GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ +2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV +WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD +W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN +AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV +DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 +TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G +lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW +mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df +WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 ++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ +tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA +GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv +8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- +# "ISRG Root X1" +# 96 BC EC 06 26 49 76 F3 74 60 77 9A CF 28 C5 A7 +# CF E8 A3 C0 AA E1 1A 8F FC EE 05 C0 BD DF 08 C6 +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- +# "Izenpe.com" +# 23 80 42 03 CA 45 D8 CD E7 16 B8 C1 3B F3 B4 48 +# 45 7F A0 6C C1 02 50 99 7F A0 14 58 31 7C 41 E5 +-----BEGIN CERTIFICATE----- +MIIF8DCCA9igAwIBAgIPBuhGJy8fCo/RhFzjafbVMA0GCSqGSIb3DQEBBQUAMDgx +CzAJBgNVBAYTAkVTMRQwEgYDVQQKDAtJWkVOUEUgUy5BLjETMBEGA1UEAwwKSXpl +bnBlLmNvbTAeFw0wNzEyMTMxMzA4MjdaFw0zNzEyMTMwODI3MjVaMDgxCzAJBgNV +BAYTAkVTMRQwEgYDVQQKDAtJWkVOUEUgUy5BLjETMBEGA1UEAwwKSXplbnBlLmNv +bTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMnTesoPHqynhugWZWqx +whtFMnGV2f4QW8yv56V5AY+Jw8ryVXH3d753lPNypCxE2J6SmxQ6oeckkAoKVo7F +2CaU4dlI4S0+2gpy3aOZFdqBoof0e24md4lYrdbrDLJBenNubdt6eEHpCIgSfocu +ZhFjbFT7PJ1ywLwu/8K33Q124zrX97RovqL144FuwUZvXY3gTcZUVYkaMzEKsVe5 +o4qYw+w7NMWVQWl+dcI8IMVhulFHoCCQk6GQS/NOfIVFVJrRBSZBsLVNHTO+xAPI +JXzBcNs79AktVCdIrC/hxKw+yMuSTFM5NyPs0wH54AlETU1kwOENWocivK0bo/4m +tRXzp/yEGensoYi0RGmEg/OJ0XQGqcwL1sLeJ4VQJsoXuMl6h1YsGgEebL4TrRCs +tST1OJGh1kva8bvS3ke18byB9llrzxlT6Y0Vy0rLqW9E5RtBz+GGp8rQap+8TI0G +M1qiheWQNaBiXBZO8OOi+gMatCxxs1gs3nsL2xoP694hHwZ3BgOwye+Z/MC5TwuG +KP7Suerj2qXDR2kS4Nvw9hmL7Xtw1wLW7YcYKCwEJEx35EiKGsY7mtQPyvp10gFA +Wo15v4vPS8+qFsGV5K1Mij4XkdSxYuWC5YAEpAN+jb/af6IPl08M0w3719Hlcn4c +yHf/W5oPt64FRuXxqBbsR6QXAgMBAAGjgfYwgfMwgbAGA1UdEQSBqDCBpYEPaW5m +b0BpemVucGUuY29tpIGRMIGOMUcwRQYDVQQKDD5JWkVOUEUgUy5BLiAtIENJRiBB +MDEzMzcyNjAtUk1lcmMuVml0b3JpYS1HYXN0ZWl6IFQxMDU1IEY2MiBTODFDMEEG +A1UECQw6QXZkYSBkZWwgTWVkaXRlcnJhbmVvIEV0b3JiaWRlYSAxNCAtIDAxMDEw +IFZpdG9yaWEtR2FzdGVpejAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUHRxlDqjyJXu0kc/ksbHmvVV0bAUwDQYJKoZIhvcNAQEFBQAD +ggIBAMeBRm8hGE+gBe/n1bqXUKJg7aWSFBpSm/nxiEqg3Hh10dUflU7F57dp5iL0 ++CmoKom+z892j+Mxc50m0xwbRxYpB2iEitL7sRskPtKYGCwkjq/2e+pEFhsqxPqg +l+nqbFik73WrAGLRne0TNtsiC7bw0fRue0aHwp28vb5CO7dz0JoqPLRbEhYArxk5 +ja2DUBzIgU+9Ag89njWW7u/kwgN8KRwCfr00J16vU9adF79XbOnQgxCvv11N75B7 +XSus7Op9ACYXzAJcY9cZGKfsK8eKPlgOiofmg59OsjQerFQJTx0CCzl+gQgVuaBp +E8gyK+OtbBPWg50jLbJtooiGfqgNASYJQNntKE6MkyQP2/EeTXp6WuKlWPHcj1+Z +ggwuz7LdmMySlD/5CbOlliVbN/UShUHiGUzGigjB3Bh6Dx4/glmimj4/+eAJn/3B +kUtdyXvWton83x18hqrNA/ILUpLxYm9/h+qrdslsUMIZgq+qHfUgKGgu1fxkN0/P +pUTEvnK0jHS0bKf68r10OEMr3q/53NjgnZ/cPcqlY0S/kqJPTIAcuxrDmkoEVU3K +7iYLHL8CxWTTnn7S05EcS6L1HOUXHA0MUqORH5zwIe0ClG+poEnK6EOMxPQ02nwi +o8ZmPrgbBYhdurz3vOXcFD2nhqi2WVIhA16L4wTtSyoeo09Q +-----END CERTIFICATE----- +# "Izenpe.com" +# 25 30 CC 8E 98 32 15 02 BA D9 6F 9B 1F BA 1B 09 +# 9E 2D 29 9E 0F 45 48 BB 91 4F 36 3B C0 D4 53 1F +-----BEGIN CERTIFICATE----- +MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4 +MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6 +ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD +VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j +b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq +scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO +xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H +LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX +uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD +yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+ +JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q +rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN +BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L +hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB +QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+ +HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu +Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg +QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB +BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx +MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA +A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb +laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56 +awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo +JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw +LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT +VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk +LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb +UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/ +QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+ +naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls +QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== +-----END CERTIFICATE----- +# "KISA RootCA 1" +# 6F DB 3F 76 C8 B8 01 A7 53 38 D8 A5 0A 7C 02 87 +# 9F 61 98 B5 7E 59 4D 31 8D 38 32 90 0F ED CD 79 +-----BEGIN CERTIFICATE----- +MIIDczCCAlugAwIBAgIBBDANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJLUjEN +MAsGA1UECgwES0lTQTEuMCwGA1UECwwlS29yZWEgQ2VydGlmaWNhdGlvbiBBdXRo +b3JpdHkgQ2VudHJhbDEWMBQGA1UEAwwNS0lTQSBSb290Q0EgMTAeFw0wNTA4MjQw +ODA1NDZaFw0yNTA4MjQwODA1NDZaMGQxCzAJBgNVBAYTAktSMQ0wCwYDVQQKDARL +SVNBMS4wLAYDVQQLDCVLb3JlYSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBDZW50 +cmFsMRYwFAYDVQQDDA1LSVNBIFJvb3RDQSAxMIIBIDANBgkqhkiG9w0BAQEFAAOC +AQ0AMIIBCAKCAQEAvATk+hM58DSWIGtsaLv623f/J/es7C/n/fB/bW+MKs0lCVsk +9KFo/CjsySXirO3eyDOE9bClCTqnsUdIxcxPjHmc+QZXfd3uOPbPFLKc6tPAXXdi +8EcNuRpAU1xkcK8IWsD3z3X5bI1kKB4g/rcbGdNaZoNy4rCbvdMlFQ0yb2Q3lIVG +yHK+d9VuHygvx2nt54OJM1jT3qC/QOhDUO7cTWu8peqmyGGO9cNkrwYV3CmLP3WM +vHFE2/yttRcdbYmDz8Yzvb9Fov4Kn6MRXw+5H5wawkbMnChmn3AmPC7fqoD+jMUE +CSVPzZNHPDfqAmeS/vwiJFys0izgXAEzisEZ2wIBA6MyMDAwHQYDVR0OBBYEFL+2 +J9gDWnZlTGEBQVYx5Yt7OtnMMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEF +BQADggEBABOvUQveimpb5poKyLGQSk6hAp3MiNKrZr097LuxQpVqslxa/6FjZJap +aBV/JV6K+KRzwYCKhQoOUugy50X4TmWAkZl0Q+VFnUkq8JSV3enhMNITbslOsXfl +BM+tWh6UCVrXPAgcrnrpFDLBRa3SJkhyrKhB2vAhhzle3/xk/2F0KpzZm4tfwjeT +2KM3LzuTa7IbB6d/CVDv0zq+IWuKkDsnSlFOa56ch534eJAx7REnxqhZvvwYC/uO +fi5C4e3nCSG9uRPFVmf0JqZCQ5BEVLRxm3bkGhKsGigA35vB1fjbXKP4krG9tNT5 +UNkAAk/bg9ART6RCVmE6fhMy04Qfybo= +-----END CERTIFICATE----- +# "Microsec e-Szigno Root CA 2009" +# 3C 5F 81 FE A5 FA B8 2C 64 BF A2 EA EC AF CD E8 +# E0 77 FC 86 20 A7 CA E5 37 16 3D F3 6E DB F3 78 +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD +VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 +ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G +CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y +OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx +FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp +Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP +kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc +cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U +fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 +N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC +xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 ++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM +Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG +SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h +mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk +ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c +2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t +HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW +-----END CERTIFICATE----- +# "NetLock Arany (Class Gold) Főtanúsítvány" +# 6C 61 DA C3 A2 DE F0 31 50 6B E0 36 D2 A6 FE 40 +# 19 94 FB D1 3D F9 C8 D4 66 59 92 74 C4 46 EC 98 +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG +EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 +MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl +cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR +dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB +pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM +b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm +aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz +IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT +lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz +AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 +VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG +ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 +BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG +AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M +U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh +bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C ++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F +uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 +XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- +# "Network Solutions Certificate Authority" +# 15 F0 BA 00 A3 AC 7A F3 AC 88 4C 07 2B 10 11 A0 +# 77 BD 77 C0 97 F4 01 64 B2 F8 59 8A BD 83 86 0C +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi +MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu +MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp +dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV +UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO +ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz +c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP +OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl +mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF +BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 +qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw +gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu +bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp +dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 +6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ +h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH +/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv +wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN +pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey +-----END CERTIFICATE----- +# "OISTE WISeKey Global Root GA CA" +# 41 C9 23 86 6A B4 CA D6 B7 AD 57 80 81 58 2E 02 +# 07 97 A6 CB DF 4F FF 78 CE 83 96 B3 89 37 D7 F5 +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB +ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly +aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl +ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w +NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G +A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD +VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX +SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR +VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2 +w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF +mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg +4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9 +4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw +EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx +SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2 +ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8 +vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa +hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi +Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ +/L7fCg0= +-----END CERTIFICATE----- +# "OISTE WISeKey Global Root GB CA" +# 6B 9C 08 E8 6E B0 F7 67 CF AD 65 CD 98 B6 21 49 +# E5 49 4A 67 F5 84 5E 7B D1 ED 01 9F 27 B8 6B D6 +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt +MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg +Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i +YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x +CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG +b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh +bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 +HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx +WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX +1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk +u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P +99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r +M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB +BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh +cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 +gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO +ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf +aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- +# "OpenTrust Root CA G1" +# 56 C7 71 28 D9 8C 18 D9 1B 4C FD FF BC 25 EE 91 +# 03 D4 75 8E A2 AB AD 82 6A 90 F3 45 7D 46 0E B4 +-----BEGIN CERTIFICATE----- +MIIFbzCCA1egAwIBAgISESCzkFU5fX82bWTCp59rY45nMA0GCSqGSIb3DQEBCwUA +MEAxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9w +ZW5UcnVzdCBSb290IENBIEcxMB4XDTE0MDUyNjA4NDU1MFoXDTM4MDExNTAwMDAw +MFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwU +T3BlblRydXN0IFJvb3QgQ0EgRzEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQD4eUbalsUwXopxAy1wpLuwxQjczeY1wICkES3d5oeuXT2R0odsN7faYp6b +wiTXj/HbpqbfRm9RpnHLPhsxZ2L3EVs0J9V5ToybWL0iEA1cJwzdMOWo010hOHQX +/uMftk87ay3bfWAfjH1MBcLrARYVmBSO0ZB3Ij/swjm4eTrwSSTilZHcYTSSjFR0 +77F9jAHiOH3BX2pfJLKOYheteSCtqx234LSWSE9mQxAGFiQD4eCcjsZGT44ameGP +uY4zbGneWK2gDqdkVBFpRGZPTBKnjix9xNRbxQA0MMHZmf4yzgeEtE7NCv82TWLx +p2NX5Ntqp66/K7nJ5rInieV+mhxNaMbBGN4zK1FGSxyO9z0M+Yo0FMT7MzUj8czx +Kselu7Cizv5Ta01BG2Yospb6p64KTrk5M0ScdMGTHPjgniQlQ/GbI4Kq3ywgsNw2 +TgOzfALU5nsaqocTvz6hdLubDuHAk5/XpGbKuxs74zD0M1mKB3IDVedzagMxbm+W +G+Oin6+Sx+31QrclTDsTBM8clq8cIqPQqwWyTBIjUtz9GVsnnB47ev1CI9sjgBPw +vFEVVJSmdz7QdFG9URQIOTfLHzSpMJ1ShC5VkLG631UAC9hWLbFJSXKAqWLXwPYY +EQRVzXR7z2FwefR7LFxckvzluFqrTJOVoSfupb7PcSNCupt2LQIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUl0YhVyE1 +2jZVx/PxN3DlCPaTKbYwHwYDVR0jBBgwFoAUl0YhVyE12jZVx/PxN3DlCPaTKbYw +DQYJKoZIhvcNAQELBQADggIBAB3dAmB84DWn5ph76kTOZ0BP8pNuZtQ5iSas000E +PLuHIT839HEl2ku6q5aCgZG27dmxpGWX4m9kWaSW7mDKHyP7Rbr/jyTwyqkxf3kf +gLMtMrpkZ2CvuVnN35pJ06iCsfmYlIrM4LvgBBuZYLFGZdwIorJGnkSI6pN+VxbS +FXJfLkur1J1juONI5f6ELlgKn0Md/rcYkoZDSw6cMoYsYPXpSOqV7XAp8dUv/TW0 +V8/bhUiZucJvbI/NeJWsZCj9VrDDb8O+WVLhX4SPgPL0DTatdrOjteFkdjpY3H1P +XlZs5VVZV6Xf8YpmMIzUUmI4d7S+KNfKNsSbBfD4Fdvb8e80nR14SohWZ25g/4/I +i+GOvUKpMwpZQhISKvqxnUOOBZuZ2mKtVzazHbYNeS2WuOvyDEsMpZTGMKcmGS3t +TAZQMPH9WD25SxdfGbRqhFS0OE85og2WaMMolP3tLR9Ka0OWLpABEPs4poEL0L91 +09S5zvE/bw4cHjdx5RiHdRk/ULlepEU0rbDK5uUTdg8xFKmOLZTW1YVNcxVPS/Ky +Pu1svf0OnWZzsD2097+o4BGkxK51CUpjAEggpsadCwmKtODmzj7HPiY46SvepghJ +AwSQiumPv+i2tCqjI40cHLI5kqiPAlxAOXXUc0ECd97N4EOH1uS6SsNsEn/+KuYj +1oxx +-----END CERTIFICATE----- +# "OpenTrust Root CA G2" +# 27 99 58 29 FE 6A 75 15 C1 BF E8 48 F9 C4 76 1D +# B1 6C 22 59 29 25 7B F4 0D 08 94 F2 9E A8 BA F2 +-----BEGIN CERTIFICATE----- +MIIFbzCCA1egAwIBAgISESChaRu/vbm9UpaPI+hIvyYRMA0GCSqGSIb3DQEBDQUA +MEAxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9w +ZW5UcnVzdCBSb290IENBIEcyMB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAw +MFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwU +T3BlblRydXN0IFJvb3QgQ0EgRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQDMtlelM5QQgTJT32F+D3Y5z1zCU3UdSXqWON2ic2rxb95eolq5cSG+Ntmh +/LzubKh8NBpxGuga2F8ORAbtp+Dz0mEL4DKiltE48MLaARf85KxP6O6JHnSrT78e +CbY2albz4e6WiWYkBuTNQjpK3eCasMSCRbP+yatcfD7J6xcvDH1urqWPyKwlCm/6 +1UWY0jUJ9gNDlP7ZvyCVeYCYitmJNbtRG6Q3ffyZO6v/v6wNj0OxmXsWEH4db0fE +FY8ElggGQgT4hNYdvJGmQr5J1WqIP7wtUdGejeBSzFfdNTVY27SPJIjki9/ca1TS +gSuyzpJLHB9G+h3Ykst2Z7UJmQnlrBcUVXDGPKBWCgOz3GIZ38i1MH/1PCZ1Eb3X +G7OHngevZXHloM8apwkQHZOJZlvoPGIytbU6bumFAYueQ4xncyhZW+vj3CzMpSZy +YhK05pyDRPZRpOLAeiRXyg6lPzq1O4vldu5w5pLeFlwoW5cZJ5L+epJUzpM5ChaH +vGOz9bGTXOBut9Dq+WIyiET7vycotjCVXRIouZW+j1MY5aIYFuJWpLIsEPUdN6b4 +t/bQWVyJ98LVtZR00dX+G7bw5tYee9I8y6jj9RjzIR9u701oBnstXW5DiabA+aC/ +gh7PU3+06yzbXfZqfUAkBXKJOAGTy3HCOV0GEfZvePg3DTmEJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUajn6QiL3 +5okATV59M4PLuG53hq8wHwYDVR0jBBgwFoAUajn6QiL35okATV59M4PLuG53hq8w +DQYJKoZIhvcNAQENBQADggIBAJjLq0A85TMCl38th6aP1F5Kr7ge57tx+4BkJamz +Gj5oXScmp7oq4fBXgwpkTx4idBvpkF/wrM//T2h6OKQQbA2xx6R3gBi2oihEdqc0 +nXGEL8pZ0keImUEiyTCYYW49qKgFbdEfwFFEVn8nNQLdXpgKQuswv42hm1GqO+qT +RmTFAHneIWv2V6CG1wZy7HBGS4tz3aAhdT7cHcCP009zHIXZ/n9iyJVvttN7jLpT +wm+bREx50B1ws9efAvSyB7DH5fitIw6mVskpEndI2S9G/Tvw/HRwkqWOOAgfZDC2 +t0v7NqwQjqBSM2OdAzVWxWm9xiNaJ5T2pBL4LTM8oValX9YZ6e18CL13zSdkzJTa +TkZQh+D5wVOAHrut+0dSixv9ovneDiK3PTNZbNTe9ZUGMg1RGUFcPk8G97krgCf2 +o6p6fAbhQ8MTOWIaNr3gKC6UAuQpLmBVrkA9sHSSXvAgZJY/X0VdiLWK2gKgW0VU +3jg9CcCoSmVGFvyqv1ROTVu+OEO3KMqLM6oaJbolXCkvW0pujOotnCr2BXbgd5eA +iN1nE28daCSLT7d0geX0YJ96Vdc+N9oWaz53rK4YcJUIeSkDiv7BO7M/Gg+kO14f +WKGVyasvc0rQLW6aWQ9VGHgtPFGml4vmu7JwqkwR3v98KzfUetF3NI/n+UL3PIEM +S1IK +-----END CERTIFICATE----- +# "OpenTrust Root CA G3" +# B7 C3 62 31 70 6E 81 07 8C 36 7C B8 96 19 8F 1E +# 32 08 DD 92 69 49 DD 8F 57 09 A4 10 F7 5B 62 92 +-----BEGIN CERTIFICATE----- +MIICITCCAaagAwIBAgISESDm+Ez8JLC+BUCs2oMbNGA/MAoGCCqGSM49BAMDMEAx +CzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5U +cnVzdCBSb290IENBIEczMB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFow +QDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwUT3Bl +blRydXN0IFJvb3QgQ0EgRzMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARK7liuTcpm +3gY6oxH84Bjwbhy6LTAMidnW7ptzg6kjFYwvWYpa3RTqnVkrQ7cG7DK2uu5Bta1d +oYXM6h0UZqNnfkbilPPntlahFVmhTzeXuSIevRHr9LIfXsMUmuXZl5mjYzBhMA4G +A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRHd8MUi2I5 +DMlv4VBN0BBY3JWIbTAfBgNVHSMEGDAWgBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAK +BggqhkjOPQQDAwNpADBmAjEAj6jcnboMBBf6Fek9LykBl7+BFjNAk2z8+e2AcG+q +j9uEwov1NcoG3GRvaBbhj5G5AjEA2Euly8LQCGzpGPta3U1fJAuwACEl74+nBCZx +4nxp5V2a+EEfOzmTk51V6s2N8fvB +-----END CERTIFICATE----- +# "QuoVadis Root CA 1 G3" +# 8A 86 6F D1 B2 76 B5 7E 57 8E 92 1C 65 82 8A 2B +# ED 58 E9 F2 F2 88 05 41 34 B7 F1 F4 BF C9 CC 74 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 +MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV +wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe +rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 +68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh +4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp +UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o +abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc +3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G +KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt +hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO +Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt +zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD +ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 +cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN +qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 +YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv +b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 +8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k +NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj +ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp +q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt +nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD +-----END CERTIFICATE----- +# "QuoVadis Root CA 2" +# 85 A0 DD 7D D7 20 AD B7 FF 05 F8 3D 54 2B 20 9D +# C7 FF 45 28 F7 D6 77 B1 83 89 FE A5 E5 C4 9E 86 +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa +GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg +Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J +WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB +rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp ++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 +ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i +Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz +PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og +/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH +oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI +yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud +EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 +A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL +MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f +BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn +g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl +fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K +WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha +B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc +hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR +TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD +mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z +ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y +4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza +8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- +# "QuoVadis Root CA 2 G3" +# 8F E4 FB 0A F9 3A 4D 0D 67 DB 0B EB B2 3E 37 C7 +# 1B F3 25 DC BC DD 24 0E A0 4D AF 58 B4 7E 18 40 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 +MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf +qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW +n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym +c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ +O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 +o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j +IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq +IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz +8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh +vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l +7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG +cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD +ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC +roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga +W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n +lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE ++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV +csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd +dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg +KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM +HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 +WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M +-----END CERTIFICATE----- +# "QuoVadis Root CA 3" +# 18 F1 FC 7F 20 5D F8 AD DD EB 7F E0 07 DD 57 E3 +# AF 37 5A 9C 4D 8D 73 54 6B F4 F1 FE D1 E1 8D 35 +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM +V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB +4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr +H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd +8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv +vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT +mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe +btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc +T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt +WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ +c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A +4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD +VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG +CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 +aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu +dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw +czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G +A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg +Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 +7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem +d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd ++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B +4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN +t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x +DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 +k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s +zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j +Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT +mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK +4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- +# "QuoVadis Root CA 3 G3" +# 88 EF 81 DE 20 2E B0 18 45 2E 43 F8 64 72 5C EA +# 5F BD 1F C2 D9 D2 05 73 07 09 C5 D8 B8 69 0F 46 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 +MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR +/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu +FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR +U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c +ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR +FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k +A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw +eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl +sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp +VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q +A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ +ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD +ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI +FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv +oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg +u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP +0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf +3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl +8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ +DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN +PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ +ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- +# "QuoVadis Root Certification Authority" +# A4 5E DE 3B BB F0 9C 8A E1 5C 72 EF C0 72 68 D6 +# 93 A2 1C 99 6F D5 1E 67 CA 07 94 60 FD 6D 88 73 +-----BEGIN CERTIFICATE----- +MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz +MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw +IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR +dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp +li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D +rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ +WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug +F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU +xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC +Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv +dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw +ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl +IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh +c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy +ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh +Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI +KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T +KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq +y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p +dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD +VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL +MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk +fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8 +7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R +cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y +mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW +xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK +SnQ2+Q== +-----END CERTIFICATE----- +# "Secure Global CA" +# 42 00 F5 04 3A C8 59 0E BB 52 7D 20 9E D1 50 30 +# 29 FB CB D4 1C A1 B5 06 EC 27 F1 5A DE 7D AC 69 +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx +MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg +Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ +iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa +/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ +jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI +HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 +sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w +gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw +KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG +AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L +URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO +H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm +I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY +iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- +# "SecureTrust CA" +# F1 C1 B5 0A E5 A2 0D D8 03 0E C9 F6 BC 24 82 3D +# D3 67 B5 25 57 59 B4 E7 1B 61 FC E9 F7 37 5D 73 +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz +MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv +cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz +Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO +0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao +wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj +7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS +8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT +BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg +JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 +6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ +3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm +D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS +CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- +# "Security Communication EV RootCA1" +# A2 2D BA 68 1E 97 37 6E 2D 39 7D 72 8A AE 3A 9B +# 62 96 B9 FD BA 60 BC 2E 11 F6 47 F2 C6 75 FB 37 +-----BEGIN CERTIFICATE----- +MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDEl +MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMh +U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIz +MloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09N +IFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNlY3VyaXR5IENvbW11 +bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSE +RMqm4miO/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gO +zXppFodEtZDkBp2uoQSXWHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5 +bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4zZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDF +MxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4bepJz11sS6/vmsJWXMY1 +VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK9U2vP9eC +OKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G +CSqGSIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HW +tWS3irO4G8za+6xmiEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZ +q51ihPZRwSzJIxXYKLerJRO1RuGGAv8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDb +EJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnWmHyojf6GPgcWkuF75x3sM3Z+ +Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEWT1MKZPlO9L9O +VL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490 +-----END CERTIFICATE----- +# "Security Communication RootCA1" +# E7 5E 72 ED 9F 56 0E EC 6E B4 80 00 73 A4 3F C3 +# AD 19 19 5A 39 22 82 01 78 95 97 4A 99 02 6B 6C +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY +MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t +dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 +WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD +VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 +9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ +DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 +Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N +QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ +xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G +A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG +kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr +Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 +Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU +JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot +RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== +-----END CERTIFICATE----- +# "Security Communication RootCA2" +# 51 3B 2C EC B8 10 D4 CD E5 DD 85 39 1A DF C6 C2 +# DD 60 D8 7B B7 36 D2 B5 21 48 4A A4 7A 0E BE F6 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl +MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe +U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX +DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy +dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj +YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV +OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr +zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM +VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ +hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO +ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw +awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs +OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF +coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc +okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 +t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy +1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ +SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- +# "Sonera Class2 CA" +# 79 08 B4 03 14 C1 38 10 0B 51 8D 07 35 80 7F FB +# FC F8 51 8A 00 95 33 71 05 BA 38 6B 15 3D D9 27 +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP +MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx +MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV +BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o +Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt +5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s +3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej +vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu +8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw +DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG +MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil +zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/ +3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD +FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6 +Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2 +ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M +-----END CERTIFICATE----- +# "SSL.com EV Root Certification Authority ECC" +# 22 A2 C1 F7 BD ED 70 4C C1 E7 01 B5 F4 08 C3 10 +# 88 0F E9 56 B5 DE 2A 4A 44 F9 9C 87 3A 25 A7 C8 +-----BEGIN CERTIFICATE----- +MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx +NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv +bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA +VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku +WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX +5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ +ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg +h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== +-----END CERTIFICATE----- +# "SSL.com EV Root Certification Authority RSA R2" +# 2E 7B F1 6C C2 24 85 A7 BB E2 AA 86 96 75 07 61 +# B0 AE 39 BE 3B 2F E9 D0 CC 6D 4E F7 34 91 42 5C +-----BEGIN CERTIFICATE----- +MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV +BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE +CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy +MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G +A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD +DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq +M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf +OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa +4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 +HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR +aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA +b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ +Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV +PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO +pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu +UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY +MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV +HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 +9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW +s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 +Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg +cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM +79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz +/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt +ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm +Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK +QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ +w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi +S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 +mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== +-----END CERTIFICATE----- +# "SSL.com Root Certification Authority ECC" +# 34 17 BB 06 CC 60 07 DA 1B 96 1C 92 0B 8A B4 CE +# 3F AD 82 0E 4A A3 0B 9A CB C4 A7 4E BD CE BC 65 +-----BEGIN CERTIFICATE----- +MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz +WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 +b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS +b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI +7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg +CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD +VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T +kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ +gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl +-----END CERTIFICATE----- +# "SSL.com Root Certification Authority RSA" +# 85 66 6A 56 2E E0 BE 5C E9 25 C1 D8 89 0A 6F 76 +# A8 7E C1 6D 4D 7D 5F 29 EA 74 19 CF 20 12 3B 69 +-----BEGIN CERTIFICATE----- +MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE +BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK +DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz +OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv +bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R +xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX +qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC +C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 +6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh +/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF +YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E +JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc +US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 +ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm ++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi +M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G +A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV +cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc +Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs +PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ +q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 +cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr +a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I +H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y +K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu +nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf +oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY +Ic2wBlX7Jz9TkHCpBB5XJ7k= +-----END CERTIFICATE----- +# "Staat der Nederlanden EV Root CA" +# 4D 24 91 41 4C FE 95 67 46 EC 4C EF A6 CF 6F 72 +# E2 8A 13 29 43 2F 9D 8A 90 7A C4 CB 5D AD C1 5A +-----BEGIN CERTIFICATE----- +MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y +MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg +TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS +b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS +M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC +UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d +Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p +rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l +pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb +j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC +KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS +/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X +cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH +1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP +px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 +MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI +eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u +2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS +v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC +wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy +CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e +vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 +Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa +Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL +eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 +FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc +7uzXLg== +-----END CERTIFICATE----- +# "Staat der Nederlanden Root CA - G2" +# 66 8C 83 94 7D A6 3B 72 4B EC E1 74 3C 31 A0 E6 +# AE D0 DB 8E C5 B3 1B E3 77 BB 78 4F 91 B6 71 6F +-----BEGIN CERTIFICATE----- +MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oX +DTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl +ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv +b3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ5291 +qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8Sp +uOUfiUtnvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPU +Z5uW6M7XxgpT0GtJlvOjCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvE +pMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiile7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp +5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCROME4HYYEhLoaJXhena/M +UGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpICT0ugpTN +GmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy +5V6548r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv +6q012iDTiIJh8BIitrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEK +eN5KzlW/HdXZt1bv8Hb/C3m1r737qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6 +B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMBAAGjgZcwgZQwDwYDVR0TAQH/ +BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcCARYxaHR0cDov +L3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqG +SIb3DQEBCwUAA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLyS +CZa59sCrI2AGeYwRTlHSeYAz+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen +5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwjf/ST7ZwaUb7dRUG/kSS0H4zpX897 +IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaNkqbG9AclVMwWVxJK +gnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfkCpYL ++63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxL +vJxxcypFURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkm +bEgeqmiSBeGCc1qb3AdbCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvk +N1trSt8sV4pAWja63XVECDdCcAz+3F4hoKOKwJCcaNpQ5kUQR3i2TtJlycM33+FC +Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z +ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ== +-----END CERTIFICATE----- +# "Staat der Nederlanden Root CA - G3" +# 3C 4F B0 B9 5A B8 B3 00 32 F4 32 B8 6F 53 5F E1 +# 72 C1 85 D0 FD 39 86 58 37 CF 36 18 7F A6 F4 28 +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX +DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl +ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv +b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP +cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW +IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX +xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy +KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR +9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az +5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8 +6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7 +Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP +bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt +BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt +XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF +MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd +INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD +U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp +LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8 +Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp +gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh +/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw +0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A +fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq +4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR +1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/ +QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM +94B7IWcnMFk= +-----END CERTIFICATE----- +# "Starfield Class 2 Certification Authority" +# 14 65 FA 20 53 97 B8 76 FA A6 F0 A9 95 8E 55 90 +# E4 0F CC 7F AA 4F B7 C2 C8 67 75 21 FB 5F B6 58 +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl +MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp +U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw +NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE +ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp +ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 +DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf +8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN ++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 +X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa +K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA +1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G +A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR +zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 +YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD +bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 +L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D +eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp +VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY +WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- +# "Starfield Root Certificate Authority - G2" +# 2C E1 CB 0B F9 D2 F9 E1 02 99 3F BE 21 51 52 C3 +# B2 DD 0C AB DE 1C 68 E5 31 9B 83 91 54 DB B7 F5 +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs +ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw +MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj +aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp +Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg +nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 +HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N +Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN +dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 +HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G +CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU +sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 +4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg +8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 +mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- +# "Starfield Services Root Certificate Authority - G2" +# 56 8D 69 05 A2 C8 87 08 A4 B3 02 51 90 ED CF ED +# B1 97 4A 60 6A 13 C6 E5 29 0F CB 2A E6 3E DA B5 +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs +ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy +ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy +dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p +OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 +8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K +Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe +hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk +6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q +AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI +bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB +ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z +qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn +0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN +sSi6 +-----END CERTIFICATE----- +# "StartCom Certification Authority" +# C7 66 A9 BE F2 D4 07 1C 86 3A 31 AA 49 20 E8 13 +# B2 D1 98 60 8C B7 B7 CF E2 11 43 B8 36 DF 09 EA +-----BEGIN CERTIFICATE----- +MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW +MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg +Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9 +MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi +U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh +cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk +pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf +OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C +Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT +Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi +HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM +Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w ++2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ +Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 +Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B +26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID +AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE +FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j +ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js +LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM +BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0 +Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy +dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh +cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh +YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg +dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp +bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ +YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT +TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ +9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8 +jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW +FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz +ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1 +ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L +EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu +L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq +yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC +O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V +um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh +NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14= +-----END CERTIFICATE----- +# "StartCom Certification Authority" +# E1 78 90 EE 09 A3 FB F4 F4 8B 9C 41 4A 17 D6 37 +# B7 A5 06 47 E9 BC 75 23 22 72 7F CC 17 42 A9 11 +-----BEGIN CERTIFICATE----- +MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEW +MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg +Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM3WhcNMzYwOTE3MTk0NjM2WjB9 +MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi +U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh +cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk +pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf +OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C +Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT +Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi +HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM +Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w ++2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ +Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 +Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B +26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID +AQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFul +F2mHMMo0aEPQQa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCC +ATgwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w +ZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVybWVk +aWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENvbW1lcmNpYWwgKFN0 +YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0aGUg +c2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93 +d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgG +CWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1 +dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5fPGFf59Jb2vKXfuM/gTF +wWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWmN3PH/UvS +Ta0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst +0OcNOrg+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNc +pRJvkrKTlMeIFw6Ttn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKl +CcWw0bdT82AUuoVpaiF8H3VhFyAXe2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVF +P0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA2MFrLH9ZXF2RsXAiV+uKa0hK +1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBsHvUwyKMQ5bLm +KhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE +JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ +8dCAWZvLMdibD4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnm +fyWl8kgAwKQB2j8= +-----END CERTIFICATE----- +# "StartCom Certification Authority G2" +# C7 BA 65 67 DE 93 A7 98 AE 1F AA 79 1E 71 2D 37 +# 8F AE 1F 93 C4 39 7F EA 44 1B B7 CB E6 FD 59 95 +-----BEGIN CERTIFICATE----- +MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEW +MBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkgRzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1 +OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoG +A1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRzIwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8Oo1XJ +JZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsD +vfOpL9HG4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnoo +D/Uefyf3lLE3PbfHkffiAez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/ +Q0kGi4xDuFby2X8hQxfqp0iVAXV16iulQ5XqFYSdCI0mblWbq9zSOdIxHWDirMxW +RST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbsO+wmETRIjfaAKxojAuuK +HDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8HvKTlXcxN +nw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM +0D4LnMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/i +UUjXuG+v+E5+M5iSFGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9 +Ha90OrInwMEePnWjFqmveiJdnxMaz6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHg +TuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJKoZIhvcNAQEL +BQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K +2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfX +UfEpY9Z1zRbkJ4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl +6/2o1PXWT6RbdejF0mCy2wl+JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK +9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG/+gyRr61M3Z3qAFdlsHB1b6uJcDJ +HgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTcnIhT76IxW1hPkWLI +wpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/XldblhY +XzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5l +IxKVCCIcl85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoo +hdVddLHRDiBYmxOlsGOm7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulr +so8uBtjRkcfGEvRM/TAXw8HaOFvjqermobp573PYtlNXLfbQ4ddI +-----END CERTIFICATE----- +# "Swisscom Root CA 1" +# 21 DB 20 12 36 60 BB 2E D4 18 20 5D A1 1E E7 A8 +# 5A 65 E2 BC 6E 55 B5 AF 7E 78 99 C8 A2 66 D9 2E +-----BEGIN CERTIFICATE----- +MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBk +MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0 +YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg +Q0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4MTgyMjA2MjBaMGQxCzAJBgNVBAYT +AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp +Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9 +m2BtRsiMMW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdih +FvkcxC7mlSpnzNApbjyFNDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/ +TilftKaNXXsLmREDA/7n29uj/x2lzZAeAR81sH8A25Bvxn570e56eqeqDFdvpG3F +EzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkCb6dJtDZd0KTeByy2dbco +kdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn7uHbHaBu +HYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNF +vJbNcA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo +19AOeCMgkckkKmUpWyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjC +L3UcPX7ape8eYIVpQtPM+GP+HkM5haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJW +bjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNYMUJDLXT5xp6mig/p/r+D5kNX +JLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw +FDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j +BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzc +K6FptWfUjNP9MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzf +ky9NfEBWMXrrpA9gzXrzvsMnjgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7Ik +Vh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQMbFamIp1TpBcahQq4FJHgmDmHtqB +sfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4HVtA4oJVwIHaM190e +3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtlvrsR +ls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ip +mXeascClOS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HH +b6D0jqTsNFFbjCYDcKF31QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksf +rK/7DZBaZmBwXarNeNQk7shBoJMBkpxqnvy5JMWzFYJ+vq6VK+uxwNrjAWALXmms +hFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCyx/yP2FS1k2Kdzs9Z+z0Y +zirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMWNY6E0F/6 +MBr1mmz0DlP5OlvRHA== +-----END CERTIFICATE----- +# "Swisscom Root CA 2" +# F0 9B 12 2C 71 14 F4 A0 9B D4 EA 4F 4A 99 D5 58 +# B4 6E 4C 25 CD 81 14 0D 29 C0 56 13 91 4C 38 41 +-----BEGIN CERTIFICATE----- +MIIF2TCCA8GgAwIBAgIQHp4o6Ejy5e/DfEoeWhhntjANBgkqhkiG9w0BAQsFADBk +MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0 +YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg +Q0EgMjAeFw0xMTA2MjQwODM4MTRaFw0zMTA2MjUwNzM4MTRaMGQxCzAJBgNVBAYT +AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp +Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAyMIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlUJOhJ1R5tMJ6HJaI2nbeHCOFvEr +jw0DzpPMLgAIe6szjPTpQOYXTKueuEcUMncy3SgM3hhLX3af+Dk7/E6J2HzFZ++r +0rk0X2s682Q2zsKwzxNoysjL67XiPS4h3+os1OD5cJZM/2pYmLcX5BtS5X4HAB1f +2uY+lQS3aYg5oUFgJWFLlTloYhyxCwWJwDaCFCE/rtuh/bxvHGCGtlOUSbkrRsVP +ACu/obvLP+DHVxxX6NZp+MEkUp2IVd3Chy50I9AU/SpHWrumnf2U5NGKpV+GY3aF +y6//SSj8gO1MedK75MDvAe5QQQg1I3ArqRa0jG6F6bYRzzHdUyYb3y1aSgJA/MTA +tukxGggo5WDDH8SQjhBiYEQN7Aq+VRhxLKX0srwVYv8c474d2h5Xszx+zYIdkeNL +6yxSNLCK/RJOlrDrcH+eOfdmQrGrrFLadkBXeyq96G4DsguAhYidDMfCd7Camlf0 +uPoTXGiTOmekl9AbmbeGMktg2M7v0Ax/lZ9vh0+Hio5fCHyqW/xavqGRn1V9TrAL +acywlKinh/LTSlDcX3KwFnUey7QYYpqwpzmqm59m2I2mbJYV4+by+PGDYmy7Velh +k6M99bFXi08jsJvllGov34zflVEpYKELKeRcVVi3qPyZ7iVNTA6z00yPhOgpD/0Q +VAKFyPnlw4vP5w8CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw +FDASBgdghXQBUwIBBgdghXQBUwIBMBIGA1UdEwEB/wQIMAYBAf8CAQcwHQYDVR0O +BBYEFE0mICKJS9PVpAqhb97iEoHF8TwuMB8GA1UdIwQYMBaAFE0mICKJS9PVpAqh +b97iEoHF8TwuMA0GCSqGSIb3DQEBCwUAA4ICAQAyCrKkG8t9voJXiblqf/P0wS4R +fbgZPnm3qKhyN2abGu2sEzsOv2LwnN+ee6FTSA5BesogpxcbtnjsQJHzQq0Qw1zv +/2BZf82Fo4s9SBwlAjxnffUy6S8w5X2lejjQ82YqZh6NM4OKb3xuqFp1mrjX2lhI +REeoTPpMSQpKwhI3qEAMw8jh0FcNlzKVxzqfl9NX+Ave5XLzo9v/tdhZsnPdTSpx +srpJ9csc1fV5yJmz/MFMdOO0vSk3FQQoHt5FRnDsr7p4DooqzgB53MBfGWcsa0vv +aGgLQ+OswWIJ76bdZWGgr4RVSJFSHMYlkSrQwSIjYVmvRRGFHQEkNI/Ps/8XciAT +woCqISxxOQ7Qj1zB09GOInJGTB2Wrk9xseEFKZZZ9LuedT3PDTcNYtsmjGOpI99n +Bjx8Oto0QuFmtEYE3saWmA9LSHokMnWRn6z3aOkquVVlzl1h0ydw2Df+n7mvoC5W +t6NlUe07qxS/TFED6F+KBZvuim6c779o+sjaC+NCydAXFJy3SuCvkychVSa1ZC+N +8f+mQAWFBVzKBxlcCxMoTFh/wqXvRdpg065lYZ1Tg3TCrvJcwhbtkj6EPnNgiLx2 +9CzP0H1907he0ZESEOnN3col49XtmS++dYFLJPlFRpTJKSFTnCZFqhMX5OfNeOI5 +wSsSnqaeG8XmDtkx2Q== +-----END CERTIFICATE----- +# "Swisscom Root EV CA 2" +# D9 5F EA 3C A4 EE DC E7 4C D7 6E 75 FC 6D 1F F6 +# 2C 44 1F 0F A8 BC 77 F0 34 B1 9E 5D B2 58 01 5D +-----BEGIN CERTIFICATE----- +MIIF4DCCA8igAwIBAgIRAPL6ZOJ0Y9ON/RAdBB92ylgwDQYJKoZIhvcNAQELBQAw +ZzELMAkGA1UEBhMCY2gxETAPBgNVBAoTCFN3aXNzY29tMSUwIwYDVQQLExxEaWdp +dGFsIENlcnRpZmljYXRlIFNlcnZpY2VzMR4wHAYDVQQDExVTd2lzc2NvbSBSb290 +IEVWIENBIDIwHhcNMTEwNjI0MDk0NTA4WhcNMzEwNjI1MDg0NTA4WjBnMQswCQYD +VQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2Vy +dGlmaWNhdGUgU2VydmljZXMxHjAcBgNVBAMTFVN3aXNzY29tIFJvb3QgRVYgQ0Eg +MjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMT3HS9X6lds93BdY7Bx +UglgRCgzo3pOCvrY6myLURYaVa5UJsTMRQdBTxB5f3HSek4/OE6zAMaVylvNwSqD +1ycfMQ4jFrclyxy0uYAyXhqdk/HoPGAsp15XGVhRXrwsVgu42O+LgrQ8uMIkqBPH +oCE2G3pXKSinLr9xJZDzRINpUKTk4RtiGZQJo/PDvO/0vezbE53PnUgJUmfANykR +HvvSEaeFGHR55E+FFOtSN+KxRdjMDUN/rhPSays/p8LiqG12W0OfvrSdsyaGOx9/ +5fLoZigWJdBLlzin5M8J0TbDC77aO0RYjb7xnglrPvMyxyuHxuxenPaHZa0zKcQv +idm5y8kDnftslFGXEBuGCxobP/YCfnvUxVFkKJ3106yDgYjTdLRZncHrYTNaRdHL +OdAGalNgHa/2+2m8atwBz735j9m9W8E6X47aD0upm50qKGsaCnw8qyIL5XctcfaC +NYGu+HuB5ur+rPQam3Rc6I8k9l2dRsQs0h4rIWqDJ2dVSqTjyDKXZpBy2uPUZC5f +46Fq9mDU5zXNysRojddxyNMkM3OxbPlq4SjbX8Y96L5V5jcb7STZDxmPX2MYWFCB +UWVv8p9+agTnNCRxunZLWB4ZvRVgRaoMEkABnRDixzgHcgplwLa7JSnaFp6LNYth +7eVxV4O1PHGf40+/fh6Bn0GXAgMBAAGjgYYwgYMwDgYDVR0PAQH/BAQDAgGGMB0G +A1UdIQQWMBQwEgYHYIV0AVMCAgYHYIV0AVMCAjASBgNVHRMBAf8ECDAGAQH/AgED +MB0GA1UdDgQWBBRF2aWBbj2ITY1x0kbBbkUe88SAnTAfBgNVHSMEGDAWgBRF2aWB +bj2ITY1x0kbBbkUe88SAnTANBgkqhkiG9w0BAQsFAAOCAgEAlDpzBp9SSzBc1P6x +XCX5145v9Ydkn+0UjrgEjihLj6p7jjm02Vj2e6E1CqGdivdj5eu9OYLU43otb98T +PLr+flaYC/NUn81ETm484T4VvwYmneTwkLbUwp4wLh/vx3rEUMfqe9pQy3omywC0 +Wqu1kx+AiYQElY2NfwmTv9SoqORjbdlk5LgpWgi/UOGED1V7XwgiG/W9mR4U9s70 +WBCCswo9GcG/W6uqmdjyMb3lOGbcWAXH7WMaLgqXfIeTK7KK4/HsGOV1timH59yL +Gn602MnTihdsfSlEvoqq9X46Lmgxk7lq2prg2+kupYTNHAq4Sgj5nPFhJpiTt3tm +7JFe3VE/23MPrQRYCd0EApUKPtN236YQHoA96M2kZNEzx5LH4k5E4wnJTsJdhw4S +nr8PyQUQ3nqjsTzyP6WqJ3mtMX0f/fwZacXduT98zca0wjAefm6S139hdlqP65VN +vBFuIXxZN5nQBrz5Bm0yFqXZaajh3DyAHmBR3NdUIR7KYndP+tiPsys6DXhyyWhB +WkdKwqPrGtcKqzwyVcgKEZzfdNbwQBUdyLmPtTbFr/giuMod89a2GQ+fYWVq6nTI +fI/DT11lgh/ZDYnadXL77/FHZxOzyNEZiCcmmpl5fx7kLD977vHeTYuWl8PVP3wb +I+2ksx0WckNLIOFZfsLorSa/ovc= +-----END CERTIFICATE----- +# "SwissSign Gold CA - G2" +# 62 DD 0B E9 B9 F5 0A 16 3E A0 F8 E7 5C 05 3B 1E +# CA 57 EA 55 C8 68 8F 64 7C 68 81 F2 C8 35 7B 95 +-----BEGIN CERTIFICATE----- +MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV +BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln +biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF +MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT +d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8 +76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+ +bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c +6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE +emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd +MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt +MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y +MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y +FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi +aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM +gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB +qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7 +lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn +8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov +L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6 +45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO +UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5 +O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC +bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv +GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a +77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC +hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3 +92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp +Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w +ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt +Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ +-----END CERTIFICATE----- +# "SwissSign Gold Root CA - G3" +# 7A F6 EA 9F 75 3A 1E 70 9B D6 4D 0B EB 86 7C 11 +# E8 C2 95 A5 6E 24 A6 E0 47 14 59 DC CD AA 15 58 +-----BEGIN CERTIFICATE----- +MIIFejCCA2KgAwIBAgIJAN7E8kTzHab8MA0GCSqGSIb3DQEBCwUAMEoxCzAJBgNV +BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxJDAiBgNVBAMTG1N3aXNzU2ln +biBHb2xkIFJvb3QgQ0EgLSBHMzAeFw0wOTA4MDQxMzMxNDdaFw0zNzA4MDQxMzMx +NDdaMEoxCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxJDAiBgNV +BAMTG1N3aXNzU2lnbiBHb2xkIFJvb3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBAMPon8hlWp1nG8FFl7S0h0NbYWCAnvJ/XvlnRN1E+qu1 +q3f/KhlMzm/Ej0Gf4OLNcuDR1FJhQQkKvwpw++CDaWEpytsimlul5t0XlbBvhI46 +PmRaQfsbWPz9Kz6ypOasyYK8zvaV+Jd37Sb2WK6eJ+IPg+zFNljIe8/Vh6GphxoT +Z2EBbaZpnOKQ8StoZfPosHz8gj3erdgKAAlEeROc8P5udXvCvLNZAQt8xdUt8L// +bVfSSYHrtLNQrFv5CxUVjGn/ozkB7fzc3CeXjnuL1Wqm1uAdX80Bkeb1Ipi6LgkY +OG8TqIHS+yE35y20YueBkLDGeVm3Z3X+vo87+jbsr63ST3Q2AeVXqyMEzEpel89+ +xu+MzJUjaY3LOMcZ9taKABQeND1v2gwLw7qX/BFLUmE+vzNnUxC/eBsJwke6Hq9Y +9XWBf71W8etW19lpDAfpNzGwEhwy71bZvnorfL3TPbxqM006PFAQhyfHegpnU9t/ +gJvoniP6+Qg6i6GONFpIM19k05eGBxl9iJTOKnzFat+vvKmfzTqmurtU+X+P388O +WsStmryzOndzg0yTPJBotXxQlRHIgl6UcdBBGPvJxmXszom2ziKzEVs/4J0+Gxho +DaoDoWdZv2udvPjyZS+aQTpF2F7QNmxvOx5jtI6YTBPbIQ6fe+3qoKpxw+ujoNIl +AgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBRclwZGNKvfMMV8xQ1VcWYwtWCPnjAfBgNVHSMEGDAWgBRclwZGNKvfMMV8 +xQ1VcWYwtWCPnjANBgkqhkiG9w0BAQsFAAOCAgEAd0tN3uqFSqssJ9ZFx/FfIMFb +YO0Hy6Iz3DbPx5TxBsfV2s/NrYQ+/xJIf0HopWZXMMQd5KcaLy1Cwe9Gc7LV9Vr9 +Dnpr0sgxow1IlldlY1UYwPzkisyYhlurDIonN/ojaFlcJtehwcK5Tiz/KV7mlAu+ +zXJPleiP9ve4Pl7Oz54RyawDKUiKqbamNLmsQP/EtnM3scd/qVHbSypHX0AkB4gG +tySz+3/3sIsz+r8jdaNc/qplGsK+8X2BdwOBsY3XlQ16PEKYt4+pfVDh31IGmqBS +VHiDB2FSCTdeipynxlHRXGPRhNzC29L6Wxg2fWa81CiXL3WWHIQHrIuOUxG+JCGq +Z/LBrYic07B4Z3j101gDIApdIPG152XMDiDj1d/mLxkrhWjBBCbPj+0FU6HdBw7r +QSbHtKksW+NpPWbAYhvAqobAN8MxBIZwOb5rXyFAQaB/5dkPOEtwX0n4hbgrLqof +k0FD+PuydDwfS1dbt9RRoZJKzr4Qou7YFCJ7uUG9jemIqdGPAxpg/z+HiaCZJyJm +sD5onnKIUTidEz5FbQXlRrVz7UOGsRQKHrzaDb8eJFxmjw6+of3G62m8Q3nXA3b5 +3IeZuJjEzX9tEPkQvixC/pwpTYNrCr21jsRIiv0hB6aAfR+b6au9gmFECnEnX22b +kJ6u/zYks2gD1pWMa3M= +-----END CERTIFICATE----- +# "SwissSign Platinum CA - G2" +# 3B 22 2E 56 67 11 E9 92 30 0D C0 B1 5A B9 47 3D +# AF DE F8 C8 4D 0C EF 7D 33 17 B4 C1 82 1D 14 36 +-----BEGIN CERTIFICATE----- +MIIFwTCCA6mgAwIBAgIITrIAZwwDXU8wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE +BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEjMCEGA1UEAxMaU3dpc3NTaWdu +IFBsYXRpbnVtIENBIC0gRzIwHhcNMDYxMDI1MDgzNjAwWhcNMzYxMDI1MDgzNjAw +WjBJMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMSMwIQYDVQQD +ExpTd2lzc1NpZ24gUGxhdGludW0gQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAMrfogLi2vj8Bxax3mCq3pZcZB/HL37PZ/pEQtZ2Y5Wu669y +IIpFR4ZieIbWIDkm9K6j/SPnpZy1IiEZtzeTIsBQnIJ71NUERFzLtMKfkr4k2Htn +IuJpX+UFeNSH2XFwMyVTtIc7KZAoNppVRDBopIOXfw0enHb/FZ1glwCNioUD7IC+ +6ixuEFGSzH7VozPY1kneWCqv9hbrS3uQMpe5up1Y8fhXSQQeol0GcN1x2/ndi5ob +jM89o03Oy3z2u5yg+gnOI2Ky6Q0f4nIoj5+saCB9bzuohTEJfwvH6GXp43gOCWcw +izSC+13gzJ2BbWLuCB4ELE6b7P6pT1/9aXjvCR+htL/68++QHkwFix7qepF6w9fl ++zC8bBsQWJj3Gl/QKTIDE0ZNYWqFTFJ0LwYfexHihJfGmfNtf9dng34TaNhxKFrY +zt3oEBSa/m0jh26OWnA81Y0JAKeqvLAxN23IhBQeW71FYyBrS3SMvds6DsHPWhaP +pZjydomyExI7C3d3rLvlPClKknLKYRorXkzig3R3+jVIeoVNjZpTxN94ypeRSCtF +KwH3HBqi7Ri6Cr2D+m+8jVeTO9TUps4e8aCxzqv9KyiaTxvXw3LbpMS/XUz13XuW +ae5ogObnmLo2t/5u7Su9IPhlGdpVCX4l3P5hYnL5fhgC72O00Puv5TtjjGePAgMB +AAGjgawwgakwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFFCvzAeHFUdvOMW0ZdHelarp35zMMB8GA1UdIwQYMBaAFFCvzAeHFUdvOMW0 +ZdHelarp35zMMEYGA1UdIAQ/MD0wOwYJYIV0AVkBAQEBMC4wLAYIKwYBBQUHAgEW +IGh0dHA6Ly9yZXBvc2l0b3J5LnN3aXNzc2lnbi5jb20vMA0GCSqGSIb3DQEBBQUA +A4ICAQAIhab1Fgz8RBrBY+D5VUYI/HAcQiiWjrfFwUF1TglxeeVtlspLpYhg0DB0 +uMoI3LQwnkAHFmtllXcBrqS3NQuB2nEVqXQXOHtYyvkv+8Bldo1bAbl93oI9ZLi+ +FHSjClTTLJUYFzX1UWs/j6KWYTl4a0vlpqD4U99REJNi54Av4tHgvI42Rncz7Lj7 +jposiU0xEQ8mngS7twSNC/K5/FqdOxa3L8iYq/6KUFkuozv8KV2LwUvJ4ooTHbG/ +u0IdUt1O2BReEMYxB+9xJ/cbOQncguqLs5WGXv312l0xpuAxtpTmREl0xRbl9x8D +YSjFyMsSoEJL+WuICI20MhjzdZ/EfwBPBZWcoxcCw7NTm6ogOSkrZvqdr16zktK1 +puEa+S1BaYEUtLS17Yk9zvupnTVCRLEcFHOBzyoBNZox1S2PbYTfgE1X4z/FhHXa +icYwu+uPyyIIoK6q8QNsOktNCaUOcsZWayFCTiMlFGiudgp8DAdwZPmaL/YFOSbG +DI8Zf0NebvRbFS/bYV3mZy8/CJT5YLSYMdp08YSTcU1f+2BY0fvEwW2JorsgH51x +kcsymxM9Pn2SUjWskpSi0xjCfMfqr3YFFt1nJ8J+HAciIfNAChs0B0QTwoRqjt8Z +Wr9/6x3iGjjRXK9HkmuAtTClyY3YqzGBH9/CZjfTk6mFhnll0g== +-----END CERTIFICATE----- +# "SwissSign Platinum Root CA - G3" +# 59 B3 82 9F 1F F4 43 34 49 58 FA E8 BF F6 21 B6 +# 84 C8 48 CF BF 7E AD 6B 63 A6 CA 50 F2 79 4F 89 +-----BEGIN CERTIFICATE----- +MIIFgTCCA2mgAwIBAgIIIj+pFyDegZQwDQYJKoZIhvcNAQELBQAwTjELMAkGA1UE +BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEoMCYGA1UEAxMfU3dpc3NTaWdu +IFBsYXRpbnVtIFJvb3QgQ0EgLSBHMzAeFw0wOTA4MDQxMzM0MDRaFw0zNzA4MDQx +MzM0MDRaME4xCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxKDAm +BgNVBAMTH1N3aXNzU2lnbiBQbGF0aW51bSBSb290IENBIC0gRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCUoO8TG59EIBvNxaoiu9nyUj56Wlh35o2h +K8ncpPPksxOUAGKbHPJDUEOBfq8wNkmsGIkMGEW4PsdUbePYmllriholqba1Dbd9 +I/BffagHqfc+hi7IAU3c5jbtHeU3B2kSS+OD0QQcJPAfcHHnGe1zSG6VKxW2VuYC +31bpm/rqpu7gwsO64MzGyHvXbzqVmzqPvlss0qmgOD7WiOGxYhOO3KswZ82oaqZj +K4Kwy8c9Tu1y9n2rMk5lAusPmXT4HBoojA5FAJMsFJ9txxue9orce3jjtJRHHU0F +bYR6kFSynot1woDfhzk/n/tIVAeNoCn1+WBfWnLou5ugQuAIADSjFTwT49YaawKy +lCGjnUG8KmtOMzumlDj8PccrM7MuKwZ0rJsQb8VORfddoVYDLA1fer0e3h13kGva +pS2KTOnfQfTnS+x9lUKfTKkJD0OIPz2T5yv0ekjaaMTdEoAxGl0kVCamJCGzTK3a +Fwg2AlfGnIZwyXXJnnxh2HjmuegUafkcECgSXUt1ULo80GdwVVVWS/s9HNjbeU2X +37ie2xcs1TUHuFCp9473Vv96Z0NPINnKZtY4YEvulDHWDaJIm/80aZTGNfWWiO+q +ZsyBputMU/8ydKe2nZhXtLomqfEzM2J+OrADEVf/3G8RI60+xgrQzFS3LcKTHeXC +pozH2O9T9wIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUVio/kFj0F1oUstcIG4VbVGpUGigwHwYDVR0jBBgwFoAUVio/ +kFj0F1oUstcIG4VbVGpUGigwDQYJKoZIhvcNAQELBQADggIBAGztiudDqHknm7jP +hz5kOBiMEUKShjfgWMMb7gQu94TsgxBoDH94LZzCl442ThbYDuprSK1Pnl0NzA2p +PhiFfsxomTk11tifhsEy+01lsyIUS8iFZtoX/3GRrJxWV95xLFZCv/jNDvCi0//S +IhX70HgKfuGwWs6ON9upnueVz2PyLA3S+m/zyNX7ALf3NWcQ03tS7BAy+L/dXsmm +gqTxsL8dLt0l5L1N8DWpkQFH+BAClFvrPusNutUdYyylLqvn4x6j7kuqX7FmAbSC +WvlGS8fx+N8svv113ZY4mjc6bqXmMhVus5DAOYp0pZWgvg0uiXnNKVaOw15XUcQF +bwRVj4HpTL1ZRssqvE3JHfLGTwXkyAQN925P2sM6nNLC9enGJHoUPhxCMKgCRTGp +/FCp3NyGOA9bkz9/CE5qDSc6EHlWwxW4PgaG9tlwZ691eoviWMzGdU8yVcVsFAko +O/KV5GreLCgHraB9Byjd1Fqj6aZ8E4yZC1J429nR3z5aQ3Z/RmBTws3ndkd8Vc20 +OWQQW5VLNV1EgyTV4C4kDMGAbmkAgAZ3CmaCEAxRbzeJV9vzTOW4ue4jZpdgt1Ld +2Zb7uoo7oE3OXvBETJDMIU8bOphrjjGD+YMIUssZwTVr7qEVW4g/bazyNJJTpjAq +E9fmhqhd2ULSx52peovL3+6iMcLl +-----END CERTIFICATE----- +# "SwissSign Silver CA - G2" +# BE 6C 4D A2 BB B9 BA 59 B6 F3 93 97 68 37 42 46 +# C3 C0 05 99 3F A9 8F 02 0D 1D ED BE D4 8A 81 D5 +-----BEGIN CERTIFICATE----- +MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE +BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu +IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow +RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY +U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv +Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br +YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF +nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH +6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt +eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/ +c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ +MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH +HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf +jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6 +5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB +rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU +F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c +wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 +cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB +AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp +WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9 +xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ +2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ +IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8 +aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X +em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR +dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/ +OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+ +hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy +tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u +-----END CERTIFICATE----- +# "SwissSign Silver Root CA - G3" +# 1E 49 AC 5D C6 9E 86 D0 56 5D A2 C1 30 5C 41 93 +# 30 B0 B7 81 BF EC 50 E5 4A 1B 35 AF 7F DD D5 01 +-----BEGIN CERTIFICATE----- +MIIFfjCCA2agAwIBAgIJAKqIsFoLsXabMA0GCSqGSIb3DQEBCwUAMEwxCzAJBgNV +BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxJjAkBgNVBAMTHVN3aXNzU2ln +biBTaWx2ZXIgUm9vdCBDQSAtIEczMB4XDTA5MDgwNDEzMTkxNFoXDTM3MDgwNDEz +MTkxNFowTDELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEmMCQG +A1UEAxMdU3dpc3NTaWduIFNpbHZlciBSb290IENBIC0gRzMwggIiMA0GCSqGSIb3 +DQEBAQUAA4ICDwAwggIKAoICAQC+h5sF5nF8Um9t7Dep6bPczF9/01DqIZsE8D2/ +vo7JpRQWMhDPmfzscK1INmckDBcy1inlSjmxN+umeAxsbxnKTvdR2hro+iE4bJWc +L9aLzDsCm78mmxFFtrg0Wh2mVEhSyJ14cc5ISsyneIPcaKtmHncH0zYYCNfUbWD4 +8HnTMzYJkmO3BJr1p5baRa90GvyC46hbDjo/UleYfrycjMHAslrfxH7+DKZUdoN+ +ut3nKvRKNk+HZS6lujmNWWEp89OOJHCMU5sRpUcHsnUFXA2E2UTZzckmRFduAn2V +AdSrJIbuPXD7V/qwKRTQnfLFl8sJyvHyPefYS5bpiC+eR1GKVGWYSNIS5FR3DAfm +vluc8d0Dfo2E/L7JYtX8yTroibVfwgVSYfCcPuwuTYxykY7IQ8GiKF71gCTc4i+H +O1MA5cvwsnyNeRmgiM14+MWKWnflBqzdSt7mcG6+r771sasOCLDboD+Uxb4Subx7 +J3m1MildrsUgI5IDe1Q5sIkiVG0S48N46jpA/aSTrOktiDzbpkdmTN/YF+0W3hrW +10Fmvx2A8aTgZBEpXgwnBWLr5cQEYtHEnwxqVdZYOJxmD537q1SAmZzsSdaCn9pF +1j9TBgO3/R/shn104KS06DK2qgcj+O8kQZ5jMHj0VN2O8Fo4jhJ/eMdvAlYhM864 +uK1pVQIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd +BgNVHQ4EFgQUoYxFkwoSYwunV18ySn3hIee3PmYwHwYDVR0jBBgwFoAUoYxFkwoS +YwunV18ySn3hIee3PmYwDQYJKoZIhvcNAQELBQADggIBAIeuYW1IOCrGHNxKLoR4 +ScAjKkW4NU3RBfq5BTPEZL3brVQWKrA+DVoo2qYagHMMxEFvr7g0tnfUW44dC4tG +kES1s+5JGInBSzSzhzV0op5FZ+1FcWa2uaElc9fCrIj70h2na9rAWubYWWQ0l2Ug +MTMDT86tCZ6u6cI+GHW0MyUSuwXsULpxQOK93ohGBSGEi6MrHuswMIm/EfVcRPiR +i0tZRQswDcoMT29jvgT+we3gh/7IzVa/5dyOetTWKU6A26ubP45lByL3RM2WHy3H +9Qm2mHD/ONxQFRGEO3+p8NgkVMgXjCsTSdaZf0XRD46/aXI3Uwf05q79Wz55uQbN +uIF4tE2g0DW65K7/00m8Ne1jxrP846thWgW2C+T/qSq+31ROwktcaNqjMqLJTVcY +UzRZPGaZ1zwCeKdMcdC/2/HEPOcB5gTyRPZIJjAzybEBGesC8cwh+joCMBedyF+A +P90lrAKb4xfevcqSFNJSgVPm6vwwZzKpYvaTFxUHMV4PG2n19Km3fC2z7YREMkco +BzuGaUWpxzaWkHJ02BKmcyPRTrm2ejrEKaFQBhG52fQmbmIIEiAW8AFXF9QFNmeX +61H5/zMkDAUPVr/vPRxSjoreaQ9aH/DVAzFEs5LG6nWorrvHYAOImP/HBIRSkIbh +tJOpUC/o69I2rDBgp9ADE7UK +-----END CERTIFICATE----- +# "Symantec Class 1 Public Primary Certification Authority - G6" +# 9D 19 0B 2E 31 45 66 68 5B E8 A8 89 E2 7A A8 C7 +# D7 AE 1D 8A AD DB A3 C1 EC F9 D2 48 63 CD 34 B9 +-----BEGIN CERTIFICATE----- +MIID9jCCAt6gAwIBAgIQJDJ18h0v0gkz97RqytDzmDANBgkqhkiG9w0BAQsFADCB +lDELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8w +HQYDVQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRl +YyBDbGFzcyAxIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +IC0gRzYwHhcNMTExMDE4MDAwMDAwWhcNMzcxMjAxMjM1OTU5WjCBlDELMAkGA1UE +BhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZT +eW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAx +IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzYwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDHOddJZKmZgiJM6kXZBxbje/SD +6Jlz+muxNuCad6BAwoGNAcfMjL2Pffd543pMA03Z+/2HOCgs3ZqLVAjbZ/sbjP4o +ki++t7JIp4Gh2F6Iw8w5QEFa0dzl2hCfL9oBTf0uRnz5LicKaTfukaMbasxEvxvH +w9QRslBglwm9LiL1QYRmn81ApqkAgMEflZKf3vNI79sdd2H8f9/ulqRy0LY+/3gn +r8uSFWkI22MQ4uaXrG7crPaizh5HmbmJtxLmodTNWRFnw2+F2EJOKL5ZVVkElauP +N4C/DfD8HzpkMViBeNfiNfYgPym4jxZuPkjctUwH4fIa6n4KedaovetdhitNAgMB +AAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBQzQejIORIVk0jyljIuWvXalF9TYDANBgkqhkiG9w0BAQsFAAOCAQEAFeNzV7EX +tl9JaUSm9l56Z6zS3nVJq/4lVcc6yUQVEG6/MWvL2QeTfxyFYwDjMhLgzMv7OWyP +4lPiPEAz2aSMR+atWPuJr+PehilWNCxFuBL6RIluLRQlKCQBZdbqUqwFblYSCT3Q +dPTXvQbKqDqNVkL6jXI+dPEDct+HG14OelWWLDi3mIXNTTNEyZSPWjEwN0ujOhKz +5zbRIWhLLTjmU64cJVYIVgNnhJ3Gw84kYsdMNs+wBkS39V8C3dlU6S+QTnrIToNA +DJqXPDe/v+z28LSFdyjBC8hnghAXOKK3Buqbvzr46SMHv3TgmDgVVXjucgBcGaP0 +0jPg/73RVDkpDw== +-----END CERTIFICATE----- +# "Symantec Class 2 Public Primary Certification Authority - G6" +# CB 62 7D 18 B5 8A D5 6D DE 33 1A 30 45 6B C6 5C +# 60 1A 4E 9B 18 DE DC EA 08 E7 DA AA 07 81 5F F0 +-----BEGIN CERTIFICATE----- +MIID9jCCAt6gAwIBAgIQZIKe/DcedF38l/+XyLH/QTANBgkqhkiG9w0BAQsFADCB +lDELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8w +HQYDVQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRl +YyBDbGFzcyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +IC0gRzYwHhcNMTExMDE4MDAwMDAwWhcNMzcxMjAxMjM1OTU5WjCBlDELMAkGA1UE +BhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZT +eW1hbnRlYyBUcnVzdCBOZXR3b3JrMUUwQwYDVQQDEzxTeW1hbnRlYyBDbGFzcyAy +IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzYwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNzOkFyGOFyz9AYxe9GPo15gRn +V2WYKaRPyVyPDzTS+NqoE2KquB5QZ3iwFkygOakVeq7t0qLA8JA3KRgmXOgNPLZs +ST/B4NzZS7YUGQum05bh1gnjGSYc+R9lS/kaQxwAg9bQqkmi1NvmYji6UBRDbfkx ++FYW2TgCkc/rbN27OU6Z4TBnRfHU8I3D3/7yOAchfQBeVkSz5GC9kSucq1sEcg+y +KNlyqwUgQiWpWwNqIBDMMfAr2jUs0Pual07wgksr2F82owstr2MNHSV/oW5cYqGN +KD6h/Bwg+AEvulWaEbAZ0shQeWsOagXXqgQ2sqPy4V93p3ec5R7c6d9qwWVdAgMB +AAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBSHjCCVyJhK0daABkqQNETfHE2/sDANBgkqhkiG9w0BAQsFAAOCAQEAgY6ypWaW +tyGltu9vI1pf24HFQqV4wWn99DzX+VxrcHIa/FqXTQCAiIiCisNxDY7FiZss7Y0L +0nJU9X3UXENX6fOupQIR9nYrgVfdfdp0MP1UR/bgFm6mtApI5ud1Bw8pGTnOefS2 +bMVfmdUfS/rfbSw8DVSAcPCIC4DPxmiiuB1w2XaM/O6lyc+tHc+ZJVdaYkXLFmu9 +Sc2lo4xpeSWuuExsi0BmSxY/zwIa3eFsawdhanYVKZl/G92IgMG/tY9zxaaWI4Sm +KIYkM2oBLldzJbZev4/mHWGoQClnHYebHX+bn5nNMdZUvmK7OaxoEkiRIKXLsd3+ +b/xa5IJVWa8xqQ== +-----END CERTIFICATE----- +# "SZAFIR ROOT CA" +# FA BC F5 19 7C DD 7F 45 8A C3 38 32 D3 28 40 21 +# DB 24 25 FD 6B EA 7A 2E 69 B7 48 6E 8F 51 F9 CC +-----BEGIN CERTIFICATE----- +MIIDcTCCAlmgAwIBAgIVAOYJ/nrqAGiM4CS07SAbH+9StETRMA0GCSqGSIb3DQEB +BQUAMFAxCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGlj +emVuaW93YSBTLkEuMRcwFQYDVQQDDA5TWkFGSVIgUk9PVCBDQTAeFw0xMTEyMDYx +MTEwNTdaFw0zMTEyMDYxMTEwNTdaMFAxCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L +cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRcwFQYDVQQDDA5TWkFGSVIg +Uk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKxHL49ZMTml +6g3wpYwrvQKkvc0Kc6oJ5sxfgmp1qZfluwbv88BdocHSiXlY8NzrVYzuWBp7J/9K +ULMAoWoTIzOQ6C9TNm4YbA9A1jdX1wYNL5Akylf8W5L/I4BXhT9KnlI6x+a7BVAm +nr/Ttl+utT/Asms2fRfEsF2vZPMxH4UFqOAhFjxTkmJWf2Cu4nvRQJHcttB+cEAo +ag/hERt/+tzo4URz6x6r19toYmxx4FjjBkUhWQw1X21re//Hof2+0YgiwYT84zLb +eqDqCOMOXxvH480yGDkh/QoazWX3U75HQExT/iJlwnu7I1V6HXztKIwCBjsxffbH +3jOshCJtywcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFFOSo33/gnbwM9TrkmdHYTMbaDsqMA0GCSqGSIb3DQEBBQUA +A4IBAQA5UFWd5EL/pBviIMm1zD2JLUCpp0mJG7JkwznIOzawhGmFFaxGoxAhQBEg +haP+E0KR66oAwVC6xe32QUVSHfWqWndzbODzLB8yj7WAR0cDM45ZngSBPBuFE3Wu +GLJX9g100ETfIX+4YBR/4NR/uvTnpnd9ete7Whl0ZfY94yuu4xQqB5QFv+P7IXXV +lTOjkjuGXEcyQAjQzbFaT9vIABSbeCXWBbjvOXukJy6WgAiclzGNSYprre8Ryydd +fmjW9HIGwsIO03EldivvqEYL1Hv1w/Pur+6FUEOaL68PEIUovfgwIB2BAw+vZDuw +cH0mX548PojGyg434cDjkSXa3mHF +-----END CERTIFICATE----- +# "T-TeleSec GlobalRoot Class 2" +# 91 E2 F5 78 8D 58 10 EB A7 BA 58 73 7D E1 54 8A +# 8E CA CD 01 45 98 BC 0B 14 3E 04 1B 17 05 25 52 +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd +AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC +FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi +1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq +jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ +wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ +WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy +NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC +uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw +IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 +g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP +BSeOE6Fuwg== +-----END CERTIFICATE----- +# "T-TeleSec GlobalRoot Class 3" +# FD 73 DA D3 1C 64 4F F1 B4 3B EF 0C CD DA 96 71 +# 0B 9C D9 87 5E CA 7E 31 70 7A F3 E9 6D 52 2B BD +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN +8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ +RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 +hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 +ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM +EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 +A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy +WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ +1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 +6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT +91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p +TpPDpFQUWw== +-----END CERTIFICATE----- +# "TeliaSonera Root CA v1" +# DD 69 36 FE 21 F8 F0 77 C1 23 A1 A5 21 C1 22 24 +# F7 22 55 B7 3E 03 A7 26 06 93 E8 A2 4B 0F A3 89 +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw +NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv +b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD +VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F +VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 +7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X +Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ +/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs +81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm +dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe +Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu +sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 +pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs +slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ +arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD +VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG +9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl +dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj +TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed +Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 +Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI +OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 +vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW +t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn +HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx +SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= +-----END CERTIFICATE----- +# "thawte Primary Root CA" +# 8D 72 2F 81 A9 C1 13 C0 79 1D F1 36 A2 96 6D B2 +# 6C 95 0A 97 1D B4 6B 41 99 F4 EA 54 B7 8B FB 9F +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB +qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV +BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw +NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j +LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG +A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs +W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta +3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk +6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 +Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J +NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP +r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU +DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz +YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX +xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 +/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ +LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 +jVaMaA== +-----END CERTIFICATE----- +# "thawte Primary Root CA - G3" +# 4B 03 F4 58 07 AD 70 F2 1B FC 2C AE 71 C9 FD E4 +# 60 4C 06 4C F5 FF B6 86 BA E5 DB AA D7 FD D3 4C +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB +rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV +BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa +Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl +LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u +MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl +ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm +gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8 +YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf +b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9 +9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S +zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk +OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV +HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA +2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW +oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu +t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c +KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM +m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu +MdRAGmI0Nj81Aa6sY6A= +-----END CERTIFICATE----- +# "TRUST2408 OCES Primary CA" +# 92 D8 09 2E E7 7B C9 20 8F 08 97 DC 05 27 18 94 +# E6 3E F2 79 33 AE 53 7F B9 83 EE F0 EA E3 EE C8 +-----BEGIN CERTIFICATE----- +MIIGHDCCBASgAwIBAgIES45gAzANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJE +SzESMBAGA1UEChMJVFJVU1QyNDA4MSIwIAYDVQQDExlUUlVTVDI0MDggT0NFUyBQ +cmltYXJ5IENBMB4XDTEwMDMwMzEyNDEzNFoXDTM3MTIwMzEzMTEzNFowRTELMAkG +A1UEBhMCREsxEjAQBgNVBAoTCVRSVVNUMjQwODEiMCAGA1UEAxMZVFJVU1QyNDA4 +IE9DRVMgUHJpbWFyeSBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +AJlJodr3U1Fa+v8HnyACHV81/wLevLS0KUk58VIABl6Wfs3LLNoj5soVAZv4LBi5 +gs7E8CZ9w0F2CopW8vzM8i5HLKE4eedPdnaFqHiBZ0q5aaaQArW+qKJx1rT/AaXt +alMB63/yvJcYlXS2lpexk5H/zDBUXeEQyvfmK+slAySWT6wKxIPDwVapauFY9QaG ++VBhCa5jBstWS7A5gQfEvYqn6csZ3jW472kW6OFNz6ftBcTwufomGJBMkonf4ZLr +6t0AdRi9jflBPz3MNNRGxyjIuAmFqGocYFA/OODBRjvSHB2DygqQ8k+9tlpvzMRr +kU7jq3RKL+83G1dJ3/LTjCLz4ryEMIC/OJ/gNZfE0qXddpPtzflIPtUFVffXdbFV +1t6XZFhJ+wBHQCpJobq/BjqLWUA86upsDbfwnePtmIPRCemeXkY0qabC+2Qmd2Fe +xyZphwTyMnbqy6FG1tB65dYf3mOqStmLa3RcHn9+2dwNfUkh0tjO2FXD7drWcU0O +I9DW8oAypiPhm/QCjMU6j6t+0pzqJ/S0tdAo+BeiXK5hwk6aR+sRb608QfBbRAs3 +U/q8jSPByenggac2BtTN6cl+AA1Mfcgl8iXWNFVGegzd/VS9vINClJCe3FNVoUnR +YCKkj+x0fqxvBLopOkJkmuZw/yhgMxljUi2qYYGn90OzAgMBAAGjggESMIIBDjAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjARBgNVHSAECjAIMAYGBFUd +IAAwgZcGA1UdHwSBjzCBjDAsoCqgKIYmaHR0cDovL2NybC5vY2VzLnRydXN0MjQw +OC5jb20vb2Nlcy5jcmwwXKBaoFikVjBUMQswCQYDVQQGEwJESzESMBAGA1UEChMJ +VFJVU1QyNDA4MSIwIAYDVQQDExlUUlVTVDI0MDggT0NFUyBQcmltYXJ5IENBMQ0w +CwYDVQQDEwRDUkwxMB8GA1UdIwQYMBaAFPZt+LFIs0FDAduGROUYBbdezAY3MB0G +A1UdDgQWBBT2bfixSLNBQwHbhkTlGAW3XswGNzANBgkqhkiG9w0BAQsFAAOCAgEA +VPAQGrT7dIjD3/sIbQW86f9CBPu0c7JKN6oUoRUtKqgJ2KCdcB5ANhCoyznHpu3m +/dUfVUI5hc31CaPgZyY37hch1q4/c9INcELGZVE/FWfehkH+acpdNr7j8UoRZlkN +15b/0UUBfGeiiJG/ugo4llfoPrp8bUmXEGggK3wyqIPcJatPtHwlb6ympfC2b/Ld +v/0IdIOzIOm+A89Q0utx+1cOBq72OHy8gpGb6MfncVFMoL2fjP652Ypgtr8qN9Ka +/XOazktiIf+2Pzp7hLi92hRc9QMYexrV/nnFSQoWdU8TqULFUoZ3zTEC3F/g2yj+ +FhbrgXHGo5/A4O74X+lpbY2XV47aSuw+DzcPt/EhMj2of7SA55WSgbjPMbmNX0rb +oenSIte2HRFW5Tr2W+qqkc/StixgkKdyzGLoFx/xeTWdJkZKwyjqge2wJqws2upY +EiThhC497+/mTiSuXd69eVUwKyqYp9SD2rTtNmF6TCghRM/dNsJOl+osxDVGcwvt +WIVFF/Onlu5fu1NHXdqNEfzldKDUvCfii3L2iATTZyHwU9CALE+2eIA+PIaLgnM1 +1oCfUnYBkQurTrihvzz9PryCVkLxiqRmBVvUz+D4N5G/wvvKDS6t6cPCS+hqM482 +cbBsn0R9fFLO4El62S9eH1tqOzO20OAOK65yJIsOpSE= +-----END CERTIFICATE----- +# "TrustCor ECA-1" +# 5A 88 5D B1 9C 01 D9 12 C5 75 93 88 93 8C AF BB +# DF 03 1A B2 D4 8E 91 EE 15 58 9B 42 97 1D 03 9C +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD +VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk +MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFzAVBgNVBAMMDlRydXN0Q29y +IEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3MjgwN1owgZwxCzAJBgNV +BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw +IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy +dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3Ig +RUNBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb +3w9U73NjKYKtR8aja+3+XzP4Q1HpGjORMRegdMTUpwHmspI+ap3tDvl0mEDTPwOA +BoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23xFUfJ3zSCNV2HykVh0A5 +3ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmcp0yJF4Ou +owReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/ +wZ0+fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZF +ZtS6mFjBAgMBAAGjYzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAf +BgNVHSMEGDAWgBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/ +MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEABT41XBVwm8nHc2Fv +civUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u/ukZMjgDfxT2 +AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F +hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50 +soIipX1TH0XsJ5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BI +WJZpTdwHjFGTot+fDz2LYLSCjaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1Wi +tJ/X5g== +-----END CERTIFICATE----- +# "TrustCor RootCert CA-1" +# D4 0E 9C 86 CD 8F E4 68 C1 77 69 59 F4 9E A7 74 +# FA 54 86 84 B6 C4 06 F3 90 92 61 F4 DC E2 57 5C +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYD +VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk +MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29y +IFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkxMjMxMTcyMzE2WjCB +pDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFuYW1h +IENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUG +A1UECwweVHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZU +cnVzdENvciBSb290Q2VydCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAv463leLCJhJrMxnHQFgKq1mqjQCj/IDHUHuO1CAmujIS2CNUSSUQIpid +RtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4pQa81QBeCQryJ3pS/C3V +seq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0JEsq1pme +9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CV +EY4hgLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorW +hnAbJN7+KIor0Gqw/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/ +DeOxCbeKyKsZn3MzUOcwHwYDVR0jBBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD +ggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5mDo4Nvu7Zp5I +/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf +ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZ +yonnMlo2HD6CqFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djts +L1Ac59v2Z3kf9YKVmgenFK+P3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdN +zl/HHk484IkzlQsPpTLWPFp5LBk= +-----END CERTIFICATE----- +# "TrustCor RootCert CA-2" +# 07 53 E9 40 37 8C 1B D5 E3 83 6E 39 5D AE A5 CB +# 83 9E 50 46 F1 BD 0E AE 19 51 CF 10 FE C7 C9 65 +-----BEGIN CERTIFICATE----- +MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNV +BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw +IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy +dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEfMB0GA1UEAwwWVHJ1c3RDb3Ig +Um9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEyMzExNzI2MzlaMIGk +MQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEg +Q2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYD +VQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRy +dXN0Q29yIFJvb3RDZXJ0IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCnIG7CKqJiJJWQdsg4foDSq8GbZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+ +QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9NkRvRUqdw6VC0xK5mC8tkq +1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1oYxOdqHp +2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nK +DOObXUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hape +az6LMvYHL1cEksr1/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF +3wP+TfSvPd9cW436cOGlfifHhi5qjxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88 +oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQPeSghYA2FFn3XVDjxklb9tTNM +g9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+CtgrKAmrhQhJ8Z3 +mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh +8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAd +BgNVHQ4EFgQU2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6U +nrybPZx9mCAZ5YwwYrIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw +DQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/hOsh80QA9z+LqBrWyOrsGS2h60COX +dKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnpkpfbsEZC89NiqpX+ +MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv2wnL +/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RX +CI/hOWB3S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYa +ZH9bDTMJBzN7Bj8RpFxwPIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW +2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dvDDqPys/cA8GiCcjl/YBeyGBCARsaU1q7 +N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYURpFHmygk71dSTlxCnKr3 +Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANExdqtvArB +As8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp +5KeXRKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu +1uwJ +-----END CERTIFICATE----- +# "Trustis FPS Root CA" +# C1 B4 82 99 AB A5 20 8F E9 63 0A CE 55 CA 68 A0 +# 3E DA 5A 51 9C 88 02 A0 D3 A6 73 BE 8F 8E 55 7D +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL +ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx +MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc +MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+ +AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH +iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj +vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA +0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB +OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/ +BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E +FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01 +GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW +zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4 +1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE +f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F +jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN +ZetX2fNXlrtIzYE= +-----END CERTIFICATE----- +# "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" +# 46 ED C3 68 90 46 D5 3A 45 3F B3 10 4A B8 0D CA +# EC 65 8B 26 60 EA 16 29 DD 7E 86 79 90 64 87 16 +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx +GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp +bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w +KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 +BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy +dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG +EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll +IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU +QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT +TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg +LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 +a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr +LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr +N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X +YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ +iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f +AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH +V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh +AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf +IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 +lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c +8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf +lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= +-----END CERTIFICATE----- +# "TWCA Global Root CA" +# 59 76 90 07 F7 68 5D 0F CD 50 87 2F 9F 95 D5 75 +# 5A 5B 2B 45 7D 81 F3 69 2B 61 0A 98 67 2F 0E 1B +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx +EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT +VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 +NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT +B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF +10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz +0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh +MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH +zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc +46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 +yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi +laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP +oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA +BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE +qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm +4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL +1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF +H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo +RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ +nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh +15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW +6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW +nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j +wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz +aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy +KwbQBM0= +-----END CERTIFICATE----- +# "TWCA Root Certification Authority" +# BF D8 8F E1 10 1C 41 AE 3E 80 1B F8 BE 56 35 0E +# E9 BA D1 A6 B9 BD 51 5E DC 5C 6D 5B 87 11 AC 44 +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES +MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU +V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz +WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO +LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE +AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH +K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX +RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z +rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx +3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq +hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC +MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls +XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D +lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn +aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ +YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- +# "UCA Global Root" +# A1 F0 5C CB 80 C2 D7 10 EC 7D 47 9A BD CB B8 79 +# E5 8D 7E DB 71 49 FE 78 A8 78 84 E3 D0 BA D0 F9 +-----BEGIN CERTIFICATE----- +MIIFkjCCA3qgAwIBAgIBCDANBgkqhkiG9w0BAQUFADA6MQswCQYDVQQGEwJDTjER +MA8GA1UEChMIVW5pVHJ1c3QxGDAWBgNVBAMTD1VDQSBHbG9iYWwgUm9vdDAeFw0w +ODAxMDEwMDAwMDBaFw0zNzEyMzEwMDAwMDBaMDoxCzAJBgNVBAYTAkNOMREwDwYD +VQQKEwhVbmlUcnVzdDEYMBYGA1UEAxMPVUNBIEdsb2JhbCBSb290MIICIjANBgkq +hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2rPlBlA/9nP3xDK/RqUlYjOHsGj+p9+I +A2N9Apb964fJ7uIIu527u+RBj8cwiQ9tJMAEbBSUgU2gDXRm8/CFr/hkGd656YGT +0CiFmUdCSiw8OCdKzP/5bBnXtfPvm65bNAbXj6ITBpyKhELVs6OQaG2BkO5NhOxM +cE4t3iQ5zhkAQ5N4+QiGHUPR9HK8BcBn+sBR0smFBySuOR56zUHSNqth6iur8CBV +mTxtLRwuLnWW2HKX4AzKaXPudSsVCeCObbvaE/9GqOgADKwHLx25urnRoPeZnnRc +GQVmMc8+KlL+b5/zub35wYH1N9ouTIElXfbZlJrTNYsgKDdfUet9Ysepk9H50DTL +qScmLCiQkjtVY7cXDlRzq6987DqrcDOsIfsiJrOGrCOp139tywgg8q9A9f9ER3Hd +J90TKKHqdjn5EKCgTUCkJ7JZFStsLSS3JGN490MYeg9NEePorIdCjedYcaSrbqLA +l3y74xNLytu7awj5abQEctXDRrl36v+6++nwOgw19o8PrgaEFt2UVdTvyie3AzzF +HCYq9TyopZWbhvGKiWf4xwxmse1Bv4KmAGg6IjTuHuvlb4l0T2qqaqhXZ1LUIGHB +zlPL/SR/XybfoQhplqCe/klD4tPq2sTxiDEhbhzhzfN1DiBEFsx9c3Q1RSw7gdQg +7LYJjD5IskkCAwEAAaOBojCBnzALBgNVHQ8EBAMCAQYwDAYDVR0TBAUwAwEB/zBj +BgNVHSUEXDBaBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcD +BAYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEFBQcDBwYIKwYBBQUHAwgGCCsGAQUF +BwMJMB0GA1UdDgQWBBTZw9P4gJJnzF3SOqLXcaK0xDiALTANBgkqhkiG9w0BAQUF +AAOCAgEA0Ih5ygiq9ws0oE4Jwul+NUiJcIQjL1HDKy9e21NrW3UIKlS6Mg7VxnGF +sZdJgPaE0PC6t3GUyHlrpsVE6EKirSUtVy/m1jEp+hmJVCl+t35HNmktbjK81HXa +QnO4TuWDQHOyXd/URHOmYgvbqm4FjMh/Rk85hZCdvBtUKayl1/7lWFZXbSyZoUkh +1WHGjGHhdSTBAd0tGzbDLxLMC9Z4i3WA6UG5iLHKPKkWxk4V43I29tSgQYWvimVw +TbVEEFDs7d9t5tnGwBLxSzovc+k8qe4bqi81pZufTcU0hF8mFGmzI7GJchT46U1R +IgP/SobEHOh7eQrbRyWBfvw0hKxZuFhD5D1DCVR0wtD92e9uWfdyYJl2b/Unp7uD +pEqB7CmB9HdL4UISVdSGKhK28FWbAS7d9qjjGcPORy/AeGEYWsdl/J1GW1fcfA67 +loMQfFUYCQSu0feLKj6g5lDWMDbX54s4U+xJRODPpN/xU3uLWrb2EZBL1nXz/gLz +Ka/wI3J9FO2pXd96gZ6bkiL8HvgBRUGXx2sBYb4zaPKgZYRmvOAqpGjTcezHCN6j +w8k2SjTxF+KAryAhk5Qe5hXTVGLxtTgv48y5ZwSpuuXu+RBuyy5+E6+SFP7zJ3N7 +OPxzbbm5iPZujAv1/P8JDrMtXnt145Ik4ubhWD5LKAN1axibRww= +-----END CERTIFICATE----- +# "UCA Root" +# 93 E6 5E C7 62 F0 55 DC 71 8A 33 25 82 C4 1A 04 +# 43 0D 72 E3 CB 87 E8 B8 97 B6 75 16 F0 D1 AA 39 +-----BEGIN CERTIFICATE----- +MIIDhDCCAmygAwIBAgIBCTANBgkqhkiG9w0BAQUFADAzMQswCQYDVQQGEwJDTjER +MA8GA1UEChMIVW5pVHJ1c3QxETAPBgNVBAMTCFVDQSBSb290MB4XDTA0MDEwMTAw +MDAwMFoXDTI5MTIzMTAwMDAwMFowMzELMAkGA1UEBhMCQ04xETAPBgNVBAoTCFVu +aVRydXN0MREwDwYDVQQDEwhVQ0EgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBALNdB8qGJn1r4vs4CQ7MgsJqGgCiFV/W6dQBt1YDAVmP9ThpJHbC +XivF9iu/r/tB/Q9a/KvXg3BNMJjRnrJ2u5LWu+kQKGkoNkTo8SzXWHwk1n8COvCB +a2FgP/Qz3m3l6ihST/ypHWN8C7rqrsRoRuTej8GnsrZYWm0dLNmMOreIy4XU9+gD +Xv2yTVDo1h//rgI/i0+WITyb1yXJHT/7mLFZ5PCpO6+zzYUs4mBGzG+OoOvwNMXx +QhhgrhLtRnUc5dipllq+3lrWeGeWW5N3UPJuG96WUUqm1ktDdSFmjXfsAoR2XEQQ +th1hbOSjIH23jboPkXXHjd+8AmCoKai9PUMCAwEAAaOBojCBnzALBgNVHQ8EBAMC +AQYwDAYDVR0TBAUwAwEB/zBjBgNVHSUEXDBaBggrBgEFBQcDAQYIKwYBBQUHAwIG +CCsGAQUFBwMDBggrBgEFBQcDBAYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEFBQcD +BwYIKwYBBQUHAwgGCCsGAQUFBwMJMB0GA1UdDgQWBBTbHzXza0z/QjFkm827Wh4d +SBC37jANBgkqhkiG9w0BAQUFAAOCAQEAOGy3iPGt+lg3dNHocN6cJ1nL5BXXoMNg +14iABMUwTD3UGusGXllH5rxmy+AI/Og17GJ9ysDawXiv5UZv+4mCI4/211NmVaDe +JRI7cTYWVRJ2+z34VFsxugAG+H1V5ad2g6pcSpemKijfvcZsCyOVjjN/Hl5AHxNU +LJzltQ7dFyiuawHTUin1Ih+QOfTcYmjwPIZH7LgFRbu3DJaUxmfLI3HQjnQi1kHr +A6i26r7EARK1s11AdgYg1GS4KUYGis4fk5oQ7vuqWrTcL9Ury/bXBYSYBZELhPc9 ++tb5evosFeo2gkO3t7jj83EB7UNDogVFwygFBzXjAaU4HoDU18PZ3g== +-----END CERTIFICATE----- +# "USERTrust ECC Certification Authority" +# 4F F4 60 D5 4B 9C 86 DA BF BC FC 57 12 E0 40 0D +# 2B ED 3F BC 4D 4F BD AA 86 E0 6A DC D2 A9 AD 7A +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl +eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT +JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT +Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg +VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo +I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng +o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G +A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB +zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW +RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- +# "USERTrust RSA Certification Authority" +# E7 93 C9 B0 2F D8 AA 13 E2 1C 31 22 8A CC B0 81 +# 19 64 3B 74 9C 89 89 64 B1 74 6D 46 C3 D4 CB D2 +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw +MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV +BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B +3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY +tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ +Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 +VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT +79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 +c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT +Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l +c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee +UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE +Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF +Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO +VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 +ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs +8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR +iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze +Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ +XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ +qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB +VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB +L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG +jjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- +# "UTN - DATACorp SGC" +# 85 FB 2F 91 DD 12 27 5A 01 45 B6 36 53 4F 84 02 +# 4A D6 8B 69 B8 EE 88 68 4F F7 11 37 58 05 B3 48 +-----BEGIN CERTIFICATE----- +MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB +kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw +IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG +EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD +VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu +dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6 +E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ +D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK +4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq +lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW +bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB +o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT +MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js +LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr +BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB +AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft +Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj +j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH +KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv +2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3 +mfnGV/TJVTl4uix5yaaIK/QI +-----END CERTIFICATE----- +# "UTN-USERFirst-Client Authentication and Email" +# 43 F2 57 41 2D 44 0D 62 74 76 97 4F 87 7D A8 F1 +# FC 24 44 56 5A 36 7A E6 0E DD C2 7A 41 25 31 AE +-----BEGIN CERTIFICATE----- +MIIEojCCA4qgAwIBAgIQRL4Mi1AAJLQR0zYlJWfJiTANBgkqhkiG9w0BAQUFADCB +rjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0BgNVBAMTLVVUTi1VU0VSRmlyc3Qt +Q2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBFbWFpbDAeFw05OTA3MDkxNzI4NTBa +Fw0xOTA3MDkxNzM2NThaMIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAV +BgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5l +dHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UE +AxMtVVROLVVTRVJGaXJzdC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWls +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsjmFpPJ9q0E7YkY3rs3B +YHW8OWX5ShpHornMSMxqmNVNNRm5pELlzkniii8efNIxB8dOtINknS4p1aJkxIW9 +hVE1eaROaJB7HHqkkqgX8pgV8pPMyaQylbsMTzC9mKALi+VuG6JG+ni8om+rWV6l +L8/K2m2qL+usobNqqrcuZzWLeeEeaYji5kbNoKXqvgvOdjp6Dpvq/NonWz1zHyLm +SGHGTPNpsaguG7bUMSAsvIKKjqQOpdeJQ/wWWq8dcdcRWdq6hw2v+vPhwvCkxWeM +1tZUOt4KpLoDd7NlyP0e03RiqhjKaJMeoYV+9Udly/hNVyh00jT/MLbu9mIwFIws +6wIDAQABo4G5MIG2MAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBSJgmd9xJ0mcABLtFBIfN49rgRufTBYBgNVHR8EUTBPME2gS6BJhkdodHRw +Oi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1DbGllbnRBdXRoZW50 +aWNhdGlvbmFuZEVtYWlsLmNybDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH +AwQwDQYJKoZIhvcNAQEFBQADggEBALFtYV2mGn98q0rkMPxTbyUkxsrt4jFcKw7u +7mFVbwQ+zznexRtJlOTrIEy05p5QLnLZjfWqo7NK2lYcYJeA3IKirUq9iiv/Cwm0 +xtcgBEXkzYABurorbs6q15L+5K/r9CYdFip/bDCVNy8zEqx/3cfREYxRmLLQo5HQ +rfafnoOTHh1CuEava2bwm3/q4wMC5QJRwarVNZ1yQAOJujEdxRBoUp7fooXFXAim +eOZTT7Hot9MUnpOmw2TjrH5xzbyf6QMbzPvprDHBr3wVdAKZw7JHpsIyYdfHb0gk +USeh1YdV8nuPmD0Wnu51tvjQjvLzxq4oW6fw8zYX/MMF08oDSlQ= +-----END CERTIFICATE----- +# "UTN-USERFirst-Hardware" +# 6E A5 47 41 D0 04 66 7E ED 1B 48 16 63 4A A3 A7 +# 9E 6E 4B 96 95 0F 82 79 DA FC 8D 9B D8 81 21 37 +-----BEGIN CERTIFICATE----- +MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB +lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt +SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG +A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe +MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v +d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh +cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn +0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ +M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a +MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd +oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI +DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy +oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0 +dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy +bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF +BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM +//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli +CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE +CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t +3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS +KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA== +-----END CERTIFICATE----- +# "UTN-USERFirst-Object" +# 6F FF 78 E4 00 A7 0C 11 01 1C D8 59 77 C4 59 FB +# 5A F9 6A 3D F0 54 08 20 D0 F4 B8 60 78 75 E5 8F +-----BEGIN CERTIFICATE----- +MIIEZjCCA06gAwIBAgIQRL4Mi1AAJLQR0zYt4LNfGzANBgkqhkiG9w0BAQUFADCB +lTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHTAbBgNVBAMTFFVUTi1VU0VSRmlyc3Qt +T2JqZWN0MB4XDTk5MDcwOTE4MzEyMFoXDTE5MDcwOTE4NDAzNlowgZUxCzAJBgNV +BAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkxHjAc +BgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8GA1UECxMYaHR0cDovL3d3 +dy51c2VydHJ1c3QuY29tMR0wGwYDVQQDExRVVE4tVVNFUkZpcnN0LU9iamVjdDCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6qgT+jo2F4qjEAVZURnicP +HxzfOpuCaDDASmEd8S8O+r5596Uj71VRloTN2+O5bj4x2AogZ8f02b+U60cEPgLO +KqJdhwQJ9jCdGIqXsqoc/EHSoTbL+z2RuufZcDX65OeQw5ujm9M89RKZd7G3CeBo +5hy485RjiGpq/gt2yb70IuRnuasaXnfBhQfdDWy/7gbHd2pBnqcP1/vulBe3/IW+ +pKvEHDHd17bR5PDv3xaPslKT16HUiaEHLr/hARJCHhrh2JU022R5KP+6LhHC5ehb +kkj7RwvCbNqtMoNB86XlQXD9ZZBt+vpRxPm9lisZBCzTbafc8H9vg2XiaquHhnUC +AwEAAaOBrzCBrDALBgNVHQ8EBAMCAcYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU2u1kdBScFDyr3ZmpvVsoTYs8ydgwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDov +L2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmlyc3QtT2JqZWN0LmNybDApBgNV +HSUEIjAgBggrBgEFBQcDAwYIKwYBBQUHAwgGCisGAQQBgjcKAwQwDQYJKoZIhvcN +AQEFBQADggEBAAgfUrE3RHjb/c652pWWmKpVZIC1WkDdIaXFwfNfLEzIR1pp6ujw +NTX00CXzyKakh0q9G7FzCL3Uw8q2NbtZhncxzaeAFK4T7/yxSPlrJSUtUbYsbUXB +mMiKVl0+7kNOPmsnjtA6S4ULX9Ptaqd1y9Fahy85dRNacrACgZ++8A+EVCBibGnU +4U3GDZlDAQ0Slox4nb9QorFEqmrPF3rPbw/U+CRVX/A0FklmPlBGyWNxODFiuGK5 +81OtbLUrohKqGU8J2l7nk8aOFAj+8DCAGKCGhU3IfdeLA/5u1fedFqySLKAj5ZyR +Uh+U3xeUc8OzwcFxBSAAeL0TUh2oPs0AH8g= +-----END CERTIFICATE----- +# "VeriSign Class 1 Public Primary Certification Authority - G3" +# CB B5 AF 18 5E 94 2A 24 02 F9 EA CB C0 ED 5B B8 +# 76 EE A3 C1 22 36 23 D0 04 47 E4 F3 BA 55 4B 65 +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl +cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu +LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT +aWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD +VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ +bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu +IENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN2E1Lm0+afY8wR4 +nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/EbRrsC+MO +8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjV +ojYJrKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjb +PG7PoBMAGrgnoeS+Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP2 +6KbqxzcSXKMpHgLZ2x87tNcPVkeBFQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vr +n5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAq2aN17O6x5q25lXQBfGfMY1a +qtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/Ny9Sn2WCVhDr4 +wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3 +ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrs +pSCAaWihT37ha88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4 +E1Z5T21Q6huwtVexN2ZYI/PcD98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g== +-----END CERTIFICATE----- +# "VeriSign Class 2 Public Primary Certification Authority - G3" +# 92 A9 D9 83 3F E1 94 4D B3 66 E8 BF AE 7A 95 B6 +# 48 0C 2D 6C 6C 2A 1B E6 5D 42 36 B6 08 FC A1 BB +-----BEGIN CERTIFICATE----- +MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJ +BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVy +aVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24s +IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNp +Z24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJBgNV +BAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNp +Z24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIElu +Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24g +Q2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt +IEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArwoNwtUs22e5LeWU +J92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6tW8UvxDO +JxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUY +wZF7C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9o +koqQHgiBVrKtaaNS0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjN +qWm6o+sdDZykIKbBoMXRRkwXbdKsZj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/E +Srg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0JhU8wI1NQ0kdvekhktdmnLfe +xbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf0xwLRtxyID+u +7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU +sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RI +sH/7NiXaldDxJBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTP +cjnhsUPgKM+351psE2tJs//jGHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q +-----END CERTIFICATE----- +# "VeriSign Class 3 Public Primary Certification Authority - G3" +# EB 04 CF 5E B1 F3 9A FA 76 2F 2B B1 20 F2 96 CB +# A5 20 C1 B9 7D B1 58 95 65 B8 1C B9 A1 7B 72 44 +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl +cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu +LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT +aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD +VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ +bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu +IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b +N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t +KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu +kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm +CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ +Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu +imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te +2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe +DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC +/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p +F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt +TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== +-----END CERTIFICATE----- +# "VeriSign Class 3 Public Primary Certification Authority - G4" +# 69 DD D7 EA 90 BB 57 C9 3E 13 5D C8 5E A6 FC D5 +# 48 0B 60 32 39 BD C4 54 FC 75 8B 2A 26 CF 7F 79 +-----BEGIN CERTIFICATE----- +MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW +ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp +U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG +A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp +U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg +SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln +biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm +GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve +fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ +aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj +aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW +kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC +4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga +FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== +-----END CERTIFICATE----- +# "VeriSign Class 3 Public Primary Certification Authority - G5" +# 9A CF AB 7E 43 C8 D8 80 D0 6B 26 2A 94 DE EE E4 +# B4 65 99 89 C3 D0 CA F1 9B AF 64 05 E4 1A B7 DF +-----BEGIN CERTIFICATE----- +MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW +ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW +ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp +U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1 +nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex +t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz +SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG +BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+ +rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/ +NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E +BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH +BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy +aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv +MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE +p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y +5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK +WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ +4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N +hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq +-----END CERTIFICATE----- +# "VeriSign Universal Root Certification Authority" +# 23 99 56 11 27 A5 71 25 DE 8C EF EA 61 0D DF 2F +# A0 78 B5 C8 06 7F 4E 82 82 90 BF B8 60 E8 4B 3C +-----BEGIN CERTIFICATE----- +MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB +vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W +ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX +MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0 +IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y +IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh +bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF +9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH +H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H +LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN +/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT +rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw +WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs +exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud +DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4 +sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+ +seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz +4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+ +BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR +lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3 +7M2CYfE45k+XmCpajQ== +-----END CERTIFICATE----- +# "Visa eCommerce Root" +# 69 FA C9 BD 55 FB 0A C7 8D 53 BB EE 5C F1 D5 97 +# 98 9F D0 AA AB 20 A2 51 51 BD F1 73 3E E7 D1 22 +-----BEGIN CERTIFICATE----- +MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr +MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl +cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv +bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw +CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h +dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l +cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h +2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E +lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV +ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq +299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t +vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL +dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF +AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR +zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3 +LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd +7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw +++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt +398znM/jra6O1I7mT1GvFpLgXPYHDw== +-----END CERTIFICATE----- +# "Visa Information Delivery Root CA" +# C5 7A 3A CB E8 C0 6B A1 98 8A 83 48 5B F3 26 F2 +# 44 87 75 37 98 49 DE 01 CA 43 57 1A F3 57 E7 4B +-----BEGIN CERTIFICATE----- +MIID+TCCAuGgAwIBAgIQW1fXqEywr9nTb0ugMbTW4jANBgkqhkiG9w0BAQUFADB5 +MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl +cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xKjAoBgNVBAMTIVZpc2EgSW5m +b3JtYXRpb24gRGVsaXZlcnkgUm9vdCBDQTAeFw0wNTA2MjcxNzQyNDJaFw0yNTA2 +MjkxNzQyNDJaMHkxCzAJBgNVBAYTAlVTMQ0wCwYDVQQKEwRWSVNBMS8wLQYDVQQL +EyZWaXNhIEludGVybmF0aW9uYWwgU2VydmljZSBBc3NvY2lhdGlvbjEqMCgGA1UE +AxMhVmlzYSBJbmZvcm1hdGlvbiBEZWxpdmVyeSBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyREA4R/QkkfpLx0cYjga/EhIPZpchH0MZsRZ +FfP6C2ITtf/Wc+MtgD4yTK0yoiXvni3d+aCtEgK3GDvkdgYrgF76ROJFZwUQjQ9l +x42gRT05DbXvWFoy7dTglCZ9z/Tt2Cnktv9oxKgmkeHY/CyfpCBg1S8xth2JlGMR +0ug/GMO5zANuegZOv438p5Lt5So+du2Gl+RMFQqEPwqN5uJSqAe0VtmB4gWdQ8on +Bj2ZAM2R73QW7UW0Igt2vA4JaSiNtaAG/Y/58VXWHGgbq7rDtNK1R30X0kJV0rGA +ib3RSwB3LpG7bOjbIucV5mQgJoVjoA1e05w6g1x/KmNTmOGRVwIDAQABo30wezAP +BgNVHRMBAf8EBTADAQH/MDkGA1UdIAQyMDAwLgYFZ4EDAgEwJTAVBggrBgEFBQcC +ARYJMS4yLjMuNC41MAwGCCsGAQUFBwICMAAwDgYDVR0PAQH/BAQDAgEGMB0GA1Ud +DgQWBBRPitp2/2d3I5qmgH1924h1hfeBejANBgkqhkiG9w0BAQUFAAOCAQEACUW1 +QdUHdDJydgDPmYt+telnG/Su+DPaf1cregzlN43bJaJosMP7NwjoJY/H2He4XLWb +5rXEkl+xH1UyUwF7mtaUoxbGxEvt8hPZSTB4da2mzXgwKvXuHyzF5Qjy1hOB0/pS +WaF9ARpVKJJ7TOJQdGKBsF2Ty4fSCLqZLgfxbqwMsd9sysXI3rDXjIhekqvbgeLz +PqZr+pfgFhwCCLSMQWl5Ll3u7Qk9wR094DZ6jj6+JCVCRUS3HyabH4OlM0Vc2K+j +INsF/64Or7GNtRf9HYEJvrPxHINxl3JVwhYj4ASeaO4KwhVbwtw94Tc/XrGcexDo +c5lC3rAi4/UZqweYCw== +-----END CERTIFICATE----- +# "VRK Gov. Root CA" +# F0 08 73 3E C5 00 DC 49 87 63 CC 92 64 C6 FC EA +# 40 EC 22 00 0E 92 7D 05 3C E9 C9 0B FA 04 6C B2 +-----BEGIN CERTIFICATE----- +MIIEGjCCAwKgAwIBAgIDAYagMA0GCSqGSIb3DQEBBQUAMIGjMQswCQYDVQQGEwJG +STEQMA4GA1UECBMHRmlubGFuZDEhMB8GA1UEChMYVmFlc3RvcmVraXN0ZXJpa2Vz +a3VzIENBMSkwJwYDVQQLEyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBTZXJ2aWNl +czEZMBcGA1UECxMQVmFybWVubmVwYWx2ZWx1dDEZMBcGA1UEAxMQVlJLIEdvdi4g +Um9vdCBDQTAeFw0wMjEyMTgxMzUzMDBaFw0yMzEyMTgxMzUxMDhaMIGjMQswCQYD +VQQGEwJGSTEQMA4GA1UECBMHRmlubGFuZDEhMB8GA1UEChMYVmFlc3RvcmVraXN0 +ZXJpa2Vza3VzIENBMSkwJwYDVQQLEyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBT +ZXJ2aWNlczEZMBcGA1UECxMQVmFybWVubmVwYWx2ZWx1dDEZMBcGA1UEAxMQVlJL +IEdvdi4gUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALCF +FdrIAzfQo0Y3bBseljDCWoUSZyPyu5/nioFgJ/gTqTy894aqqvTzJSm0/nWuHoGG +igWyHWWyOOi0zCia+xc28ZPVec7Bg4shT8MNrUHfeJ1I4x9CRPw8bSEga60ihCRC +jxdNwlAfZM0tOSJWiP2yY51U2kJpwMhP1xjiPshphJQ9LIDGfM6911Mf64i5psu7 +hVfvV3ZdDIvTXhJBnyHAOfQmbQj6OLOhd7HuFtjQaNq0mKWgZUZKa41+qk1guPjI +DfxxPu45h4G02fhukO4/DmHXHSto5i7hQkQmeCxY8n0Wf2HASSQqiYe2XS8pGfim +545SnkFLWg6quMJmQlMCAwEAAaNVMFMwDwYDVR0TAQH/BAUwAwEB/zARBglghkgB +hvhCAQEEBAMCAAcwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBTb6eGb0tEkC/yr +46Bn6q6cS3f0sDANBgkqhkiG9w0BAQUFAAOCAQEArX1ID1QRnljurw2bEi8hpM2b +uoRH5sklVSPj3xhYKizbXvfNVPVRJHtiZ+GxH0mvNNDrsczZog1Sf0JLiGCXzyVy +t08pLWKfT6HAVVdWDsRol5EfnGTCKTIB6dTI2riBmCguGMcs/OubUpbf9MiQGS0j +8/G7cdqehSO9Gu8u5Hp5t8OdhkktY7ktdM9lDzJmid87Ie4pbzlj2RXBbvbfgD5Q +eBmK3QOjFKU3p7UsfLYRh+cF8ry23tT/l4EohP7+bEaFEEGfTXWMB9SZZ291im/k +UJL2mdUQuMSpe/cXjUu/15WfCdxEDx4yw8DP03kN5Mc7h/CQNIghYkmSBAQfvA== +-----END CERTIFICATE----- +# "XRamp Global Certification Authority" +# CE CD DC 90 50 99 D8 DA DF C5 B1 D2 09 B7 37 CB +# E2 C1 8C FB 2C 10 C0 FF 0B CF 0D 32 86 FC 1A A2 +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB +gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk +MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY +UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx +NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 +dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy +dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 +38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP +KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q +DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 +qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa +JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi +PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P +BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs +jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 +eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR +vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa +IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy +i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ +O+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- +` diff --git a/libgo/go/crypto/x509/root_darwin_ios_gen.go b/libgo/go/crypto/x509/root_darwin_ios_gen.go new file mode 100644 index 00000000000..7a42466e5f0 --- /dev/null +++ b/libgo/go/crypto/x509/root_darwin_ios_gen.go @@ -0,0 +1,179 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +// Generates root_darwin_ios.go. +// +// As of iOS 13, there is no API for querying the system trusted X.509 root +// certificates. +// +// Apple publishes the trusted root certificates for iOS and macOS on +// opensource.apple.com so we embed them into the x509 package. +// +// Note that this ignores distrusted and revoked certificates. +package main + +import ( + "archive/tar" + "bytes" + "compress/gzip" + "crypto/sha256" + "crypto/tls" + "crypto/x509" + "encoding/pem" + "flag" + "fmt" + "go/format" + "io" + "io/ioutil" + "log" + "net/http" + "path" + "sort" + "strings" + "time" +) + +func main() { + var output = flag.String("output", "root_darwin_ios.go", "file name to write") + var version = flag.String("version", "", "security_certificates version") + flag.Parse() + if *version == "" { + log.Fatal("Select the latest security_certificates version from " + + "https://opensource.apple.com/source/security_certificates/") + } + + url := "https://opensource.apple.com/tarballs/security_certificates/security_certificates-%s.tar.gz" + hc := &http.Client{Timeout: 1 * time.Minute} + resp, err := hc.Get(fmt.Sprintf(url, *version)) + if err != nil { + log.Fatal(err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + log.Fatalf("HTTP status not OK: %s", resp.Status) + } + + zr, err := gzip.NewReader(resp.Body) + if err != nil { + log.Fatal(err) + } + defer zr.Close() + + var certs []*x509.Certificate + pool := x509.NewCertPool() + + tr := tar.NewReader(zr) + for { + hdr, err := tr.Next() + if err == io.EOF { + break + } + if err != nil { + log.Fatal(err) + } + + rootsDirectory := fmt.Sprintf("security_certificates-%s/certificates/roots/", *version) + if dir, file := path.Split(hdr.Name); hdr.Typeflag != tar.TypeReg || + dir != rootsDirectory || strings.HasPrefix(file, ".") { + continue + } + + der, err := ioutil.ReadAll(tr) + if err != nil { + log.Fatal(err) + } + + c, err := x509.ParseCertificate(der) + if err != nil { + log.Printf("Failed to parse certificate %q: %v", hdr.Name, err) + continue + } + + certs = append(certs, c) + pool.AddCert(c) + } + + // Quick smoke test to check the pool is well formed, and that we didn't end + // up trusting roots in the removed folder. + for _, c := range certs { + if c.Subject.CommonName == "Symantec Class 2 Public Primary Certification Authority - G4" { + log.Fatal("The pool includes a removed root!") + } + } + conn, err := tls.Dial("tcp", "mail.google.com:443", &tls.Config{ + RootCAs: pool, + }) + if err != nil { + log.Fatal(err) + } + conn.Close() + + certName := func(c *x509.Certificate) string { + if c.Subject.CommonName != "" { + return c.Subject.CommonName + } + if len(c.Subject.OrganizationalUnit) > 0 { + return c.Subject.OrganizationalUnit[0] + } + return c.Subject.Organization[0] + } + sort.Slice(certs, func(i, j int) bool { + if strings.ToLower(certName(certs[i])) != strings.ToLower(certName(certs[j])) { + return strings.ToLower(certName(certs[i])) < strings.ToLower(certName(certs[j])) + } + return certs[i].NotBefore.Before(certs[j].NotBefore) + }) + + out := new(bytes.Buffer) + fmt.Fprintf(out, header, *version) + fmt.Fprintf(out, "const systemRootsPEM = `\n") + + for _, c := range certs { + fmt.Fprintf(out, "# %q\n", certName(c)) + h := sha256.Sum256(c.Raw) + fmt.Fprintf(out, "# % X\n", h[:len(h)/2]) + fmt.Fprintf(out, "# % X\n", h[len(h)/2:]) + b := &pem.Block{ + Type: "CERTIFICATE", + Bytes: c.Raw, + } + if err := pem.Encode(out, b); err != nil { + log.Fatal(err) + } + } + + fmt.Fprintf(out, "`") + + source, err := format.Source(out.Bytes()) + if err != nil { + log.Fatal(err) + } + if err := ioutil.WriteFile(*output, source, 0644); err != nil { + log.Fatal(err) + } +} + +const header = `// Code generated by root_darwin_ios_gen.go -version %s; DO NOT EDIT. +// Update the version in root.go and regenerate with "go generate". + +// +build darwin,arm64 darwin,amd64,ios +// +build !x509omitbundledroots + +package x509 + +func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) { + return nil, nil +} + +// loadSystemRootsWithCgo is not available on iOS. +var loadSystemRootsWithCgo func() (*CertPool, error) + +func loadSystemRoots() (*CertPool, error) { + p := NewCertPool() + p.AppendCertsFromPEM([]byte(systemRootsPEM)) + return p, nil +} +` diff --git a/libgo/go/crypto/x509/root_nocgo_darwin.go b/libgo/go/crypto/x509/root_nocgo_darwin.go deleted file mode 100644 index 2ac4666aff6..00000000000 --- a/libgo/go/crypto/x509/root_nocgo_darwin.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !cgo - -package x509 - -func loadSystemRoots() (*CertPool, error) { - return execSecurityRoots() -} diff --git a/libgo/go/crypto/x509/root_omit.go b/libgo/go/crypto/x509/root_omit.go new file mode 100644 index 00000000000..175d71643b2 --- /dev/null +++ b/libgo/go/crypto/x509/root_omit.go @@ -0,0 +1,29 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin,arm64 darwin,amd64,ios +// +build x509omitbundledroots + +// This file provides the loadSystemRoots func when the +// "x509omitbundledroots" build tag has disabled bundling a copy, +// which currently on happens on darwin/arm64 (root_darwin_arm64.go). +// This then saves 256 KiB of binary size and another 560 KiB of +// runtime memory size retaining the parsed roots forever. Constrained +// environments can construct minimal x509 root CertPools on the fly +// in the crypto/tls.Config.VerifyPeerCertificate hook. + +package x509 + +import "errors" + +func loadSystemRoots() (*CertPool, error) { + return nil, errors.New("x509: system root bundling disabled") +} + +func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) { + return nil, nil +} + +// loadSystemRootsWithCgo is not available on iOS. +var loadSystemRootsWithCgo func() (*CertPool, error) diff --git a/libgo/go/crypto/x509/root_omit_test.go b/libgo/go/crypto/x509/root_omit_test.go new file mode 100644 index 00000000000..5ab6c931deb --- /dev/null +++ b/libgo/go/crypto/x509/root_omit_test.go @@ -0,0 +1,23 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin,arm64 darwin,amd64,ios +// +build x509omitbundledroots + +package x509 + +import ( + "strings" + "testing" +) + +func TestOmitBundledRoots(t *testing.T) { + cp, err := loadSystemRoots() + if err == nil { + t.Fatalf("loadSystemRoots = (pool %p, error %v); want non-nil error", cp, err) + } + if !strings.Contains(err.Error(), "root bundling disabled") { + t.Errorf("unexpected error doesn't mention bundling: %v", err) + } +} diff --git a/libgo/go/crypto/x509/root_unix.go b/libgo/go/crypto/x509/root_unix.go index a557ad671c3..5fefe550fb2 100644 --- a/libgo/go/crypto/x509/root_unix.go +++ b/libgo/go/crypto/x509/root_unix.go @@ -9,6 +9,8 @@ package x509 import ( "io/ioutil" "os" + "path/filepath" + "strings" ) // Possible directories with certificate files; stop after successfully @@ -29,6 +31,8 @@ const ( // certDirEnv is the environment variable which identifies which directory // to check for SSL certificate files. If set this overrides the system default. + // It is a colon separated list of directories. + // See https://www.openssl.org/docs/man1.0.2/man1/c_rehash.html. certDirEnv = "SSL_CERT_DIR" ) @@ -58,27 +62,27 @@ func loadSystemRoots() (*CertPool, error) { dirs := certDirectories if d := os.Getenv(certDirEnv); d != "" { - dirs = []string{d} + // OpenSSL and BoringSSL both use ":" as the SSL_CERT_DIR separator. + // See: + // * https://golang.org/issue/35325 + // * https://www.openssl.org/docs/man1.0.2/man1/c_rehash.html + dirs = strings.Split(d, ":") } for _, directory := range dirs { - fis, err := ioutil.ReadDir(directory) + fis, err := readUniqueDirectoryEntries(directory) if err != nil { if firstErr == nil && !os.IsNotExist(err) { firstErr = err } continue } - rootsAdded := false for _, fi := range fis { data, err := ioutil.ReadFile(directory + "/" + fi.Name()) - if err == nil && roots.AppendCertsFromPEM(data) { - rootsAdded = true + if err == nil { + roots.AppendCertsFromPEM(data) } } - if rootsAdded { - return roots, nil - } } if len(roots.certs) > 0 || firstErr == nil { @@ -87,3 +91,29 @@ func loadSystemRoots() (*CertPool, error) { return nil, firstErr } + +// readUniqueDirectoryEntries is like ioutil.ReadDir but omits +// symlinks that point within the directory. +func readUniqueDirectoryEntries(dir string) ([]os.FileInfo, error) { + fis, err := ioutil.ReadDir(dir) + if err != nil { + return nil, err + } + uniq := fis[:0] + for _, fi := range fis { + if !isSameDirSymlink(fi, dir) { + uniq = append(uniq, fi) + } + } + return uniq, nil +} + +// isSameDirSymlink reports whether fi in dir is a symlink with a +// target not containing a slash. +func isSameDirSymlink(fi os.FileInfo, dir string) bool { + if fi.Mode()&os.ModeSymlink == 0 { + return false + } + target, err := os.Readlink(filepath.Join(dir, fi.Name())) + return err == nil && !strings.Contains(target, "/") +} diff --git a/libgo/go/crypto/x509/root_unix_test.go b/libgo/go/crypto/x509/root_unix_test.go index 9e220192b9f..5a8015429c0 100644 --- a/libgo/go/crypto/x509/root_unix_test.go +++ b/libgo/go/crypto/x509/root_unix_test.go @@ -7,8 +7,13 @@ package x509 import ( + "bytes" "fmt" + "io/ioutil" "os" + "path/filepath" + "reflect" + "strings" "testing" ) @@ -121,3 +126,107 @@ func TestEnvVars(t *testing.T) { }) } } + +// Ensure that "SSL_CERT_DIR" when used as the environment +// variable delimited by colons, allows loadSystemRoots to +// load all the roots from the respective directories. +// See https://golang.org/issue/35325. +func TestLoadSystemCertsLoadColonSeparatedDirs(t *testing.T) { + origFile, origDir := os.Getenv(certFileEnv), os.Getenv(certDirEnv) + origCertFiles := certFiles[:] + + // To prevent any other certs from being loaded in + // through "SSL_CERT_FILE" or from known "certFiles", + // clear them all, and they'll be reverting on defer. + certFiles = certFiles[:0] + os.Setenv(certFileEnv, "") + + defer func() { + certFiles = origCertFiles[:] + os.Setenv(certDirEnv, origDir) + os.Setenv(certFileEnv, origFile) + }() + + tmpDir, err := ioutil.TempDir(os.TempDir(), "x509-issue35325") + if err != nil { + t.Fatalf("Failed to create temporary directory: %v", err) + } + defer os.RemoveAll(tmpDir) + + rootPEMs := []string{ + geoTrustRoot, + googleLeaf, + startComRoot, + } + + var certDirs []string + for i, certPEM := range rootPEMs { + certDir := filepath.Join(tmpDir, fmt.Sprintf("cert-%d", i)) + if err := os.MkdirAll(certDir, 0755); err != nil { + t.Fatalf("Failed to create certificate dir: %v", err) + } + certOutFile := filepath.Join(certDir, "cert.crt") + if err := ioutil.WriteFile(certOutFile, []byte(certPEM), 0655); err != nil { + t.Fatalf("Failed to write certificate to file: %v", err) + } + certDirs = append(certDirs, certDir) + } + + // Sanity check: the number of certDirs should be equal to the number of roots. + if g, w := len(certDirs), len(rootPEMs); g != w { + t.Fatalf("Failed sanity check: len(certsDir)=%d is not equal to len(rootsPEMS)=%d", g, w) + } + + // Now finally concatenate them with a colon. + colonConcatCertDirs := strings.Join(certDirs, ":") + os.Setenv(certDirEnv, colonConcatCertDirs) + gotPool, err := loadSystemRoots() + if err != nil { + t.Fatalf("Failed to load system roots: %v", err) + } + subjects := gotPool.Subjects() + // We expect exactly len(rootPEMs) subjects back. + if g, w := len(subjects), len(rootPEMs); g != w { + t.Fatalf("Invalid number of subjects: got %d want %d", g, w) + } + + wantPool := NewCertPool() + for _, certPEM := range rootPEMs { + wantPool.AppendCertsFromPEM([]byte(certPEM)) + } + strCertPool := func(p *CertPool) string { + return string(bytes.Join(p.Subjects(), []byte("\n"))) + } + if !reflect.DeepEqual(gotPool, wantPool) { + g, w := strCertPool(gotPool), strCertPool(wantPool) + t.Fatalf("Mismatched certPools\nGot:\n%s\n\nWant:\n%s", g, w) + } +} + +func TestReadUniqueDirectoryEntries(t *testing.T) { + tmp := t.TempDir() + temp := func(base string) string { return filepath.Join(tmp, base) } + if f, err := os.Create(temp("file")); err != nil { + t.Fatal(err) + } else { + f.Close() + } + if err := os.Symlink("target-in", temp("link-in")); err != nil { + t.Fatal(err) + } + if err := os.Symlink("../target-out", temp("link-out")); err != nil { + t.Fatal(err) + } + got, err := readUniqueDirectoryEntries(tmp) + if err != nil { + t.Fatal(err) + } + gotNames := []string{} + for _, fi := range got { + gotNames = append(gotNames, fi.Name()) + } + wantNames := []string{"file", "link-out"} + if !reflect.DeepEqual(gotNames, wantNames) { + t.Errorf("got %q; want %q", gotNames, wantNames) + } +} diff --git a/libgo/go/crypto/x509/sec1.go b/libgo/go/crypto/x509/sec1.go index 0bfb90cd546..52c108ff1d6 100644 --- a/libgo/go/crypto/x509/sec1.go +++ b/libgo/go/crypto/x509/sec1.go @@ -52,13 +52,10 @@ func MarshalECPrivateKey(key *ecdsa.PrivateKey) ([]byte, error) { // marshalECPrivateKey marshals an EC private key into ASN.1, DER format and // sets the curve ID to the given OID, or omits it if OID is nil. func marshalECPrivateKeyWithOID(key *ecdsa.PrivateKey, oid asn1.ObjectIdentifier) ([]byte, error) { - privateKeyBytes := key.D.Bytes() - paddedPrivateKey := make([]byte, (key.Curve.Params().N.BitLen()+7)/8) - copy(paddedPrivateKey[len(paddedPrivateKey)-len(privateKeyBytes):], privateKeyBytes) - + privateKey := make([]byte, (key.Curve.Params().N.BitLen()+7)/8) return asn1.Marshal(ecPrivateKey{ Version: 1, - PrivateKey: paddedPrivateKey, + PrivateKey: key.D.FillBytes(privateKey), NamedCurveOID: oid, PublicKey: asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)}, }) diff --git a/libgo/go/crypto/x509/verify.go b/libgo/go/crypto/x509/verify.go index c80b5ac825d..cb8d8f872dd 100644 --- a/libgo/go/crypto/x509/verify.go +++ b/libgo/go/crypto/x509/verify.go @@ -19,7 +19,7 @@ import ( ) // ignoreCN disables interpreting Common Name as a hostname. See issue 24151. -var ignoreCN = strings.Contains(os.Getenv("GODEBUG"), "x509ignoreCN=1") +var ignoreCN = !strings.Contains(os.Getenv("GODEBUG"), "x509ignoreCN=0") type InvalidReason int @@ -48,9 +48,9 @@ const ( // contains name constraints, and the Common Name can be interpreted as // a hostname. // - // You can avoid this error by setting the experimental GODEBUG environment - // variable to "x509ignoreCN=1", disabling Common Name matching entirely. - // This behavior might become the default in the future. + // This error is only returned when legacy Common Name matching is enabled + // by setting the GODEBUG environment variable to "x509ignoreCN=1". This + // setting might be removed in the future. NameConstraintsWithoutSANs // UnconstrainedName results when a CA certificate contains permitted // name constraints, but leaf certificate contains a name of an @@ -109,10 +109,16 @@ type HostnameError struct { func (h HostnameError) Error() string { c := h.Certificate - if !c.hasSANExtension() && !validHostname(c.Subject.CommonName) && - matchHostnames(toLowerCaseASCII(c.Subject.CommonName), toLowerCaseASCII(h.Host)) { - // This would have validated, if it weren't for the validHostname check on Common Name. - return "x509: Common Name is not a valid hostname: " + c.Subject.CommonName + if !c.hasSANExtension() && matchHostnames(c.Subject.CommonName, h.Host) { + if !ignoreCN && !validHostnamePattern(c.Subject.CommonName) { + // This would have validated, if it weren't for the validHostname check on Common Name. + return "x509: Common Name is not a valid hostname: " + c.Subject.CommonName + } + if ignoreCN && validHostnamePattern(c.Subject.CommonName) { + // This would have validated if x509ignoreCN=0 were set. + return "x509: certificate relies on legacy Common Name field, " + + "use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0" + } } var valid string @@ -185,8 +191,7 @@ func (se SystemRootsError) Error() string { // verified. Platform-specific verification needs the ASN.1 contents. var errNotParsed = errors.New("x509: missing ASN.1 contents; use ParseCertificate") -// VerifyOptions contains parameters for Certificate.Verify. It's a structure -// because other PKIX verification APIs have ended up needing many options. +// VerifyOptions contains parameters for Certificate.Verify. type VerifyOptions struct { // DNSName, if set, is checked against the leaf certificate with // Certificate.VerifyHostname or the platform verifier. @@ -736,6 +741,12 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V // the name being validated. Note that DirectoryName constraints are not // supported. // +// Name constraint validation follows the rules from RFC 5280, with the +// addition that DNS name constraints may use the leading period format +// defined for emails and URIs. When a constraint has a leading period +// it indicates that at least one additional label must be prepended to +// the constrained name to be considered valid. +// // Extended Key Usage values are enforced nested down a chain, so an intermediate // or root that enumerates EKUs prevents a leaf from asserting an EKU not in that // list. (While this is not specified, it is common practice in order to limit @@ -895,12 +906,16 @@ func (c *Certificate) buildChains(cache map[*Certificate][][]*Certificate, curre return } +func validHostnamePattern(host string) bool { return validHostname(host, true) } +func validHostnameInput(host string) bool { return validHostname(host, false) } + // validHostname reports whether host is a valid hostname that can be matched or // matched against according to RFC 6125 2.2, with some leniency to accommodate // legacy values. -func validHostname(host string) bool { - host = strings.TrimSuffix(host, ".") - +func validHostname(host string, isPattern bool) bool { + if !isPattern { + host = strings.TrimSuffix(host, ".") + } if len(host) == 0 { return false } @@ -910,7 +925,7 @@ func validHostname(host string) bool { // Empty label. return false } - if i == 0 && part == "*" { + if isPattern && i == 0 && part == "*" { // Only allow full left-most wildcards, as those are the only ones // we match, and matching literal '*' characters is probably never // the expected behavior. @@ -929,8 +944,8 @@ func validHostname(host string) bool { if c == '-' && j != 0 { continue } - if c == '_' || c == ':' { - // Not valid characters in hostnames, but commonly + if c == '_' { + // Not a valid character in hostnames, but commonly // found in deployments outside the WebPKI. continue } @@ -943,19 +958,26 @@ func validHostname(host string) bool { // commonNameAsHostname reports whether the Common Name field should be // considered the hostname that the certificate is valid for. This is a legacy -// behavior, disabled if the Subject Alt Name extension is present. +// behavior, disabled by default or if the Subject Alt Name extension is present. // // It applies the strict validHostname check to the Common Name field, so that // certificates without SANs can still be validated against CAs with name // constraints if there is no risk the CN would be matched as a hostname. // See NameConstraintsWithoutSANs and issue 24151. func (c *Certificate) commonNameAsHostname() bool { - return !ignoreCN && !c.hasSANExtension() && validHostname(c.Subject.CommonName) + return !ignoreCN && !c.hasSANExtension() && validHostnamePattern(c.Subject.CommonName) +} + +func matchExactly(hostA, hostB string) bool { + if hostA == "" || hostA == "." || hostB == "" || hostB == "." { + return false + } + return toLowerCaseASCII(hostA) == toLowerCaseASCII(hostB) } func matchHostnames(pattern, host string) bool { - host = strings.TrimSuffix(host, ".") - pattern = strings.TrimSuffix(pattern, ".") + pattern = toLowerCaseASCII(pattern) + host = toLowerCaseASCII(strings.TrimSuffix(host, ".")) if len(pattern) == 0 || len(host) == 0 { return false @@ -1014,6 +1036,16 @@ func toLowerCaseASCII(in string) string { // VerifyHostname returns nil if c is a valid certificate for the named host. // Otherwise it returns an error describing the mismatch. +// +// IP addresses can be optionally enclosed in square brackets and are checked +// against the IPAddresses field. Other names are checked case insensitively +// against the DNSNames field. If the names are valid hostnames, the certificate +// fields can have a wildcard as the left-most label. +// +// The legacy Common Name field is ignored unless it's a valid hostname, the +// certificate doesn't have any Subject Alternative Names, and the GODEBUG +// environment variable is set to "x509ignoreCN=0". Support for Common Name is +// deprecated will be entirely removed in the future. func (c *Certificate) VerifyHostname(h string) error { // IP addresses may be written in [ ]. candidateIP := h @@ -1031,15 +1063,26 @@ func (c *Certificate) VerifyHostname(h string) error { return HostnameError{c, candidateIP} } - lowered := toLowerCaseASCII(h) - + names := c.DNSNames if c.commonNameAsHostname() { - if matchHostnames(toLowerCaseASCII(c.Subject.CommonName), lowered) { - return nil - } - } else { - for _, match := range c.DNSNames { - if matchHostnames(toLowerCaseASCII(match), lowered) { + names = []string{c.Subject.CommonName} + } + + candidateName := toLowerCaseASCII(h) // Save allocations inside the loop. + validCandidateName := validHostnameInput(candidateName) + + for _, match := range names { + // Ideally, we'd only match valid hostnames according to RFC 6125 like + // browsers (more or less) do, but in practice Go is used in a wider + // array of contexts and can't even assume DNS resolution. Instead, + // always allow perfect matches, and only apply wildcard and trailing + // dot processing to valid hostnames. + if validCandidateName && validHostnamePattern(match) { + if matchHostnames(match, candidateName) { + return nil + } + } else { + if matchExactly(match, candidateName) { return nil } } diff --git a/libgo/go/crypto/x509/verify_test.go b/libgo/go/crypto/x509/verify_test.go index bbb68db8578..76d1ab9a474 100644 --- a/libgo/go/crypto/x509/verify_test.go +++ b/libgo/go/crypto/x509/verify_test.go @@ -403,7 +403,7 @@ var verifyTests = []verifyTest{ systemSkip: true, // does not chain to a system root ignoreCN: true, - errorCallback: expectHostnameError("Common Name is not a valid hostname"), + errorCallback: expectHostnameError("certificate is not valid for any names"), }, { name: "ValidCN/ignoreCN", @@ -414,7 +414,7 @@ var verifyTests = []verifyTest{ systemSkip: true, // does not chain to a system root ignoreCN: true, - errorCallback: expectHostnameError("not valid for any names"), + errorCallback: expectHostnameError("certificate relies on legacy Common Name field"), }, { // A certificate with an AKID should still chain to a parent without SKID. @@ -1807,26 +1807,31 @@ CCqGSM49BAMCA0gAMEUCIQClA3d4tdrDu9Eb5ZBpgyC+fU1xTZB0dKQHz6M5fPZA func TestValidHostname(t *testing.T) { tests := []struct { - host string - want bool + host string + validInput, validPattern bool }{ - {"example.com", true}, - {"eXample123-.com", true}, - {"-eXample123-.com", false}, - {"", false}, - {".", false}, - {"example..com", false}, - {".example.com", false}, - {"*.example.com", true}, - {"*foo.example.com", false}, - {"foo.*.example.com", false}, - {"exa_mple.com", true}, - {"foo,bar", false}, - {"project-dev:us-central1:main", true}, + {host: "example.com", validInput: true, validPattern: true}, + {host: "eXample123-.com", validInput: true, validPattern: true}, + {host: "-eXample123-.com"}, + {host: ""}, + {host: "."}, + {host: "example..com"}, + {host: ".example.com"}, + {host: "example.com.", validInput: true}, + {host: "*.example.com."}, + {host: "*.example.com", validPattern: true}, + {host: "*foo.example.com"}, + {host: "foo.*.example.com"}, + {host: "exa_mple.com", validInput: true, validPattern: true}, + {host: "foo,bar"}, + {host: "project-dev:us-central1:main"}, } for _, tt := range tests { - if got := validHostname(tt.host); got != tt.want { - t.Errorf("validHostname(%q) = %v, want %v", tt.host, got, tt.want) + if got := validHostnamePattern(tt.host); got != tt.validPattern { + t.Errorf("validHostnamePattern(%q) = %v, want %v", tt.host, got, tt.validPattern) + } + if got := validHostnameInput(tt.host); got != tt.validInput { + t.Errorf("validHostnameInput(%q) = %v, want %v", tt.host, got, tt.validInput) } } } diff --git a/libgo/go/crypto/x509/x509.go b/libgo/go/crypto/x509/x509.go index 013f1c996d9..8ce57fb1ec3 100644 --- a/libgo/go/crypto/x509/x509.go +++ b/libgo/go/crypto/x509/x509.go @@ -3,10 +3,6 @@ // license that can be found in the LICENSE file. // Package x509 parses X.509-encoded keys and certificates. -// -// On UNIX systems the environment variables SSL_CERT_FILE and SSL_CERT_DIR -// can be used to override the system default locations for the SSL certificate -// file and SSL certificate files directory, respectively. package x509 import ( @@ -17,6 +13,7 @@ import ( "crypto/ed25519" "crypto/elliptic" "crypto/rsa" + "crypto/sha1" _ "crypto/sha1" _ "crypto/sha256" _ "crypto/sha512" @@ -46,6 +43,8 @@ type pkixPublicKey struct { } // ParsePKIXPublicKey parses a public key in PKIX, ASN.1 DER form. +// The encoded public key is a SubjectPublicKeyInfo structure +// (see RFC 5280, Section 4.1). // // It returns a *rsa.PublicKey, *dsa.PublicKey, *ecdsa.PublicKey, or // ed25519.PublicKey. More types might be supported in the future. @@ -106,6 +105,8 @@ func marshalPublicKey(pub interface{}) (publicKeyBytes []byte, publicKeyAlgorith } // MarshalPKIXPublicKey converts a public key to PKIX, ASN.1 DER form. +// The encoded public key is a SubjectPublicKeyInfo structure +// (see RFC 5280, Section 4.1). // // The following key types are currently supported: *rsa.PublicKey, *ecdsa.PublicKey // and ed25519.PublicKey. Unsupported key types result in an error. @@ -163,8 +164,6 @@ type dsaSignature struct { R, S *big.Int } -type ecdsaSignature dsaSignature - type validity struct { NotBefore, NotAfter time.Time } @@ -905,16 +904,7 @@ func checkSignature(algo SignatureAlgorithm, signed, signature []byte, publicKey if pubKeyAlgo != ECDSA { return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub) } - ecdsaSig := new(ecdsaSignature) - if rest, err := asn1.Unmarshal(signature, ecdsaSig); err != nil { - return err - } else if len(rest) != 0 { - return errors.New("x509: trailing data after ECDSA signature") - } - if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { - return errors.New("x509: ECDSA signature contained zero or negative values") - } - if !ecdsa.Verify(pub, signed, ecdsaSig.R, ecdsaSig.S) { + if !ecdsa.VerifyASN1(pub, signed, signature) { return errors.New("x509: ECDSA verification failure") } return @@ -1374,7 +1364,7 @@ func parseCertificate(in *certificate) (*Certificate, error) { if rest, err := asn1.Unmarshal(in.TBSCertificate.Issuer.FullBytes, &issuer); err != nil { return nil, err } else if len(rest) != 0 { - return nil, errors.New("x509: trailing data after X.509 subject") + return nil, errors.New("x509: trailing data after X.509 issuer") } out.Issuer.FillFromRDNSequence(&issuer) @@ -1644,6 +1634,7 @@ var ( oidExtensionNameConstraints = []int{2, 5, 29, 30} oidExtensionCRLDistributionPoints = []int{2, 5, 29, 31} oidExtensionAuthorityInfoAccess = []int{1, 3, 6, 1, 5, 5, 7, 1, 1} + oidExtensionCRLNumber = []int{2, 5, 29, 20} ) var ( @@ -1696,7 +1687,7 @@ func isIA5String(s string) error { return nil } -func buildExtensions(template *Certificate, subjectIsEmpty bool, authorityKeyId []byte) (ret []pkix.Extension, err error) { +func buildExtensions(template *Certificate, subjectIsEmpty bool, authorityKeyId []byte, subjectKeyId []byte) (ret []pkix.Extension, err error) { ret = make([]pkix.Extension, 10 /* maximum number of elements. */) n := 0 @@ -1761,9 +1752,9 @@ func buildExtensions(template *Certificate, subjectIsEmpty bool, authorityKeyId n++ } - if len(template.SubjectKeyId) > 0 && !oidInExtensions(oidExtensionSubjectKeyId, template.ExtraExtensions) { + if len(subjectKeyId) > 0 && !oidInExtensions(oidExtensionSubjectKeyId, template.ExtraExtensions) { ret[n].Id = oidExtensionSubjectKeyId - ret[n].Value, err = asn1.Marshal(template.SubjectKeyId) + ret[n].Value, err = asn1.Marshal(subjectKeyId) if err != nil { return } @@ -2092,6 +2083,9 @@ var emptyASN1Subject = []byte{0x30, 0} // The AuthorityKeyId will be taken from the SubjectKeyId of parent, if any, // unless the resulting certificate is self-signed. Otherwise the value from // template will be used. +// +// If SubjectKeyId from template is empty and the template is a CA, SubjectKeyId +// will be generated from the hash of the public key. func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv interface{}) (cert []byte, err error) { key, ok := priv.(crypto.Signer) if !ok { @@ -2102,6 +2096,10 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv return nil, errors.New("x509: no SerialNumber given") } + if template.BasicConstraintsValid && !template.IsCA && template.MaxPathLen != -1 && (template.MaxPathLen != 0 || template.MaxPathLenZero) { + return nil, errors.New("x509: only CAs are allowed to specify MaxPathLen") + } + hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(key.Public(), template.SignatureAlgorithm) if err != nil { return nil, err @@ -2127,7 +2125,17 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv authorityKeyId = parent.SubjectKeyId } - extensions, err := buildExtensions(template, bytes.Equal(asn1Subject, emptyASN1Subject), authorityKeyId) + subjectKeyId := template.SubjectKeyId + if len(subjectKeyId) == 0 && template.IsCA { + // SubjectKeyId generated using method 1 in RFC 5280, Section 4.2.1.2: + // (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the + // value of the BIT STRING subjectPublicKey (excluding the tag, + // length, and number of unused bits). + h := sha1.Sum(publicKeyBytes) + subjectKeyId = h[:] + } + + extensions, err := buildExtensions(template, bytes.Equal(asn1Subject, emptyASN1Subject), authorityKeyId, subjectKeyId) if err != nil { return } @@ -2213,6 +2221,9 @@ func ParseDERCRL(derBytes []byte) (*pkix.CertificateList, error) { // CreateCRL returns a DER encoded CRL, signed by this Certificate, that // contains the given list of revoked certificates. +// +// Note: this method does not generate an RFC 5280 conformant X.509 v2 CRL. +// To generate a standards compliant CRL, use CreateRevocationList instead. func (c *Certificate) CreateCRL(rand io.Reader, priv interface{}, revokedCerts []pkix.RevokedCertificate, now, expiry time.Time) (crlBytes []byte, err error) { key, ok := priv.(crypto.Signer) if !ok { @@ -2338,7 +2349,7 @@ type certificateRequest struct { SignatureValue asn1.BitString } -// oidExtensionRequest is a PKCS#9 OBJECT IDENTIFIER that indicates requested +// oidExtensionRequest is a PKCS #9 OBJECT IDENTIFIER that indicates requested // extensions in a CSR. var oidExtensionRequest = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 14} @@ -2660,3 +2671,141 @@ func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error func (c *CertificateRequest) CheckSignature() error { return checkSignature(c.SignatureAlgorithm, c.RawTBSCertificateRequest, c.Signature, c.PublicKey) } + +// RevocationList contains the fields used to create an X.509 v2 Certificate +// Revocation list with CreateRevocationList. +type RevocationList struct { + // SignatureAlgorithm is used to determine the signature algorithm to be + // used when signing the CRL. If 0 the default algorithm for the signing + // key will be used. + SignatureAlgorithm SignatureAlgorithm + + // RevokedCertificates is used to populate the revokedCertificates + // sequence in the CRL, it may be empty. RevokedCertificates may be nil, + // in which case an empty CRL will be created. + RevokedCertificates []pkix.RevokedCertificate + + // Number is used to populate the X.509 v2 cRLNumber extension in the CRL, + // which should be a monotonically increasing sequence number for a given + // CRL scope and CRL issuer. + Number *big.Int + // ThisUpdate is used to populate the thisUpdate field in the CRL, which + // indicates the issuance date of the CRL. + ThisUpdate time.Time + // NextUpdate is used to populate the nextUpdate field in the CRL, which + // indicates the date by which the next CRL will be issued. NextUpdate + // must be greater than ThisUpdate. + NextUpdate time.Time + // ExtraExtensions contains any additional extensions to add directly to + // the CRL. + ExtraExtensions []pkix.Extension +} + +// CreateRevocationList creates a new X.509 v2 Certificate Revocation List, +// according to RFC 5280, based on template. +// +// The CRL is signed by priv which should be the private key associated with +// the public key in the issuer certificate. +// +// The issuer may not be nil, and the crlSign bit must be set in KeyUsage in +// order to use it as a CRL issuer. +// +// The issuer distinguished name CRL field and authority key identifier +// extension are populated using the issuer certificate. issuer must have +// SubjectKeyId set. +func CreateRevocationList(rand io.Reader, template *RevocationList, issuer *Certificate, priv crypto.Signer) ([]byte, error) { + if template == nil { + return nil, errors.New("x509: template can not be nil") + } + if issuer == nil { + return nil, errors.New("x509: issuer can not be nil") + } + if (issuer.KeyUsage & KeyUsageCRLSign) == 0 { + return nil, errors.New("x509: issuer must have the crlSign key usage bit set") + } + if len(issuer.SubjectKeyId) == 0 { + return nil, errors.New("x509: issuer certificate doesn't contain a subject key identifier") + } + if template.NextUpdate.Before(template.ThisUpdate) { + return nil, errors.New("x509: template.ThisUpdate is after template.NextUpdate") + } + if template.Number == nil { + return nil, errors.New("x509: template contains nil Number field") + } + + hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(priv.Public(), template.SignatureAlgorithm) + if err != nil { + return nil, err + } + + // Force revocation times to UTC per RFC 5280. + revokedCertsUTC := make([]pkix.RevokedCertificate, len(template.RevokedCertificates)) + for i, rc := range template.RevokedCertificates { + rc.RevocationTime = rc.RevocationTime.UTC() + revokedCertsUTC[i] = rc + } + + aki, err := asn1.Marshal(authKeyId{Id: issuer.SubjectKeyId}) + if err != nil { + return nil, err + } + crlNum, err := asn1.Marshal(template.Number) + if err != nil { + return nil, err + } + + tbsCertList := pkix.TBSCertificateList{ + Version: 1, // v2 + Signature: signatureAlgorithm, + Issuer: issuer.Subject.ToRDNSequence(), + ThisUpdate: template.ThisUpdate.UTC(), + NextUpdate: template.NextUpdate.UTC(), + Extensions: []pkix.Extension{ + { + Id: oidExtensionAuthorityKeyId, + Value: aki, + }, + { + Id: oidExtensionCRLNumber, + Value: crlNum, + }, + }, + } + if len(revokedCertsUTC) > 0 { + tbsCertList.RevokedCertificates = revokedCertsUTC + } + + if len(template.ExtraExtensions) > 0 { + tbsCertList.Extensions = append(tbsCertList.Extensions, template.ExtraExtensions...) + } + + tbsCertListContents, err := asn1.Marshal(tbsCertList) + if err != nil { + return nil, err + } + + input := tbsCertListContents + if hashFunc != 0 { + h := hashFunc.New() + h.Write(tbsCertListContents) + input = h.Sum(nil) + } + var signerOpts crypto.SignerOpts = hashFunc + if template.SignatureAlgorithm.isRSAPSS() { + signerOpts = &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthEqualsHash, + Hash: hashFunc, + } + } + + signature, err := priv.Sign(rand, input, signerOpts) + if err != nil { + return nil, err + } + + return asn1.Marshal(pkix.CertificateList{ + TBSCertList: tbsCertList, + SignatureAlgorithm: signatureAlgorithm, + SignatureValue: asn1.BitString{Bytes: signature, BitLength: len(signature) * 8}, + }) +} diff --git a/libgo/go/crypto/x509/x509_test.go b/libgo/go/crypto/x509/x509_test.go index 9e15b8adbfe..840f535e552 100644 --- a/libgo/go/crypto/x509/x509_test.go +++ b/libgo/go/crypto/x509/x509_test.go @@ -6,6 +6,7 @@ package x509 import ( "bytes" + "crypto" "crypto/dsa" "crypto/ecdsa" "crypto/ed25519" @@ -356,25 +357,40 @@ var matchHostnamesTests = []matchHostnamesTest{ {"*.example.com", "www.example.com", true}, {"*.example.com", "www.example.com.", true}, {"*.example.com", "xyz.www.example.com", false}, + {"*.example.com", "https://www.example.com", false}, // Issue 27591 + {"*.example..com", "www.example..com", false}, + {"www.example..com", "www.example..com", true}, {"*.*.example.com", "xyz.www.example.com", false}, {"*.www.*.com", "xyz.www.example.com", false}, {"*bar.example.com", "foobar.example.com", false}, {"f*.example.com", "foobar.example.com", false}, + {"www.example.com", "*.example.com", false}, {"", ".", false}, {".", "", false}, {".", ".", false}, {"example.com", "example.com.", true}, - {"example.com.", "example.com", true}, - {"example.com.", "example.com.", true}, - {"*.com.", "example.com.", true}, - {"*.com.", "example.com", true}, + {"example.com.", "example.com", false}, + {"example.com.", "example.com.", true}, // perfect matches allow trailing dots in patterns + {"*.com.", "example.com.", false}, + {"*.com.", "example.com", false}, {"*.com", "example.com", true}, {"*.com", "example.com.", true}, + {"foo:bar", "foo:bar", true}, + {"*.foo:bar", "xxx.foo:bar", false}, + {"*.2.3.4", "1.2.3.4", false}, + {"*.2.3.4", "[1.2.3.4]", false}, + {"*:4860:4860::8888", "2001:4860:4860::8888", false}, + {"*:4860:4860::8888", "[2001:4860:4860::8888]", false}, + {"2001:4860:4860::8888", "2001:4860:4860::8888", false}, + {"2001:4860:4860::8888", "[2001:4860:4860::8888]", false}, + {"[2001:4860:4860::8888]", "2001:4860:4860::8888", false}, + {"[2001:4860:4860::8888]", "[2001:4860:4860::8888]", false}, } func TestMatchHostnames(t *testing.T) { for i, test := range matchHostnamesTests { - r := matchHostnames(test.pattern, test.host) + c := &Certificate{DNSNames: []string{test.pattern}} + r := c.VerifyHostname(test.host) == nil if r != test.ok { t.Errorf("#%d mismatch got: %t want: %t when matching '%s' against '%s'", i, r, test.ok, test.host, test.pattern) } @@ -425,7 +441,7 @@ func TestMatchIP(t *testing.T) { } func TestCertificateParse(t *testing.T) { - s, _ := hex.DecodeString(certBytes) + s, _ := base64.StdEncoding.DecodeString(certBytes) certs, err := ParseCertificates(s) if err != nil { t.Error(err) @@ -444,7 +460,7 @@ func TestCertificateParse(t *testing.T) { t.Error(err) } - const expectedExtensions = 4 + const expectedExtensions = 10 if n := len(certs[0].Extensions); n != expectedExtensions { t.Errorf("want %d extensions, got %d", expectedExtensions, n) } @@ -488,48 +504,50 @@ func TestMismatchedSignatureAlgorithm(t *testing.T) { } } -var certBytes = "308203223082028ba00302010202106edf0d9499fd4533dd1297fc42a93be1300d06092a864886" + - "f70d0101050500304c310b3009060355040613025a4131253023060355040a131c546861777465" + - "20436f6e73756c74696e67202850747929204c74642e311630140603550403130d546861777465" + - "20534743204341301e170d3039303332353136343932395a170d3130303332353136343932395a" + - "3069310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630" + - "140603550407130d4d6f756e7461696e205669657731133011060355040a130a476f6f676c6520" + - "496e63311830160603550403130f6d61696c2e676f6f676c652e636f6d30819f300d06092a8648" + - "86f70d010101050003818d0030818902818100c5d6f892fccaf5614b064149e80a2c9581a218ef" + - "41ec35bd7a58125ae76f9ea54ddc893abbeb029f6b73616bf0ffd868791fba7af9c4aebf3706ba" + - "3eeaeed27435b4ddcfb157c05f351d66aa87fee0de072d66d773affbd36ab78bef090e0cc861a9" + - "03ac90dd98b51c9c41566c017f0beec3bff391051ffba0f5cc6850ad2a590203010001a381e730" + - "81e430280603551d250421301f06082b0601050507030106082b06010505070302060960864801" + - "86f842040130360603551d1f042f302d302ba029a0278625687474703a2f2f63726c2e74686177" + - "74652e636f6d2f54686177746553474343412e63726c307206082b060105050701010466306430" + - "2206082b060105050730018616687474703a2f2f6f6373702e7468617774652e636f6d303e0608" + - "2b060105050730028632687474703a2f2f7777772e7468617774652e636f6d2f7265706f736974" + - "6f72792f5468617774655f5347435f43412e637274300c0603551d130101ff04023000300d0609" + - "2a864886f70d01010505000381810062f1f3050ebc105e497c7aedf87e24d2f4a986bb3b837bd1" + - "9b91ebcad98b065992f6bd2b49b7d6d3cb2e427a99d606c7b1d46352527fac39e6a8b6726de5bf" + - "70212a52cba07634a5e332011bd1868e78eb5e3c93cf03072276786f207494feaa0ed9d53b2110" + - "a76571f90209cdae884385c882587030ee15f33d761e2e45a6bc308203233082028ca003020102" + - "020430000002300d06092a864886f70d0101050500305f310b3009060355040613025553311730" + - "15060355040a130e566572695369676e2c20496e632e31373035060355040b132e436c61737320" + - "33205075626c6963205072696d6172792043657274696669636174696f6e20417574686f726974" + - "79301e170d3034303531333030303030305a170d3134303531323233353935395a304c310b3009" + - "060355040613025a4131253023060355040a131c54686177746520436f6e73756c74696e672028" + - "50747929204c74642e311630140603550403130d5468617774652053474320434130819f300d06" + - "092a864886f70d010101050003818d0030818902818100d4d367d08d157faecd31fe7d1d91a13f" + - "0b713cacccc864fb63fc324b0794bd6f80ba2fe10493c033fc093323e90b742b71c403c6d2cde2" + - "2ff50963cdff48a500bfe0e7f388b72d32de9836e60aad007bc4644a3b847503f270927d0e62f5" + - "21ab693684317590f8bfc76c881b06957cc9e5a8de75a12c7a68dfd5ca1c875860190203010001" + - "a381fe3081fb30120603551d130101ff040830060101ff020100300b0603551d0f040403020106" + - "301106096086480186f842010104040302010630280603551d110421301fa41d301b3119301706" + - "035504031310507269766174654c6162656c332d313530310603551d1f042a30283026a024a022" + - "8620687474703a2f2f63726c2e766572697369676e2e636f6d2f706361332e63726c303206082b" + - "0601050507010104263024302206082b060105050730018616687474703a2f2f6f6373702e7468" + - "617774652e636f6d30340603551d25042d302b06082b0601050507030106082b06010505070302" + - "06096086480186f8420401060a6086480186f845010801300d06092a864886f70d010105050003" + - "81810055ac63eadea1ddd2905f9f0bce76be13518f93d9052bc81b774bad6950a1eededcfddb07" + - "e9e83994dcab72792f06bfab8170c4a8edea5334edef1e53d906c7562bd15cf4d18a8eb42bb137" + - "9048084225c53e8acb7feb6f04d16dc574a2f7a27c7b603c77cd0ece48027f012fb69b37e02a2a" + - "36dcd585d6ace53f546f961e05af" +var certBytes = "MIIE0jCCA7qgAwIBAgIQWcvS+TTB3GwCAAAAAGEAWzANBgkqhkiG9w0BAQsFADBCMQswCQYD" + + "VQQGEwJVUzEeMBwGA1UEChMVR29vZ2xlIFRydXN0IFNlcnZpY2VzMRMwEQYDVQQDEwpHVFMg" + + "Q0EgMU8xMB4XDTIwMDQwMTEyNTg1NloXDTIwMDYyNDEyNTg1NlowaTELMAkGA1UEBhMCVVMx" + + "EzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxEzARBgNVBAoT" + + "Ckdvb2dsZSBMTEMxGDAWBgNVBAMTD21haWwuZ29vZ2xlLmNvbTBZMBMGByqGSM49AgEGCCqG" + + "SM49AwEHA0IABO+dYiPnkFl+cZVf6mrWeNp0RhQcJSBGH+sEJxjvc+cYlW3QJCnm57qlpFdd" + + "pz3MPyVejvXQdM6iI1mEWP4C2OujggJmMIICYjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAww" + + "CgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUI6pZhnQ/lQgmPDwSKR2A54G7" + + "AS4wHwYDVR0jBBgwFoAUmNH4bhDrz5vsYJ8YkBug630J/SswZAYIKwYBBQUHAQEEWDBWMCcG" + + "CCsGAQUFBzABhhtodHRwOi8vb2NzcC5wa2kuZ29vZy9ndHMxbzEwKwYIKwYBBQUHMAKGH2h0" + + "dHA6Ly9wa2kuZ29vZy9nc3IyL0dUUzFPMS5jcnQwLAYDVR0RBCUwI4IPbWFpbC5nb29nbGUu" + + "Y29tghBpbmJveC5nb29nbGUuY29tMCEGA1UdIAQaMBgwCAYGZ4EMAQICMAwGCisGAQQB1nkC" + + "BQMwLwYDVR0fBCgwJjAkoCKgIIYeaHR0cDovL2NybC5wa2kuZ29vZy9HVFMxTzEuY3JsMIIB" + + "AwYKKwYBBAHWeQIEAgSB9ASB8QDvAHYAsh4FzIuizYogTodm+Su5iiUgZ2va+nDnsklTLe+L" + + "kF4AAAFxNgmxKgAABAMARzBFAiEA12/OHdTGXQ3qHHC3NvYCyB8aEz/+ZFOLCAI7lhqj28sC" + + "IG2/7Yz2zK6S6ai+dH7cTMZmoFGo39gtaTqtZAqEQX7nAHUAXqdz+d9WwOe1Nkh90EngMnqR" + + "mgyEoRIShBh1loFxRVgAAAFxNgmxTAAABAMARjBEAiA7PNq+MFfv6O9mBkxFViS2TfU66yRB" + + "/njcebWglLQjZQIgOyRKhxlEizncFRml7yn4Bg48ktXKGjo+uiw6zXEINb0wDQYJKoZIhvcN" + + "AQELBQADggEBADM2Rh306Q10PScsolYMxH1B/K4Nb2WICvpY0yDPJFdnGjqCYym196TjiEvs" + + "R6etfeHdyzlZj6nh82B4TVyHjiWM02dQgPalOuWQcuSy0OvLh7F1E7CeHzKlczdFPBTOTdM1" + + "RDTxlvw1bAqc0zueM8QIAyEy3opd7FxAcGQd5WRIJhzLBL+dbbMOW/LTeW7cm/Xzq8cgCybN" + + "BSZAvhjseJ1L29OlCTZL97IfnX0IlFQzWuvvHy7V2B0E3DHlzM0kjwkkCKDUUp/wajv2NZKC" + + "TkhEyERacZRKc9U0ADxwsAzHrdz5+5zfD2usEV/MQ5V6d8swLXs+ko0X6swrd4YCiB8wggRK" + + "MIIDMqADAgECAg0B47SaoY2KqYElaVC4MA0GCSqGSIb3DQEBCwUAMEwxIDAeBgNVBAsTF0ds" + + "b2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpH" + + "bG9iYWxTaWduMB4XDTE3MDYxNTAwMDA0MloXDTIxMTIxNTAwMDA0MlowQjELMAkGA1UEBhMC" + + "VVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczETMBEGA1UEAxMKR1RTIENBIDFP" + + "MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAYz0XUi83TnORA73603WkhG8nP" + + "PI5MdbkPMRmEPZ48Ke9QDRCTbwWAgJ8qoL0SSwLhPZ9YFiT+MJ8LdHdVkx1L903hkoIQ9lGs" + + "DMOyIpQPNGuYEEnnC52DOd0gxhwt79EYYWXnI4MgqCMS/9Ikf9Qv50RqW03XUGawr55CYwX7" + + "4BzEY2Gvn2oz/2KXvUjZ03wUZ9x13C5p6PhteGnQtxAFuPExwjsk/RozdPgj4OxrGYoWxuPN" + + "pM0L27OkWWA4iDutHbnGjKdTG/y82aSrvN08YdeTFZjugb2P4mRHIEAGTtesl+i5wFkSoUkl" + + "I+TtcDQspbRjfPmjPYPRzW0krAcCAwEAAaOCATMwggEvMA4GA1UdDwEB/wQEAwIBhjAdBgNV" + + "HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4E" + + "FgQUmNH4bhDrz5vsYJ8YkBug630J/SswHwYDVR0jBBgwFoAUm+IHV2ccHsBqBt5ZtJot39wZ" + + "hi4wNQYIKwYBBQUHAQEEKTAnMCUGCCsGAQUFBzABhhlodHRwOi8vb2NzcC5wa2kuZ29vZy9n" + + "c3IyMDIGA1UdHwQrMCkwJ6AloCOGIWh0dHA6Ly9jcmwucGtpLmdvb2cvZ3NyMi9nc3IyLmNy" + + "bDA/BgNVHSAEODA2MDQGBmeBDAECAjAqMCgGCCsGAQUFBwIBFhxodHRwczovL3BraS5nb29n" + + "L3JlcG9zaXRvcnkvMA0GCSqGSIb3DQEBCwUAA4IBAQAagD42efvzLqlGN31eVBY1rsdOCJn+" + + "vdE0aSZSZgc9CrpJy2L08RqO/BFPaJZMdCvTZ96yo6oFjYRNTCBlD6WW2g0W+Gw7228EI4hr" + + "OmzBYL1on3GO7i1YNAfw1VTphln9e14NIZT1jMmo+NjyrcwPGvOap6kEJ/mjybD/AnhrYbrH" + + "NSvoVvpPwxwM7bY8tEvq7czhPOzcDYzWPpvKQliLzBYhF0C8otZm79rEFVvNiaqbCSbnMtIN" + + "bmcgAlsQsJAJnAwfnq3YO+qh/GzoEFwIUhlRKnG7rHq13RXtK8kIKiyKtKYhq2P/11JJUNCJ" + + "t63yr/tQri/hlQ3zRq2dnPXK" func parseCIDR(s string) *net.IPNet { _, net, err := net.ParseCIDR(s) @@ -1241,9 +1259,9 @@ FOq7cMJvODRwvMin9HwNHijXKp8iikXoAnaEHi1kLR4JtSlxH5WKTnmHUWCa54ZA 9mDH0e5odhcdkMySkwc= -----END CERTIFICATE-----` -const ed25519CRLKey = `-----BEGIN PRIVATE KEY----- +var ed25519CRLKey = testingKey(`-----BEGIN TEST KEY----- MC4CAQAwBQYDK2VwBCIEINdKh2096vUBYu4EIFpjShsUSh3vimKya1sQ1YTT4RZG ------END PRIVATE KEY-----` +-----END TEST KEY-----`) func TestCRLCreation(t *testing.T) { block, _ := pem.Decode([]byte(pemPrivateKey)) @@ -1644,6 +1662,44 @@ func serialiseAndParse(t *testing.T, template *Certificate) *Certificate { return cert } +func TestMaxPathLenNotCA(t *testing.T) { + template := &Certificate{ + SerialNumber: big.NewInt(1), + Subject: pkix.Name{ + CommonName: "Σ Acme Co", + }, + NotBefore: time.Unix(1000, 0), + NotAfter: time.Unix(100000, 0), + + BasicConstraintsValid: true, + IsCA: false, + } + if m := serialiseAndParse(t, template).MaxPathLen; m != -1 { + t.Errorf("MaxPathLen should be -1 when IsCa is false, got %d", m) + } + + template.MaxPathLen = -1 + if m := serialiseAndParse(t, template).MaxPathLen; m != -1 { + t.Errorf("MaxPathLen should be -1 when IsCa is false and MaxPathLen set to -1, got %d", m) + } + + template.MaxPathLen = 5 + if _, err := CreateCertificate(rand.Reader, template, template, &testPrivateKey.PublicKey, testPrivateKey); err == nil { + t.Error("specifying a MaxPathLen when IsCA is false should fail") + } + + template.MaxPathLen = 0 + template.MaxPathLenZero = true + if _, err := CreateCertificate(rand.Reader, template, template, &testPrivateKey.PublicKey, testPrivateKey); err == nil { + t.Error("setting MaxPathLenZero when IsCA is false should fail") + } + + template.BasicConstraintsValid = false + if m := serialiseAndParse(t, template).MaxPathLen; m != 0 { + t.Errorf("Bad MaxPathLen should be ignored if BasicConstraintsValid is false, got %d", m) + } +} + func TestMaxPathLen(t *testing.T) { template := &Certificate{ SerialNumber: big.NewInt(1), @@ -1709,6 +1765,33 @@ func TestNoAuthorityKeyIdInSelfSignedCert(t *testing.T) { } } +func TestNoSubjectKeyIdInCert(t *testing.T) { + template := &Certificate{ + SerialNumber: big.NewInt(1), + Subject: pkix.Name{ + CommonName: "Σ Acme Co", + }, + NotBefore: time.Unix(1000, 0), + NotAfter: time.Unix(100000, 0), + + BasicConstraintsValid: true, + IsCA: true, + } + if cert := serialiseAndParse(t, template); len(cert.SubjectKeyId) == 0 { + t.Fatalf("self-signed certificate did not generate subject key id using the public key") + } + + template.IsCA = false + if cert := serialiseAndParse(t, template); len(cert.SubjectKeyId) != 0 { + t.Fatalf("self-signed certificate generated subject key id when it isn't a CA") + } + + template.SubjectKeyId = []byte{1, 2, 3, 4} + if cert := serialiseAndParse(t, template); len(cert.SubjectKeyId) == 0 { + t.Fatalf("self-signed certificate erased explicit subject key id") + } +} + func TestASN1BitLength(t *testing.T) { tests := []struct { bytes []byte @@ -1805,7 +1888,7 @@ func TestMD5(t *testing.T) { } } -// certMissingRSANULL contains an RSA public key where the AlgorithmIdentifer +// certMissingRSANULL contains an RSA public key where the AlgorithmIdentifier // parameters are omitted rather than being an ASN.1 NULL. const certMissingRSANULL = ` -----BEGIN CERTIFICATE----- @@ -1984,19 +2067,40 @@ func TestEmptyNameConstraints(t *testing.T) { } func TestPKIXNameString(t *testing.T) { - pem, err := hex.DecodeString(certBytes) + der, err := base64.StdEncoding.DecodeString(certBytes) if err != nil { t.Fatal(err) } - certs, err := ParseCertificates(pem) + certs, err := ParseCertificates(der) if err != nil { t.Fatal(err) } + // Check that parsed non-standard attributes are printed. + rdns := pkix.Name{ + Locality: []string{"Gophertown"}, + ExtraNames: []pkix.AttributeTypeAndValue{ + {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}}, + }.ToRDNSequence() + nn := pkix.Name{} + nn.FillFromRDNSequence(&rdns) + + // Check that zero-length non-nil ExtraNames hide Names. + extra := []pkix.AttributeTypeAndValue{ + {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "backing array"}} + extraNotNil := pkix.Name{ + Locality: []string{"Gophertown"}, + ExtraNames: extra[:0], + Names: []pkix.AttributeTypeAndValue{ + {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}}, + } + tests := []struct { dn pkix.Name want string }{ + {nn, "L=Gophertown,1.2.3.4.5=#130a676f6c616e672e6f7267"}, + {extraNotNil, "L=Gophertown"}, {pkix.Name{ CommonName: "Steve Kille", Organization: []string{"Isode Limited"}, @@ -2009,7 +2113,7 @@ func TestPKIXNameString(t *testing.T) { Country: []string{"GB"}, }, "SERIALNUMBER=RFC 2253,CN=Steve Kille,OU=RFCs,O=Isode Limited,POSTALCODE=TW9 1DT,STREET=The Square,L=Richmond,ST=Surrey,C=GB"}, {certs[0].Subject, - "CN=mail.google.com,O=Google Inc,L=Mountain View,ST=California,C=US"}, + "CN=mail.google.com,O=Google LLC,L=Mountain View,ST=California,C=US"}, {pkix.Name{ Organization: []string{"#Google, Inc. \n-> 'Alphabet\" "}, Country: []string{"US"}, @@ -2025,6 +2129,20 @@ func TestPKIXNameString(t *testing.T) { ExtraNames: []pkix.AttributeTypeAndValue{ {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}}, }, "1.2.3.4.5=#130a676f6c616e672e6f7267,L=Gophertown"}, + // If there are no ExtraNames, the Names are printed instead. + {pkix.Name{ + Locality: []string{"Gophertown"}, + Names: []pkix.AttributeTypeAndValue{ + {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}}, + }, "L=Gophertown,1.2.3.4.5=#130a676f6c616e672e6f7267"}, + // If there are both, print only the ExtraNames. + {pkix.Name{ + Locality: []string{"Gophertown"}, + ExtraNames: []pkix.AttributeTypeAndValue{ + {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}}, + Names: []pkix.AttributeTypeAndValue{ + {Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 6}), Value: "example.com"}}, + }, "1.2.3.4.5=#130a676f6c616e672e6f7267,L=Gophertown"}, } for i, test := range tests { @@ -2032,6 +2150,10 @@ func TestPKIXNameString(t *testing.T) { t.Errorf("#%d: String() = \n%s\n, want \n%s", i, got, test.want) } } + + if extra[0].Value != "backing array" { + t.Errorf("the backing array of an empty ExtraNames got modified by String") + } } func TestRDNSequenceString(t *testing.T) { @@ -2293,3 +2415,290 @@ func TestPKCS1MismatchKeyFormat(t *testing.T) { } } } + +func TestCreateRevocationList(t *testing.T) { + ec256Priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + t.Fatalf("Failed to generate ECDSA P256 key: %s", err) + } + _, ed25519Priv, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + t.Fatalf("Failed to generate Ed25519 key: %s", err) + } + tests := []struct { + name string + key crypto.Signer + issuer *Certificate + template *RevocationList + expectedError string + }{ + { + name: "nil template", + key: ec256Priv, + issuer: nil, + template: nil, + expectedError: "x509: template can not be nil", + }, + { + name: "nil issuer", + key: ec256Priv, + issuer: nil, + template: &RevocationList{}, + expectedError: "x509: issuer can not be nil", + }, + { + name: "issuer doesn't have crlSign key usage bit set", + key: ec256Priv, + issuer: &Certificate{ + KeyUsage: KeyUsageCertSign, + }, + template: &RevocationList{}, + expectedError: "x509: issuer must have the crlSign key usage bit set", + }, + { + name: "issuer missing SubjectKeyId", + key: ec256Priv, + issuer: &Certificate{ + KeyUsage: KeyUsageCRLSign, + }, + template: &RevocationList{}, + expectedError: "x509: issuer certificate doesn't contain a subject key identifier", + }, + { + name: "nextUpdate before thisUpdate", + key: ec256Priv, + issuer: &Certificate{ + KeyUsage: KeyUsageCRLSign, + Subject: pkix.Name{ + CommonName: "testing", + }, + SubjectKeyId: []byte{1, 2, 3}, + }, + template: &RevocationList{ + ThisUpdate: time.Time{}.Add(time.Hour), + NextUpdate: time.Time{}, + }, + expectedError: "x509: template.ThisUpdate is after template.NextUpdate", + }, + { + name: "nil Number", + key: ec256Priv, + issuer: &Certificate{ + KeyUsage: KeyUsageCRLSign, + Subject: pkix.Name{ + CommonName: "testing", + }, + SubjectKeyId: []byte{1, 2, 3}, + }, + template: &RevocationList{ + ThisUpdate: time.Time{}.Add(time.Hour * 24), + NextUpdate: time.Time{}.Add(time.Hour * 48), + }, + expectedError: "x509: template contains nil Number field", + }, + { + name: "invalid signature algorithm", + key: ec256Priv, + issuer: &Certificate{ + KeyUsage: KeyUsageCRLSign, + Subject: pkix.Name{ + CommonName: "testing", + }, + SubjectKeyId: []byte{1, 2, 3}, + }, + template: &RevocationList{ + SignatureAlgorithm: SHA256WithRSA, + RevokedCertificates: []pkix.RevokedCertificate{ + { + SerialNumber: big.NewInt(2), + RevocationTime: time.Time{}.Add(time.Hour), + }, + }, + Number: big.NewInt(5), + ThisUpdate: time.Time{}.Add(time.Hour * 24), + NextUpdate: time.Time{}.Add(time.Hour * 48), + }, + expectedError: "x509: requested SignatureAlgorithm does not match private key type", + }, + { + name: "valid", + key: ec256Priv, + issuer: &Certificate{ + KeyUsage: KeyUsageCRLSign, + Subject: pkix.Name{ + CommonName: "testing", + }, + SubjectKeyId: []byte{1, 2, 3}, + }, + template: &RevocationList{ + RevokedCertificates: []pkix.RevokedCertificate{ + { + SerialNumber: big.NewInt(2), + RevocationTime: time.Time{}.Add(time.Hour), + }, + }, + Number: big.NewInt(5), + ThisUpdate: time.Time{}.Add(time.Hour * 24), + NextUpdate: time.Time{}.Add(time.Hour * 48), + }, + }, + { + name: "valid, Ed25519 key", + key: ed25519Priv, + issuer: &Certificate{ + KeyUsage: KeyUsageCRLSign, + Subject: pkix.Name{ + CommonName: "testing", + }, + SubjectKeyId: []byte{1, 2, 3}, + }, + template: &RevocationList{ + RevokedCertificates: []pkix.RevokedCertificate{ + { + SerialNumber: big.NewInt(2), + RevocationTime: time.Time{}.Add(time.Hour), + }, + }, + Number: big.NewInt(5), + ThisUpdate: time.Time{}.Add(time.Hour * 24), + NextUpdate: time.Time{}.Add(time.Hour * 48), + }, + }, + { + name: "valid, non-default signature algorithm", + key: ec256Priv, + issuer: &Certificate{ + KeyUsage: KeyUsageCRLSign, + Subject: pkix.Name{ + CommonName: "testing", + }, + SubjectKeyId: []byte{1, 2, 3}, + }, + template: &RevocationList{ + SignatureAlgorithm: ECDSAWithSHA512, + RevokedCertificates: []pkix.RevokedCertificate{ + { + SerialNumber: big.NewInt(2), + RevocationTime: time.Time{}.Add(time.Hour), + }, + }, + Number: big.NewInt(5), + ThisUpdate: time.Time{}.Add(time.Hour * 24), + NextUpdate: time.Time{}.Add(time.Hour * 48), + }, + }, + { + name: "valid, extra extension", + key: ec256Priv, + issuer: &Certificate{ + KeyUsage: KeyUsageCRLSign, + Subject: pkix.Name{ + CommonName: "testing", + }, + SubjectKeyId: []byte{1, 2, 3}, + }, + template: &RevocationList{ + RevokedCertificates: []pkix.RevokedCertificate{ + { + SerialNumber: big.NewInt(2), + RevocationTime: time.Time{}.Add(time.Hour), + }, + }, + Number: big.NewInt(5), + ThisUpdate: time.Time{}.Add(time.Hour * 24), + NextUpdate: time.Time{}.Add(time.Hour * 48), + ExtraExtensions: []pkix.Extension{ + { + Id: []int{2, 5, 29, 99}, + Value: []byte{5, 0}, + }, + }, + }, + }, + { + name: "valid, empty list", + key: ec256Priv, + issuer: &Certificate{ + KeyUsage: KeyUsageCRLSign, + Subject: pkix.Name{ + CommonName: "testing", + }, + SubjectKeyId: []byte{1, 2, 3}, + }, + template: &RevocationList{ + Number: big.NewInt(5), + ThisUpdate: time.Time{}.Add(time.Hour * 24), + NextUpdate: time.Time{}.Add(time.Hour * 48), + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + crl, err := CreateRevocationList(rand.Reader, tc.template, tc.issuer, tc.key) + if err != nil && tc.expectedError == "" { + t.Fatalf("CreateRevocationList failed unexpectedly: %s", err) + } else if err != nil && tc.expectedError != err.Error() { + t.Fatalf("CreateRevocationList failed unexpectedly, wanted: %s, got: %s", tc.expectedError, err) + } else if err == nil && tc.expectedError != "" { + t.Fatalf("CreateRevocationList didn't fail, expected: %s", tc.expectedError) + } + if tc.expectedError != "" { + return + } + + parsedCRL, err := ParseDERCRL(crl) + if err != nil { + t.Fatalf("Failed to parse generated CRL: %s", err) + } + + if tc.template.SignatureAlgorithm != UnknownSignatureAlgorithm && + parsedCRL.SignatureAlgorithm.Algorithm.Equal(signatureAlgorithmDetails[tc.template.SignatureAlgorithm].oid) { + t.Fatalf("SignatureAlgorithm mismatch: got %v; want %v.", parsedCRL.SignatureAlgorithm, + tc.template.SignatureAlgorithm) + } + + if !reflect.DeepEqual(parsedCRL.TBSCertList.RevokedCertificates, tc.template.RevokedCertificates) { + t.Fatalf("RevokedCertificates mismatch: got %v; want %v.", + parsedCRL.TBSCertList.RevokedCertificates, tc.template.RevokedCertificates) + } + + if len(parsedCRL.TBSCertList.Extensions) != 2+len(tc.template.ExtraExtensions) { + t.Fatalf("Generated CRL has wrong number of extensions, wanted: %d, got: %d", 2+len(tc.template.ExtraExtensions), len(parsedCRL.TBSCertList.Extensions)) + } + expectedAKI, err := asn1.Marshal(authKeyId{Id: tc.issuer.SubjectKeyId}) + if err != nil { + t.Fatalf("asn1.Marshal failed: %s", err) + } + akiExt := pkix.Extension{ + Id: oidExtensionAuthorityKeyId, + Value: expectedAKI, + } + if !reflect.DeepEqual(parsedCRL.TBSCertList.Extensions[0], akiExt) { + t.Fatalf("Unexpected first extension: got %v, want %v", + parsedCRL.TBSCertList.Extensions[0], akiExt) + } + expectedNum, err := asn1.Marshal(tc.template.Number) + if err != nil { + t.Fatalf("asn1.Marshal failed: %s", err) + } + crlExt := pkix.Extension{ + Id: oidExtensionCRLNumber, + Value: expectedNum, + } + if !reflect.DeepEqual(parsedCRL.TBSCertList.Extensions[1], crlExt) { + t.Fatalf("Unexpected second extension: got %v, want %v", + parsedCRL.TBSCertList.Extensions[1], crlExt) + } + if len(parsedCRL.TBSCertList.Extensions[2:]) == 0 && len(tc.template.ExtraExtensions) == 0 { + // If we don't have anything to check return early so we don't + // hit a [] != nil false positive below. + return + } + if !reflect.DeepEqual(parsedCRL.TBSCertList.Extensions[2:], tc.template.ExtraExtensions) { + t.Fatalf("Extensions mismatch: got %v; want %v.", + parsedCRL.TBSCertList.Extensions[2:], tc.template.ExtraExtensions) + } + }) + } +} diff --git a/libgo/go/database/sql/driver/driver.go b/libgo/go/database/sql/driver/driver.go index a0ba7ecf694..5bbcf20db2f 100644 --- a/libgo/go/database/sql/driver/driver.go +++ b/libgo/go/database/sql/driver/driver.go @@ -6,6 +6,35 @@ // drivers as used by package sql. // // Most code should use package sql. +// +// The driver interface has evolved over time. Drivers should implement +// Connector and DriverContext interfaces. +// The Connector.Connect and Driver.Open methods should never return ErrBadConn. +// ErrBadConn should only be returned from Validator, SessionResetter, or +// a query method if the connection is already in an invalid (e.g. closed) state. +// +// All Conn implementations should implement the following interfaces: +// Pinger, SessionResetter, and Validator. +// +// If named parameters or context are supported, the driver's Conn should implement: +// ExecerContext, QueryerContext, ConnPrepareContext, and ConnBeginTx. +// +// To support custom data types, implement NamedValueChecker. NamedValueChecker +// also allows queries to accept per-query options as a parameter by returning +// ErrRemoveArgument from CheckNamedValue. +// +// If multiple result sets are supported, Rows should implement RowsNextResultSet. +// If the driver knows how to describe the types present in the returned result +// it should implement the following interfaces: RowsColumnTypeScanType, +// RowsColumnTypeDatabaseTypeName, RowsColumnTypeLength, RowsColumnTypeNullable, +// and RowsColumnTypePrecisionScale. A given row value may also return a Rows +// type, which may represent a database cursor value. +// +// Before a connection is returned to the connection pool after use, IsValid is +// called if implemented. Before a connection is reused for another query, +// ResetSession is called if implemented. If a connection is never returned to the +// connection pool but immediately reused, then ResetSession is called prior to +// reuse but IsValid is not called. package driver import ( @@ -67,7 +96,7 @@ type Driver interface { // If a Driver implements DriverContext, then sql.DB will call // OpenConnector to obtain a Connector and then invoke -// that Connector's Conn method to obtain each needed connection, +// that Connector's Connect method to obtain each needed connection, // instead of invoking the Driver's Open method for each connection. // The two-step sequence allows drivers to parse the name just once // and also provides access to per-Conn contexts. @@ -94,7 +123,9 @@ type Connector interface { // // The provided context.Context is for dialing purposes only // (see net.DialContext) and should not be stored or used for - // other purposes. + // other purposes. A default timeout should still be used + // when dialing as a connection pool may call Connect + // asynchronously to any query. // // The returned connection is only used by one goroutine at a // time. @@ -205,6 +236,9 @@ type Conn interface { // connections and only calls Close when there's a surplus of // idle connections, it shouldn't be necessary for drivers to // do their own connection caching. + // + // Drivers must ensure all network calls made by Close + // do not block indefinitely (e.g. apply a timeout). Close() error // Begin starts and returns a new transaction. @@ -261,6 +295,17 @@ type SessionResetter interface { ResetSession(ctx context.Context) error } +// Validator may be implemented by Conn to allow drivers to +// signal if a connection is valid or if it should be discarded. +// +// If implemented, drivers may return the underlying error from queries, +// even if the connection should be discarded by the connection pool. +type Validator interface { + // IsValid is called prior to placing the connection into the + // connection pool. The connection will be discarded if false is returned. + IsValid() bool +} + // Result is the result of a query execution. type Result interface { // LastInsertId returns the database's auto-generated ID @@ -280,6 +325,9 @@ type Stmt interface { // // As of Go 1.1, a Stmt will not be closed if it's in use // by any queries. + // + // Drivers must ensure all network calls made by Close + // do not block indefinitely (e.g. apply a timeout). Close() error // NumInput returns the number of placeholder parameters. diff --git a/libgo/go/database/sql/fakedb_test.go b/libgo/go/database/sql/fakedb_test.go index 0ec72d409d3..7605a2a6d23 100644 --- a/libgo/go/database/sql/fakedb_test.go +++ b/libgo/go/database/sql/fakedb_test.go @@ -397,7 +397,7 @@ func (c *fakeConn) ResetSession(ctx context.Context) error { return nil } -var _ validator = (*fakeConn)(nil) +var _ driver.Validator = (*fakeConn)(nil) func (c *fakeConn) IsValid() bool { return !c.isBad() diff --git a/libgo/go/database/sql/sql.go b/libgo/go/database/sql/sql.go index a0b7ca8f087..b3d0653f5c6 100644 --- a/libgo/go/database/sql/sql.go +++ b/libgo/go/database/sql/sql.go @@ -424,13 +424,15 @@ type DB struct { closed bool dep map[finalCloser]depSet lastPut map[*driverConn]string // stacktrace of last conn's put; debug only - maxIdle int // zero means defaultMaxIdleConns; negative means 0 + maxIdleCount int // zero means defaultMaxIdleConns; negative means 0 maxOpen int // <= 0 means unlimited maxLifetime time.Duration // maximum amount of time a connection may be reused + maxIdleTime time.Duration // maximum amount of time a connection may be idle before being closed cleanerCh chan struct{} waitCount int64 // Total number of connections waited for. - maxIdleClosed int64 // Total number of connections closed due to idle. - maxLifetimeClosed int64 // Total number of connections closed due to max free limit. + maxIdleClosed int64 // Total number of connections closed due to idle count. + maxIdleTimeClosed int64 // Total number of connections closed due to idle time. + maxLifetimeClosed int64 // Total number of connections closed due to max connection lifetime limit. stop func() // stop cancels the connection opener and the session resetter. } @@ -464,8 +466,9 @@ type driverConn struct { // guarded by db.mu inUse bool - onPut []func() // code (with db.mu held) run when conn is next returned - dbmuClosed bool // same as closed, but guarded by db.mu, for removeClosedStmtLocked + returnedAt time.Time // Time the connection was created or returned. + onPut []func() // code (with db.mu held) run when conn is next returned + dbmuClosed bool // same as closed, but guarded by db.mu, for removeClosedStmtLocked } func (dc *driverConn) releaseConn(err error) { @@ -500,11 +503,6 @@ func (dc *driverConn) resetSession(ctx context.Context) error { return nil } -// validator was introduced for Go1.15, but backported to Go1.14. -type validator interface { - IsValid() bool -} - // validateConnection checks if the connection is valid and can // still be used. It also marks the session for reset if required. func (dc *driverConn) validateConnection(needsReset bool) bool { @@ -514,7 +512,7 @@ func (dc *driverConn) validateConnection(needsReset bool) bool { if needsReset { dc.needReset = true } - if cv, ok := dc.ci.(validator); ok { + if cv, ok := dc.ci.(driver.Validator); ok { return cv.IsValid() } return true @@ -858,7 +856,7 @@ func (db *DB) Close() error { const defaultMaxIdleConns = 2 func (db *DB) maxIdleConnsLocked() int { - n := db.maxIdle + n := db.maxIdleCount switch { case n == 0: // TODO(bradfitz): ask driver, if supported, for its default preference @@ -870,6 +868,14 @@ func (db *DB) maxIdleConnsLocked() int { } } +func (db *DB) shortestIdleTimeLocked() time.Duration { + min := db.maxIdleTime + if min > db.maxLifetime { + min = db.maxLifetime + } + return min +} + // SetMaxIdleConns sets the maximum number of connections in the idle // connection pool. // @@ -883,14 +889,14 @@ func (db *DB) maxIdleConnsLocked() int { func (db *DB) SetMaxIdleConns(n int) { db.mu.Lock() if n > 0 { - db.maxIdle = n + db.maxIdleCount = n } else { // No idle connections. - db.maxIdle = -1 + db.maxIdleCount = -1 } // Make sure maxIdle doesn't exceed maxOpen if db.maxOpen > 0 && db.maxIdleConnsLocked() > db.maxOpen { - db.maxIdle = db.maxOpen + db.maxIdleCount = db.maxOpen } var closing []*driverConn idleCount := len(db.freeConn) @@ -931,13 +937,13 @@ func (db *DB) SetMaxOpenConns(n int) { // // Expired connections may be closed lazily before reuse. // -// If d <= 0, connections are reused forever. +// If d <= 0, connections are not closed due to a connection's age. func (db *DB) SetConnMaxLifetime(d time.Duration) { if d < 0 { d = 0 } db.mu.Lock() - // wake cleaner up when lifetime is shortened. + // Wake cleaner up when lifetime is shortened. if d > 0 && d < db.maxLifetime && db.cleanerCh != nil { select { case db.cleanerCh <- struct{}{}: @@ -949,11 +955,34 @@ func (db *DB) SetConnMaxLifetime(d time.Duration) { db.mu.Unlock() } +// SetConnMaxIdleTime sets the maximum amount of time a connection may be idle. +// +// Expired connections may be closed lazily before reuse. +// +// If d <= 0, connections are not closed due to a connection's idle time. +func (db *DB) SetConnMaxIdleTime(d time.Duration) { + if d < 0 { + d = 0 + } + db.mu.Lock() + defer db.mu.Unlock() + + // Wake cleaner up when idle time is shortened. + if d > 0 && d < db.maxIdleTime && db.cleanerCh != nil { + select { + case db.cleanerCh <- struct{}{}: + default: + } + } + db.maxIdleTime = d + db.startCleanerLocked() +} + // startCleanerLocked starts connectionCleaner if needed. func (db *DB) startCleanerLocked() { - if db.maxLifetime > 0 && db.numOpen > 0 && db.cleanerCh == nil { + if (db.maxLifetime > 0 || db.maxIdleTime > 0) && db.numOpen > 0 && db.cleanerCh == nil { db.cleanerCh = make(chan struct{}, 1) - go db.connectionCleaner(db.maxLifetime) + go db.connectionCleaner(db.shortestIdleTimeLocked()) } } @@ -972,15 +1001,30 @@ func (db *DB) connectionCleaner(d time.Duration) { } db.mu.Lock() - d = db.maxLifetime + + d = db.shortestIdleTimeLocked() if db.closed || db.numOpen == 0 || d <= 0 { db.cleanerCh = nil db.mu.Unlock() return } - expiredSince := nowFunc().Add(-d) - var closing []*driverConn + closing := db.connectionCleanerRunLocked() + db.mu.Unlock() + for _, c := range closing { + c.Close() + } + + if d < minInterval { + d = minInterval + } + t.Reset(d) + } +} + +func (db *DB) connectionCleanerRunLocked() (closing []*driverConn) { + if db.maxLifetime > 0 { + expiredSince := nowFunc().Add(-db.maxLifetime) for i := 0; i < len(db.freeConn); i++ { c := db.freeConn[i] if c.createdAt.Before(expiredSince) { @@ -993,17 +1037,26 @@ func (db *DB) connectionCleaner(d time.Duration) { } } db.maxLifetimeClosed += int64(len(closing)) - db.mu.Unlock() - - for _, c := range closing { - c.Close() - } + } - if d < minInterval { - d = minInterval + if db.maxIdleTime > 0 { + expiredSince := nowFunc().Add(-db.maxIdleTime) + var expiredCount int64 + for i := 0; i < len(db.freeConn); i++ { + c := db.freeConn[i] + if db.maxIdleTime > 0 && c.returnedAt.Before(expiredSince) { + closing = append(closing, c) + expiredCount++ + last := len(db.freeConn) - 1 + db.freeConn[i] = db.freeConn[last] + db.freeConn[last] = nil + db.freeConn = db.freeConn[:last] + i-- + } } - t.Reset(d) + db.maxIdleTimeClosed += expiredCount } + return } // DBStats contains database statistics. @@ -1019,6 +1072,7 @@ type DBStats struct { WaitCount int64 // The total number of connections waited for. WaitDuration time.Duration // The total time blocked waiting for a new connection. MaxIdleClosed int64 // The total number of connections closed due to SetMaxIdleConns. + MaxIdleTimeClosed int64 // The total number of connections closed due to SetConnMaxIdleTime. MaxLifetimeClosed int64 // The total number of connections closed due to SetConnMaxLifetime. } @@ -1039,6 +1093,7 @@ func (db *DB) Stats() DBStats { WaitCount: db.waitCount, WaitDuration: time.Duration(wait), MaxIdleClosed: db.maxIdleClosed, + MaxIdleTimeClosed: db.maxIdleTimeClosed, MaxLifetimeClosed: db.maxLifetimeClosed, } return stats @@ -1099,9 +1154,10 @@ func (db *DB) openNewConnection(ctx context.Context) { return } dc := &driverConn{ - db: db, - createdAt: nowFunc(), - ci: ci, + db: db, + createdAt: nowFunc(), + returnedAt: nowFunc(), + ci: ci, } if db.putConnDBLocked(dc, err) { db.addDepLocked(dc, dc) @@ -1152,11 +1208,13 @@ func (db *DB) conn(ctx context.Context, strategy connReuseStrategy) (*driverConn copy(db.freeConn, db.freeConn[1:]) db.freeConn = db.freeConn[:numFree-1] conn.inUse = true - db.mu.Unlock() if conn.expired(lifetime) { + db.maxLifetimeClosed++ + db.mu.Unlock() conn.Close() return nil, driver.ErrBadConn } + db.mu.Unlock() // Reset the session if required. if err := conn.resetSession(ctx); err == driver.ErrBadConn { @@ -1178,7 +1236,7 @@ func (db *DB) conn(ctx context.Context, strategy connReuseStrategy) (*driverConn db.waitCount++ db.mu.Unlock() - waitStart := time.Now() + waitStart := nowFunc() // Timeout the connection request with the context. select { @@ -1212,6 +1270,9 @@ func (db *DB) conn(ctx context.Context, strategy connReuseStrategy) (*driverConn // This prioritizes giving a valid connection to a client over the exact connection // lifetime, which could expire exactly after this point anyway. if strategy == cachedOrNewConn && ret.err == nil && ret.conn.expired(lifetime) { + db.mu.Lock() + db.maxLifetimeClosed++ + db.mu.Unlock() ret.conn.Close() return nil, driver.ErrBadConn } @@ -1240,10 +1301,11 @@ func (db *DB) conn(ctx context.Context, strategy connReuseStrategy) (*driverConn } db.mu.Lock() dc := &driverConn{ - db: db, - createdAt: nowFunc(), - ci: ci, - inUse: true, + db: db, + createdAt: nowFunc(), + returnedAt: nowFunc(), + ci: ci, + inUse: true, } db.addDepLocked(dc, dc) db.mu.Unlock() @@ -1295,12 +1357,14 @@ func (db *DB) putConn(dc *driverConn, err error, resetSession bool) { } if err != driver.ErrBadConn && dc.expired(db.maxLifetime) { + db.maxLifetimeClosed++ err = driver.ErrBadConn } if debugGetPut { db.lastPut[dc] = stack() } dc.inUse = false + dc.returnedAt = nowFunc() for _, fn := range dc.onPut { fn() @@ -1691,7 +1755,7 @@ func (db *DB) beginDC(ctx context.Context, dc *driverConn, release func(error), keepConnOnRollback := false withLock(dc, func() { _, hasSessionResetter := dc.ci.(driver.SessionResetter) - _, hasConnectionValidator := dc.ci.(validator) + _, hasConnectionValidator := dc.ci.(driver.Validator) keepConnOnRollback = hasSessionResetter && hasConnectionValidator txi, err = ctxDriverBegin(ctx, opts, dc.ci) }) @@ -2729,10 +2793,17 @@ func (rs *Rows) lasterrOrErrLocked(err error) error { return err } +// bypassRowsAwaitDone is only used for testing. +// If true, it will not close the Rows automatically from the context. +var bypassRowsAwaitDone = false + func (rs *Rows) initContextClose(ctx, txctx context.Context) { if ctx.Done() == nil && (txctx == nil || txctx.Done() == nil) { return } + if bypassRowsAwaitDone { + return + } ctx, rs.cancel = context.WithCancel(ctx) go rs.awaitDone(ctx, txctx) } @@ -2942,10 +3013,11 @@ func (ci *ColumnType) Nullable() (nullable, ok bool) { } // DatabaseTypeName returns the database system name of the column type. If an empty -// string is returned the driver type name is not supported. +// string is returned, then the driver type name is not supported. // Consult your driver documentation for a list of driver data types. Length specifiers // are not included. -// Common type include "VARCHAR", "TEXT", "NVARCHAR", "DECIMAL", "BOOL", "INT", "BIGINT". +// Common type names include "VARCHAR", "TEXT", "NVARCHAR", "DECIMAL", "BOOL", +// "INT", and "BIGINT". func (ci *ColumnType) DatabaseTypeName() string { return ci.databaseType } @@ -3160,6 +3232,14 @@ func (r *Row) Scan(dest ...interface{}) error { return r.rows.Close() } +// Err provides a way for wrapping packages to check for +// query errors without calling Scan. +// Err returns the error, if any, that was encountered while running the query. +// If this error is not nil, this error will also be returned from Scan. +func (r *Row) Err() error { + return r.err +} + // A Result summarizes an executed SQL command. type Result interface { // LastInsertId returns the integer generated by the database diff --git a/libgo/go/database/sql/sql_test.go b/libgo/go/database/sql/sql_test.go index a9e18004fb4..5727f0d8aa6 100644 --- a/libgo/go/database/sql/sql_test.go +++ b/libgo/go/database/sql/sql_test.go @@ -823,6 +823,24 @@ func TestQueryRow(t *testing.T) { } } +func TestRowErr(t *testing.T) { + db := newTestDB(t, "people") + + err := db.QueryRowContext(context.Background(), "SELECT|people|bdate|age=?", 3).Err() + if err != nil { + t.Errorf("Unexpected err = %v; want %v", err, nil) + } + + ctx, cancel := context.WithCancel(context.Background()) + cancel() + + err = db.QueryRowContext(ctx, "SELECT|people|bdate|age=?", 3).Err() + exp := "context canceled" + if err == nil || !strings.Contains(err.Error(), exp) { + t.Errorf("Expected err = %v; got %v", exp, err) + } +} + func TestTxRollbackCommitErr(t *testing.T) { db := newTestDB(t, "people") defer closeDB(t, db) @@ -2724,7 +2742,7 @@ func TestManyErrBadConn(t *testing.T) { } } -// Issue 34755: Ensure that a Tx cannot commit after a rollback. +// Issue 34775: Ensure that a Tx cannot commit after a rollback. func TestTxCannotCommitAfterRollback(t *testing.T) { db := newTestDB(t, "tx_status") defer closeDB(t, db) @@ -2766,6 +2784,9 @@ func TestTxCannotCommitAfterRollback(t *testing.T) { // 2. (A) Start a query, (B) begin Tx rollback through a ctx cancel. // 3. Check if 2.A has committed in Tx (pass) or outside of Tx (fail). sendQuery := make(chan struct{}) + // The Tx status is returned through the row results, ensure + // that the rows results are not cancelled. + bypassRowsAwaitDone = true hookTxGrabConn = func() { cancel() <-sendQuery @@ -2776,6 +2797,7 @@ func TestTxCannotCommitAfterRollback(t *testing.T) { defer func() { hookTxGrabConn = nil rollbackHook = nil + bypassRowsAwaitDone = false }() err = tx.QueryRow("SELECT|tx_status|tx_status|").Scan(&txStatus) @@ -3812,6 +3834,61 @@ func TestStatsMaxIdleClosedTen(t *testing.T) { } } +func TestMaxIdleTime(t *testing.T) { + list := []struct { + wantMaxIdleTime time.Duration + wantIdleClosed int64 + timeOffset time.Duration + }{ + {time.Nanosecond, 1, 10 * time.Millisecond}, + {time.Hour, 0, 10 * time.Millisecond}, + } + baseTime := time.Unix(0, 0) + defer func() { + nowFunc = time.Now + }() + for _, item := range list { + nowFunc = func() time.Time { + return baseTime + } + t.Run(fmt.Sprintf("%v", item.wantMaxIdleTime), func(t *testing.T) { + db := newTestDB(t, "people") + defer closeDB(t, db) + + db.SetMaxOpenConns(1) + db.SetMaxIdleConns(1) + db.SetConnMaxIdleTime(item.wantMaxIdleTime) + db.SetConnMaxLifetime(0) + + preMaxIdleClosed := db.Stats().MaxIdleTimeClosed + + if err := db.Ping(); err != nil { + t.Fatal(err) + } + + nowFunc = func() time.Time { + return baseTime.Add(item.timeOffset) + } + + db.mu.Lock() + closing := db.connectionCleanerRunLocked() + db.mu.Unlock() + for _, c := range closing { + c.Close() + } + if g, w := int64(len(closing)), item.wantIdleClosed; g != w { + t.Errorf("got: %d; want %d closed conns", g, w) + } + + st := db.Stats() + maxIdleClosed := st.MaxIdleTimeClosed - preMaxIdleClosed + if g, w := maxIdleClosed, item.wantIdleClosed; g != w { + t.Errorf(" got: %d; want %d max idle closed conns", g, w) + } + }) + } +} + type nvcDriver struct { fakeDriver skipNamedValueCheck bool diff --git a/libgo/go/debug/gosym/symtab.go b/libgo/go/debug/gosym/symtab.go index 3be612e1df7..00701c2875a 100644 --- a/libgo/go/debug/gosym/symtab.go +++ b/libgo/go/debug/gosym/symtab.go @@ -121,8 +121,8 @@ type Obj struct { type Table struct { Syms []Sym // nil for Go 1.3 and later binaries Funcs []Func - Files map[string]*Obj // nil for Go 1.2 and later binaries - Objs []Obj // nil for Go 1.2 and later binaries + Files map[string]*Obj // for Go 1.2 and later all files map to one Obj + Objs []Obj // for Go 1.2 and later only one Obj in slice go12line *LineTable // Go 1.2 line number table } diff --git a/libgo/go/debug/pe/file_test.go b/libgo/go/debug/pe/file_test.go index bc41be26691..d96cd30904e 100644 --- a/libgo/go/debug/pe/file_test.go +++ b/libgo/go/debug/pe/file_test.go @@ -451,7 +451,7 @@ func testDWARF(t *testing.T, linktype int) { } offset := uintptr(addr) - imageBase if offset != uintptr(wantoffset) { - t.Fatal("Runtime offset (0x%x) did "+ + t.Fatalf("Runtime offset (0x%x) did "+ "not match dwarf offset "+ "(0x%x)", wantoffset, offset) } @@ -621,16 +621,14 @@ func TestBuildingWindowsGUI(t *testing.T) { } defer f.Close() - const _IMAGE_SUBSYSTEM_WINDOWS_GUI = 2 - switch oh := f.OptionalHeader.(type) { case *OptionalHeader32: - if oh.Subsystem != _IMAGE_SUBSYSTEM_WINDOWS_GUI { - t.Errorf("unexpected Subsystem value: have %d, but want %d", oh.Subsystem, _IMAGE_SUBSYSTEM_WINDOWS_GUI) + if oh.Subsystem != IMAGE_SUBSYSTEM_WINDOWS_GUI { + t.Errorf("unexpected Subsystem value: have %d, but want %d", oh.Subsystem, IMAGE_SUBSYSTEM_WINDOWS_GUI) } case *OptionalHeader64: - if oh.Subsystem != _IMAGE_SUBSYSTEM_WINDOWS_GUI { - t.Errorf("unexpected Subsystem value: have %d, but want %d", oh.Subsystem, _IMAGE_SUBSYSTEM_WINDOWS_GUI) + if oh.Subsystem != IMAGE_SUBSYSTEM_WINDOWS_GUI { + t.Errorf("unexpected Subsystem value: have %d, but want %d", oh.Subsystem, IMAGE_SUBSYSTEM_WINDOWS_GUI) } default: t.Fatalf("unexpected OptionalHeader type: have %T, but want *pe.OptionalHeader32 or *pe.OptionalHeader64", oh) diff --git a/libgo/go/debug/pe/pe.go b/libgo/go/debug/pe/pe.go index 3f8099dfab1..db112fe7ad6 100644 --- a/libgo/go/debug/pe/pe.go +++ b/libgo/go/debug/pe/pe.go @@ -129,3 +129,56 @@ const ( IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT = 13 IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR = 14 ) + +// Values of IMAGE_FILE_HEADER.Characteristics. These can be combined together. +const ( + IMAGE_FILE_RELOCS_STRIPPED = 0x0001 + IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002 + IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004 + IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008 + IMAGE_FILE_AGGRESIVE_WS_TRIM = 0x0010 + IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020 + IMAGE_FILE_BYTES_REVERSED_LO = 0x0080 + IMAGE_FILE_32BIT_MACHINE = 0x0100 + IMAGE_FILE_DEBUG_STRIPPED = 0x0200 + IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400 + IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800 + IMAGE_FILE_SYSTEM = 0x1000 + IMAGE_FILE_DLL = 0x2000 + IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000 + IMAGE_FILE_BYTES_REVERSED_HI = 0x8000 +) + +// OptionalHeader64.Subsystem and OptionalHeader32.Subsystem values. +const ( + IMAGE_SUBSYSTEM_UNKNOWN = 0 + IMAGE_SUBSYSTEM_NATIVE = 1 + IMAGE_SUBSYSTEM_WINDOWS_GUI = 2 + IMAGE_SUBSYSTEM_WINDOWS_CUI = 3 + IMAGE_SUBSYSTEM_OS2_CUI = 5 + IMAGE_SUBSYSTEM_POSIX_CUI = 7 + IMAGE_SUBSYSTEM_NATIVE_WINDOWS = 8 + IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9 + IMAGE_SUBSYSTEM_EFI_APPLICATION = 10 + IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11 + IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12 + IMAGE_SUBSYSTEM_EFI_ROM = 13 + IMAGE_SUBSYSTEM_XBOX = 14 + IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16 +) + +// OptionalHeader64.DllCharacteristics and OptionalHeader32.DllCharacteristics +// values. These can be combined together. +const ( + IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020 + IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040 + IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY = 0x0080 + IMAGE_DLLCHARACTERISTICS_NX_COMPAT = 0x0100 + IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200 + IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400 + IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800 + IMAGE_DLLCHARACTERISTICS_APPCONTAINER = 0x1000 + IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000 + IMAGE_DLLCHARACTERISTICS_GUARD_CF = 0x4000 + IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000 +) diff --git a/libgo/go/encoding/asn1/asn1.go b/libgo/go/encoding/asn1/asn1.go index fd4dd68021b..d809dde2781 100644 --- a/libgo/go/encoding/asn1/asn1.go +++ b/libgo/go/encoding/asn1/asn1.go @@ -313,6 +313,12 @@ func parseBase128Int(bytes []byte, initOffset int) (ret, offset int, err error) } ret64 <<= 7 b := bytes[offset] + // integers should be minimally encoded, so the leading octet should + // never be 0x80 + if shifted == 0 && b == 0x80 { + err = SyntaxError{"integer is not minimally encoded"} + return + } ret64 |= int64(b & 0x7f) offset++ if b&0x80 == 0 { @@ -1031,6 +1037,12 @@ func setDefaultValue(v reflect.Value, params fieldParameters) (ok bool) { // Because Unmarshal uses the reflect package, the structs // being written to must use upper case field names. // +// After parsing b, any bytes that were leftover and not used to fill +// val will be returned in rest. When parsing a SEQUENCE into a struct, +// any trailing elements of the SEQUENCE that do not have matching +// fields in val will not be included in rest, as these are considered +// valid elements of the SEQUENCE and not trailing data. +// // An ASN.1 INTEGER can be written to an int, int32, int64, // or *big.Int (from the math/big package). // If the encoded value does not fit in the Go type, diff --git a/libgo/go/encoding/asn1/asn1_test.go b/libgo/go/encoding/asn1/asn1_test.go index d5649bff9fa..8daae97faad 100644 --- a/libgo/go/encoding/asn1/asn1_test.go +++ b/libgo/go/encoding/asn1/asn1_test.go @@ -1129,3 +1129,15 @@ func TestBMPString(t *testing.T) { } } } + +func TestNonMinimalEncodedOID(t *testing.T) { + h, err := hex.DecodeString("060a2a80864886f70d01010b") + if err != nil { + t.Fatalf("failed to decode from hex string: %s", err) + } + var oid ObjectIdentifier + _, err = Unmarshal(h, &oid) + if err == nil { + t.Fatalf("accepted non-minimally encoded oid") + } +} diff --git a/libgo/go/encoding/asn1/marshal.go b/libgo/go/encoding/asn1/marshal.go index c9ae2ca33e5..0d34d5aa1e8 100644 --- a/libgo/go/encoding/asn1/marshal.go +++ b/libgo/go/encoding/asn1/marshal.go @@ -5,10 +5,12 @@ package asn1 import ( + "bytes" "errors" "fmt" "math/big" "reflect" + "sort" "time" "unicode/utf8" ) @@ -78,6 +80,48 @@ func (m multiEncoder) Encode(dst []byte) { } } +type setEncoder []encoder + +func (s setEncoder) Len() int { + var size int + for _, e := range s { + size += e.Len() + } + return size +} + +func (s setEncoder) Encode(dst []byte) { + // Per X690 Section 11.6: The encodings of the component values of a + // set-of value shall appear in ascending order, the encodings being + // compared as octet strings with the shorter components being padded + // at their trailing end with 0-octets. + // + // First we encode each element to its TLV encoding and then use + // octetSort to get the ordering expected by X690 DER rules before + // writing the sorted encodings out to dst. + l := make([][]byte, len(s)) + for i, e := range s { + l[i] = make([]byte, e.Len()) + e.Encode(l[i]) + } + + sort.Slice(l, func(i, j int) bool { + // Since we are using bytes.Compare to compare TLV encodings we + // don't need to right pad s[i] and s[j] to the same length as + // suggested in X690. If len(s[i]) < len(s[j]) the length octet of + // s[i], which is the first determining byte, will inherently be + // smaller than the length octet of s[j]. This lets us skip the + // padding step. + return bytes.Compare(l[i], l[j]) < 0 + }) + + var off int + for _, b := range l { + copy(dst[off:], b) + off += len(b) + } +} + type taggedEncoder struct { // scratch contains temporary space for encoding the tag and length of // an element in order to avoid extra allocations. @@ -511,6 +555,9 @@ func makeBody(value reflect.Value, params fieldParameters) (e encoder, err error } } + if params.set { + return setEncoder(m), nil + } return multiEncoder(m), nil } case reflect.String: @@ -618,6 +665,15 @@ func makeField(v reflect.Value, params fieldParameters) (e encoder, err error) { tag = TagSet } + // makeField can be called for a slice that should be treated as a SET + // but doesn't have params.set set, for instance when using a slice + // with the SET type name suffix. In this case getUniversalType returns + // TagSet, but makeBody doesn't know about that so will treat the slice + // as a sequence. To work around this we set params.set. + if tag == TagSet && !params.set { + params.set = true + } + t := new(taggedEncoder) t.body, err = makeBody(v, params) diff --git a/libgo/go/encoding/asn1/marshal_test.go b/libgo/go/encoding/asn1/marshal_test.go index a77826a7b03..529052285f5 100644 --- a/libgo/go/encoding/asn1/marshal_test.go +++ b/libgo/go/encoding/asn1/marshal_test.go @@ -319,3 +319,60 @@ func BenchmarkMarshal(b *testing.B) { } } } + +func TestSetEncoder(t *testing.T) { + testStruct := struct { + Strings []string `asn1:"set"` + }{ + Strings: []string{"a", "aa", "b", "bb", "c", "cc"}, + } + + // Expected ordering of the SET should be: + // a, b, c, aa, bb, cc + + output, err := Marshal(testStruct) + if err != nil { + t.Errorf("%v", err) + } + + expectedOrder := []string{"a", "b", "c", "aa", "bb", "cc"} + var resultStruct struct { + Strings []string `asn1:"set"` + } + rest, err := Unmarshal(output, &resultStruct) + if err != nil { + t.Errorf("%v", err) + } + if len(rest) != 0 { + t.Error("Unmarshal returned extra garbage") + } + if !reflect.DeepEqual(expectedOrder, resultStruct.Strings) { + t.Errorf("Unexpected SET content. got: %s, want: %s", resultStruct.Strings, expectedOrder) + } +} + +func TestSetEncoderSETSliceSuffix(t *testing.T) { + type testSetSET []string + testSet := testSetSET{"a", "aa", "b", "bb", "c", "cc"} + + // Expected ordering of the SET should be: + // a, b, c, aa, bb, cc + + output, err := Marshal(testSet) + if err != nil { + t.Errorf("%v", err) + } + + expectedOrder := testSetSET{"a", "b", "c", "aa", "bb", "cc"} + var resultSet testSetSET + rest, err := Unmarshal(output, &resultSet) + if err != nil { + t.Errorf("%v", err) + } + if len(rest) != 0 { + t.Error("Unmarshal returned extra garbage") + } + if !reflect.DeepEqual(expectedOrder, resultSet) { + t.Errorf("Unexpected SET content. got: %s, want: %s", resultSet, expectedOrder) + } +} diff --git a/libgo/go/encoding/base64/base64.go b/libgo/go/encoding/base64/base64.go index 690d3ce0421..0c33f8e5f84 100644 --- a/libgo/go/encoding/base64/base64.go +++ b/libgo/go/encoding/base64/base64.go @@ -480,15 +480,16 @@ func (enc *Encoding) Decode(dst, src []byte) (n int, err error) { si := 0 for strconv.IntSize >= 64 && len(src)-si >= 8 && len(dst)-n >= 8 { + src2 := src[si : si+8] if dn, ok := assemble64( - enc.decodeMap[src[si+0]], - enc.decodeMap[src[si+1]], - enc.decodeMap[src[si+2]], - enc.decodeMap[src[si+3]], - enc.decodeMap[src[si+4]], - enc.decodeMap[src[si+5]], - enc.decodeMap[src[si+6]], - enc.decodeMap[src[si+7]], + enc.decodeMap[src2[0]], + enc.decodeMap[src2[1]], + enc.decodeMap[src2[2]], + enc.decodeMap[src2[3]], + enc.decodeMap[src2[4]], + enc.decodeMap[src2[5]], + enc.decodeMap[src2[6]], + enc.decodeMap[src2[7]], ); ok { binary.BigEndian.PutUint64(dst[n:], dn) n += 6 @@ -504,11 +505,12 @@ func (enc *Encoding) Decode(dst, src []byte) (n int, err error) { } for len(src)-si >= 4 && len(dst)-n >= 4 { + src2 := src[si : si+4] if dn, ok := assemble32( - enc.decodeMap[src[si+0]], - enc.decodeMap[src[si+1]], - enc.decodeMap[src[si+2]], - enc.decodeMap[src[si+3]], + enc.decodeMap[src2[0]], + enc.decodeMap[src2[1]], + enc.decodeMap[src2[2]], + enc.decodeMap[src2[3]], ); ok { binary.BigEndian.PutUint32(dst[n:], dn) n += 3 diff --git a/libgo/go/encoding/base64/base64_test.go b/libgo/go/encoding/base64/base64_test.go index bc67036f5bc..c2c9478a437 100644 --- a/libgo/go/encoding/base64/base64_test.go +++ b/libgo/go/encoding/base64/base64_test.go @@ -401,7 +401,7 @@ func TestDecoderIssue3577(t *testing.T) { source: "VHdhcyBicmlsbGlnLCBhbmQgdGhlIHNsaXRoeSB0b3Zlcw==", // twas brillig... nextc: next, }) - errc := make(chan error) + errc := make(chan error, 1) go func() { _, err := ioutil.ReadAll(d) errc <- err diff --git a/libgo/go/encoding/csv/writer.go b/libgo/go/encoding/csv/writer.go index 3f34bc51dbf..ac64b4d54c8 100644 --- a/libgo/go/encoding/csv/writer.go +++ b/libgo/go/encoding/csv/writer.go @@ -158,10 +158,24 @@ func (w *Writer) fieldNeedsQuotes(field string) bool { if field == "" { return false } - if field == `\.` || strings.ContainsRune(field, w.Comma) || strings.ContainsAny(field, "\"\r\n") { + + if field == `\.` { return true } + if w.Comma < utf8.RuneSelf { + for i := 0; i < len(field); i++ { + c := field[i] + if c == '\n' || c == '\r' || c == '"' || c == byte(w.Comma) { + return true + } + } + } else { + if strings.ContainsRune(field, w.Comma) || strings.ContainsAny(field, "\"\r\n") { + return true + } + } + r1, _ := utf8.DecodeRuneInString(field) return unicode.IsSpace(r1) } diff --git a/libgo/go/encoding/csv/writer_test.go b/libgo/go/encoding/csv/writer_test.go index 011f01c172a..ab28b0d7c35 100644 --- a/libgo/go/encoding/csv/writer_test.go +++ b/libgo/go/encoding/csv/writer_test.go @@ -93,3 +93,20 @@ func TestError(t *testing.T) { t.Error("Error should not be nil") } } + +var benchmarkWriteData = [][]string{ + {"abc", "def", "12356", "1234567890987654311234432141542132"}, + {"abc", "def", "12356", "1234567890987654311234432141542132"}, + {"abc", "def", "12356", "1234567890987654311234432141542132"}, +} + +func BenchmarkWrite(b *testing.B) { + for i := 0; i < b.N; i++ { + w := NewWriter(&bytes.Buffer{}) + err := w.WriteAll(benchmarkWriteData) + if err != nil { + b.Fatal(err) + } + w.Flush() + } +} diff --git a/libgo/go/encoding/hex/hex_test.go b/libgo/go/encoding/hex/hex_test.go index dbb00b94cac..31e3f689365 100644 --- a/libgo/go/encoding/hex/hex_test.go +++ b/libgo/go/encoding/hex/hex_test.go @@ -267,7 +267,6 @@ func BenchmarkDecode(b *testing.B) { func BenchmarkDump(b *testing.B) { for _, size := range []int{256, 1024, 4096, 16384} { src := bytes.Repeat([]byte{2, 3, 5, 7, 9, 11, 13, 17}, size/8) - sink = make([]byte, 2*size) b.Run(fmt.Sprintf("%v", size), func(b *testing.B) { b.SetBytes(int64(size)) diff --git a/libgo/go/encoding/json/decode_test.go b/libgo/go/encoding/json/decode_test.go index 689cc34c243..219e845c7b0 100644 --- a/libgo/go/encoding/json/decode_test.go +++ b/libgo/go/encoding/json/decode_test.go @@ -2476,3 +2476,99 @@ func TestUnmarshalRescanLiteralMangledUnquote(t *testing.T) { t.Fatalf("Unexpected roundtrip result:\nwant: %q\ngot: %q", want, got) } } + +func TestUnmarshalMaxDepth(t *testing.T) { + testcases := []struct { + name string + data string + errMaxDepth bool + }{ + { + name: "ArrayUnderMaxNestingDepth", + data: `{"a":` + strings.Repeat(`[`, 10000-1) + strings.Repeat(`]`, 10000-1) + `}`, + errMaxDepth: false, + }, + { + name: "ArrayOverMaxNestingDepth", + data: `{"a":` + strings.Repeat(`[`, 10000) + strings.Repeat(`]`, 10000) + `}`, + errMaxDepth: true, + }, + { + name: "ArrayOverStackDepth", + data: `{"a":` + strings.Repeat(`[`, 3000000) + strings.Repeat(`]`, 3000000) + `}`, + errMaxDepth: true, + }, + { + name: "ObjectUnderMaxNestingDepth", + data: `{"a":` + strings.Repeat(`{"a":`, 10000-1) + `0` + strings.Repeat(`}`, 10000-1) + `}`, + errMaxDepth: false, + }, + { + name: "ObjectOverMaxNestingDepth", + data: `{"a":` + strings.Repeat(`{"a":`, 10000) + `0` + strings.Repeat(`}`, 10000) + `}`, + errMaxDepth: true, + }, + { + name: "ObjectOverStackDepth", + data: `{"a":` + strings.Repeat(`{"a":`, 3000000) + `0` + strings.Repeat(`}`, 3000000) + `}`, + errMaxDepth: true, + }, + } + + targets := []struct { + name string + newValue func() interface{} + }{ + { + name: "unstructured", + newValue: func() interface{} { + var v interface{} + return &v + }, + }, + { + name: "typed named field", + newValue: func() interface{} { + v := struct { + A interface{} `json:"a"` + }{} + return &v + }, + }, + { + name: "typed missing field", + newValue: func() interface{} { + v := struct { + B interface{} `json:"b"` + }{} + return &v + }, + }, + { + name: "custom unmarshaler", + newValue: func() interface{} { + v := unmarshaler{} + return &v + }, + }, + } + + for _, tc := range testcases { + for _, target := range targets { + t.Run(target.name+"-"+tc.name, func(t *testing.T) { + err := Unmarshal([]byte(tc.data), target.newValue()) + if !tc.errMaxDepth { + if err != nil { + t.Errorf("unexpected error: %v", err) + } + } else { + if err == nil { + t.Errorf("expected error containing 'exceeded max depth', got none") + } else if !strings.Contains(err.Error(), "exceeded max depth") { + t.Errorf("expected error containing 'exceeded max depth', got: %v", err) + } + } + }) + } + } +} diff --git a/libgo/go/encoding/json/encode.go b/libgo/go/encoding/json/encode.go index b351cf3f449..578d551102d 100644 --- a/libgo/go/encoding/json/encode.go +++ b/libgo/go/encoding/json/encode.go @@ -650,7 +650,7 @@ func stringEncoder(e *encodeState, v reflect.Value, opts encOpts) { func isValidNumber(s string) bool { // This function implements the JSON numbers grammar. // See https://tools.ietf.org/html/rfc7159#section-6 - // and https://json.org/number.gif + // and https://www.json.org/img/number.png if s == "" { return false diff --git a/libgo/go/encoding/json/scanner.go b/libgo/go/encoding/json/scanner.go index 552bd703604..9dc1903e2db 100644 --- a/libgo/go/encoding/json/scanner.go +++ b/libgo/go/encoding/json/scanner.go @@ -139,6 +139,10 @@ const ( parseArrayValue // parsing array value ) +// This limits the max nesting depth to prevent stack overflow. +// This is permitted by https://tools.ietf.org/html/rfc7159#section-9 +const maxNestingDepth = 10000 + // reset prepares the scanner for use. // It must be called before calling s.step. func (s *scanner) reset() { @@ -168,8 +172,13 @@ func (s *scanner) eof() int { } // pushParseState pushes a new parse state p onto the parse stack. -func (s *scanner) pushParseState(p int) { - s.parseState = append(s.parseState, p) +// an error state is returned if maxNestingDepth was exceeded, otherwise successState is returned. +func (s *scanner) pushParseState(c byte, newParseState int, successState int) int { + s.parseState = append(s.parseState, newParseState) + if len(s.parseState) <= maxNestingDepth { + return successState + } + return s.error(c, "exceeded max depth") } // popParseState pops a parse state (already obtained) off the stack @@ -186,12 +195,12 @@ func (s *scanner) popParseState() { } func isSpace(c byte) bool { - return c == ' ' || c == '\t' || c == '\r' || c == '\n' + return c <= ' ' && (c == ' ' || c == '\t' || c == '\r' || c == '\n') } // stateBeginValueOrEmpty is the state after reading `[`. func stateBeginValueOrEmpty(s *scanner, c byte) int { - if c <= ' ' && isSpace(c) { + if isSpace(c) { return scanSkipSpace } if c == ']' { @@ -202,18 +211,16 @@ func stateBeginValueOrEmpty(s *scanner, c byte) int { // stateBeginValue is the state at the beginning of the input. func stateBeginValue(s *scanner, c byte) int { - if c <= ' ' && isSpace(c) { + if isSpace(c) { return scanSkipSpace } switch c { case '{': s.step = stateBeginStringOrEmpty - s.pushParseState(parseObjectKey) - return scanBeginObject + return s.pushParseState(c, parseObjectKey, scanBeginObject) case '[': s.step = stateBeginValueOrEmpty - s.pushParseState(parseArrayValue) - return scanBeginArray + return s.pushParseState(c, parseArrayValue, scanBeginArray) case '"': s.step = stateInString return scanBeginLiteral @@ -242,7 +249,7 @@ func stateBeginValue(s *scanner, c byte) int { // stateBeginStringOrEmpty is the state after reading `{`. func stateBeginStringOrEmpty(s *scanner, c byte) int { - if c <= ' ' && isSpace(c) { + if isSpace(c) { return scanSkipSpace } if c == '}' { @@ -255,7 +262,7 @@ func stateBeginStringOrEmpty(s *scanner, c byte) int { // stateBeginString is the state after reading `{"key": value,`. func stateBeginString(s *scanner, c byte) int { - if c <= ' ' && isSpace(c) { + if isSpace(c) { return scanSkipSpace } if c == '"' { @@ -275,7 +282,7 @@ func stateEndValue(s *scanner, c byte) int { s.endTop = true return stateEndTop(s, c) } - if c <= ' ' && isSpace(c) { + if isSpace(c) { s.step = stateEndValue return scanSkipSpace } diff --git a/libgo/go/encoding/xml/marshal.go b/libgo/go/encoding/xml/marshal.go index e325f313743..0554b0d204e 100644 --- a/libgo/go/encoding/xml/marshal.go +++ b/libgo/go/encoding/xml/marshal.go @@ -479,8 +479,11 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat xmlname := tinfo.xmlname if xmlname.name != "" { start.Name.Space, start.Name.Local = xmlname.xmlns, xmlname.name - } else if v, ok := xmlname.value(val).Interface().(Name); ok && v.Local != "" { - start.Name = v + } else { + fv := xmlname.value(val, dontInitNilPointers) + if v, ok := fv.Interface().(Name); ok && v.Local != "" { + start.Name = v + } } } if start.Name.Local == "" && finfo != nil { @@ -500,7 +503,7 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat if finfo.flags&fAttr == 0 { continue } - fv := finfo.value(val) + fv := finfo.value(val, dontInitNilPointers) if finfo.flags&fOmitEmpty != 0 && isEmptyValue(fv) { continue @@ -803,7 +806,12 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error { if finfo.flags&fAttr != 0 { continue } - vf := finfo.value(val) + vf := finfo.value(val, dontInitNilPointers) + if !vf.IsValid() { + // The field is behind an anonymous struct field that's + // nil. Skip it. + continue + } switch finfo.flags & fMode { case fCDATA, fCharData: diff --git a/libgo/go/encoding/xml/marshal_test.go b/libgo/go/encoding/xml/marshal_test.go index 8473158bcd0..31309ef2ca8 100644 --- a/libgo/go/encoding/xml/marshal_test.go +++ b/libgo/go/encoding/xml/marshal_test.go @@ -309,6 +309,11 @@ type ChardataEmptyTest struct { Contents *string `xml:",chardata"` } +type PointerAnonFields struct { + *MyInt + *NamedType +} + type MyMarshalerTest struct { } @@ -889,6 +894,18 @@ var marshalTests = []struct { ``, }, + // Anonymous struct pointer field which is nil + { + Value: &EmbedB{}, + ExpectXML: ``, + }, + + // Other kinds of nil anonymous fields + { + Value: &PointerAnonFields{}, + ExpectXML: ``, + }, + // Test that name casing matters { Value: &NameCasing{Xy: "mixed", XY: "upper", XyA: "mixedA", XYA: "upperA"}, diff --git a/libgo/go/encoding/xml/read.go b/libgo/go/encoding/xml/read.go index 10a60eed1a9..ef5df3f7f6a 100644 --- a/libgo/go/encoding/xml/read.go +++ b/libgo/go/encoding/xml/read.go @@ -435,7 +435,7 @@ func (d *Decoder) unmarshal(val reflect.Value, start *StartElement) error { } return UnmarshalError(e) } - fv := finfo.value(sv) + fv := finfo.value(sv, initNilPointers) if _, ok := fv.Interface().(Name); ok { fv.Set(reflect.ValueOf(start.Name)) } @@ -449,7 +449,7 @@ func (d *Decoder) unmarshal(val reflect.Value, start *StartElement) error { finfo := &tinfo.fields[i] switch finfo.flags & fMode { case fAttr: - strv := finfo.value(sv) + strv := finfo.value(sv, initNilPointers) if a.Name.Local == finfo.name && (finfo.xmlns == "" || finfo.xmlns == a.Name.Space) { if err := d.unmarshalAttr(strv, a); err != nil { return err @@ -465,7 +465,7 @@ func (d *Decoder) unmarshal(val reflect.Value, start *StartElement) error { } if !handled && any >= 0 { finfo := &tinfo.fields[any] - strv := finfo.value(sv) + strv := finfo.value(sv, initNilPointers) if err := d.unmarshalAttr(strv, a); err != nil { return err } @@ -478,22 +478,22 @@ func (d *Decoder) unmarshal(val reflect.Value, start *StartElement) error { switch finfo.flags & fMode { case fCDATA, fCharData: if !saveData.IsValid() { - saveData = finfo.value(sv) + saveData = finfo.value(sv, initNilPointers) } case fComment: if !saveComment.IsValid() { - saveComment = finfo.value(sv) + saveComment = finfo.value(sv, initNilPointers) } case fAny, fAny | fElement: if !saveAny.IsValid() { - saveAny = finfo.value(sv) + saveAny = finfo.value(sv, initNilPointers) } case fInnerXML: if !saveXML.IsValid() { - saveXML = finfo.value(sv) + saveXML = finfo.value(sv, initNilPointers) if d.saved == nil { saveXMLIndex = 0 d.saved = new(bytes.Buffer) @@ -687,7 +687,7 @@ Loop: } if len(finfo.parents) == len(parents) && finfo.name == start.Name.Local { // It's a perfect match, unmarshal the field. - return true, d.unmarshal(finfo.value(sv), start) + return true, d.unmarshal(finfo.value(sv, initNilPointers), start) } if len(finfo.parents) > len(parents) && finfo.parents[len(parents)] == start.Name.Local { // It's a prefix for the field. Break and recurse diff --git a/libgo/go/encoding/xml/typeinfo.go b/libgo/go/encoding/xml/typeinfo.go index 639952c74ad..f30fe58590b 100644 --- a/libgo/go/encoding/xml/typeinfo.go +++ b/libgo/go/encoding/xml/typeinfo.go @@ -344,15 +344,25 @@ func (e *TagPathError) Error() string { return fmt.Sprintf("%s field %q with tag %q conflicts with field %q with tag %q", e.Struct, e.Field1, e.Tag1, e.Field2, e.Tag2) } +const ( + initNilPointers = true + dontInitNilPointers = false +) + // value returns v's field value corresponding to finfo. -// It's equivalent to v.FieldByIndex(finfo.idx), but initializes -// and dereferences pointers as necessary. -func (finfo *fieldInfo) value(v reflect.Value) reflect.Value { +// It's equivalent to v.FieldByIndex(finfo.idx), but when passed +// initNilPointers, it initializes and dereferences pointers as necessary. +// When passed dontInitNilPointers and a nil pointer is reached, the function +// returns a zero reflect.Value. +func (finfo *fieldInfo) value(v reflect.Value, shouldInitNilPointers bool) reflect.Value { for i, x := range finfo.idx { if i > 0 { t := v.Type() if t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct { if v.IsNil() { + if !shouldInitNilPointers { + return reflect.Value{} + } v.Set(reflect.New(v.Type().Elem())) } v = v.Elem() diff --git a/libgo/go/encoding/xml/xml.go b/libgo/go/encoding/xml/xml.go index 5e73dcf7316..adaf4daf198 100644 --- a/libgo/go/encoding/xml/xml.go +++ b/libgo/go/encoding/xml/xml.go @@ -960,7 +960,7 @@ func (d *Decoder) ungetc(b byte) { d.offset-- } -var entity = map[string]int{ +var entity = map[string]rune{ "lt": '<', "gt": '>', "amp": '&', @@ -1055,7 +1055,7 @@ Input: d.buf.WriteByte(';') n, err := strconv.ParseUint(s, base, 64) if err == nil && n <= unicode.MaxRune { - text = string(n) + text = string(rune(n)) haveText = true } } diff --git a/libgo/go/errors/wrap.go b/libgo/go/errors/wrap.go index 272d056b318..b82ca34b46f 100644 --- a/libgo/go/errors/wrap.go +++ b/libgo/go/errors/wrap.go @@ -70,7 +70,7 @@ func Is(err, target error) bool { // setting target. // // An error type might provide an As method so it can be treated as if it were a -// a different error type. +// different error type. // // As panics if target is not a non-nil pointer to either a type that implements // error, or to any interface type. diff --git a/libgo/go/errors/wrap_test.go b/libgo/go/errors/wrap_test.go index 590c1857e37..4a4a732c9be 100644 --- a/libgo/go/errors/wrap_test.go +++ b/libgo/go/errors/wrap_test.go @@ -238,6 +238,19 @@ func (errorUncomparable) Is(target error) bool { return ok } +func ExampleIs() { + if _, err := os.Open("non-existing"); err != nil { + if errors.Is(err, os.ErrNotExist) { + fmt.Println("file does not exist") + } else { + fmt.Println(err) + } + } + + // Output: + // file does not exist +} + func ExampleAs() { if _, err := os.Open("non-existing"); err != nil { var pathError *os.PathError diff --git a/libgo/go/expvar/expvar_test.go b/libgo/go/expvar/expvar_test.go index 7b1f83a7d77..69b0a76058f 100644 --- a/libgo/go/expvar/expvar_test.go +++ b/libgo/go/expvar/expvar_test.go @@ -489,12 +489,13 @@ func BenchmarkRealworldExpvarUsage(b *testing.B) { b.Fatalf("Listen failed: %v", err) } defer ln.Close() - done := make(chan bool) + done := make(chan bool, 1) go func() { for p := 0; p < P; p++ { s, err := ln.Accept() if err != nil { b.Errorf("Accept failed: %v", err) + done <- false return } servers[p] = s @@ -504,11 +505,14 @@ func BenchmarkRealworldExpvarUsage(b *testing.B) { for p := 0; p < P; p++ { c, err := net.Dial("tcp", ln.Addr().String()) if err != nil { + <-done b.Fatalf("Dial failed: %v", err) } clients[p] = c } - <-done + if !<-done { + b.FailNow() + } b.StartTimer() diff --git a/libgo/go/flag/flag.go b/libgo/go/flag/flag.go index 6a516175245..286bba68739 100644 --- a/libgo/go/flag/flag.go +++ b/libgo/go/flag/flag.go @@ -9,9 +9,9 @@ Define flags using flag.String(), Bool(), Int(), etc. - This declares an integer flag, -flagname, stored in the pointer ip, with type *int. + This declares an integer flag, -n, stored in the pointer nFlag, with type *int: import "flag" - var ip = flag.Int("flagname", 1234, "help message for flagname") + var nFlag = flag.Int("n", 1234, "help message for flag n") If you like, you can bind the flag to a variable using the Var() functions. var flagvar int func init() { @@ -308,7 +308,7 @@ type ErrorHandling int // These constants cause FlagSet.Parse to behave as described if the parse fails. const ( ContinueOnError ErrorHandling = iota // Return a descriptive error. - ExitOnError // Call os.Exit(2). + ExitOnError // Call os.Exit(2) or for -h/-help Exit(0). PanicOnError // Call panic with a descriptive error. ) @@ -331,7 +331,7 @@ type FlagSet struct { formal map[string]*Flag args []string // arguments after flags errorHandling ErrorHandling - output io.Writer // nil means stderr; use out() accessor + output io.Writer // nil means stderr; use Output() accessor } // A Flag represents the state of a flag. @@ -979,6 +979,9 @@ func (f *FlagSet) Parse(arguments []string) error { case ContinueOnError: return err case ExitOnError: + if err == ErrHelp { + os.Exit(0) + } os.Exit(2) case PanicOnError: panic(err) diff --git a/libgo/go/flag/flag_test.go b/libgo/go/flag/flag_test.go index 0d9491c0208..a01a5e4cea2 100644 --- a/libgo/go/flag/flag_test.go +++ b/libgo/go/flag/flag_test.go @@ -8,9 +8,12 @@ import ( "bytes" . "flag" "fmt" + "internal/testenv" "io" "io/ioutil" "os" + "os/exec" + "runtime" "sort" "strconv" "strings" @@ -544,3 +547,66 @@ func TestRangeError(t *testing.T) { } } } + +func TestExitCode(t *testing.T) { + testenv.MustHaveExec(t) + + magic := 123 + if os.Getenv("GO_CHILD_FLAG") != "" { + fs := NewFlagSet("test", ExitOnError) + if os.Getenv("GO_CHILD_FLAG_HANDLE") != "" { + var b bool + fs.BoolVar(&b, os.Getenv("GO_CHILD_FLAG_HANDLE"), false, "") + } + fs.Parse([]string{os.Getenv("GO_CHILD_FLAG")}) + os.Exit(magic) + } + + tests := []struct { + flag string + flagHandle string + expectExit int + }{ + { + flag: "-h", + expectExit: 0, + }, + { + flag: "-help", + expectExit: 0, + }, + { + flag: "-undefined", + expectExit: 2, + }, + { + flag: "-h", + flagHandle: "h", + expectExit: magic, + }, + { + flag: "-help", + flagHandle: "help", + expectExit: magic, + }, + } + + for _, test := range tests { + cmd := exec.Command(os.Args[0], "-test.run=TestExitCode") + cmd.Env = append( + os.Environ(), + "GO_CHILD_FLAG="+test.flag, + "GO_CHILD_FLAG_HANDLE="+test.flagHandle, + ) + cmd.Run() + got := cmd.ProcessState.ExitCode() + // ExitCode is either 0 or 1 on Plan 9. + if runtime.GOOS == "plan9" && test.expectExit != 0 { + test.expectExit = 1 + } + if got != test.expectExit { + t.Errorf("unexpected exit code for test case %+v \n: got %d, expect %d", + test, got, test.expectExit) + } + } +} diff --git a/libgo/go/fmt/fmt_test.go b/libgo/go/fmt/fmt_test.go index b9e3bc60f5b..550c196c703 100644 --- a/libgo/go/fmt/fmt_test.go +++ b/libgo/go/fmt/fmt_test.go @@ -236,10 +236,10 @@ var fmtTests = []struct { {"%#q", "\U0010ffff", "`􏿿`"}, {"%#+q", "\U0010ffff", "`􏿿`"}, // Runes that are not valid. - {"%q", string(0x110000), `"�"`}, - {"%+q", string(0x110000), `"\ufffd"`}, - {"%#q", string(0x110000), "`�`"}, - {"%#+q", string(0x110000), "`�`"}, + {"%q", string(rune(0x110000)), `"�"`}, + {"%+q", string(rune(0x110000)), `"\ufffd"`}, + {"%#q", string(rune(0x110000)), "`�`"}, + {"%#+q", string(rune(0x110000)), "`�`"}, // characters {"%c", uint('x'), "x"}, @@ -463,6 +463,15 @@ var fmtTests = []struct { {"%#.4x", 1.0, "0x1.0000p+00"}, {"%#.4g", 1.0, "1.000"}, {"%#.4g", 100000.0, "1.000e+05"}, + {"%#.4g", 1.234, "1.234"}, + {"%#.4g", 0.1234, "0.1234"}, + {"%#.4g", 1.23, "1.230"}, + {"%#.4g", 0.123, "0.1230"}, + {"%#.4g", 1.2, "1.200"}, + {"%#.4g", 0.12, "0.1200"}, + {"%#.4g", 10.2, "10.20"}, + {"%#.4g", 0.0, "0.000"}, + {"%#.4g", 0.012, "0.01200"}, {"%#.0f", 123.0, "123."}, {"%#.0e", 123.0, "1.e+02"}, {"%#.0x", 123.0, "0x1.p+07"}, @@ -1459,7 +1468,7 @@ func (flagPrinter) Format(f State, c rune) { s := "%" for i := 0; i < 128; i++ { if f.Flag(i) { - s += string(i) + s += string(rune(i)) } } if w, ok := f.Width(); ok { diff --git a/libgo/go/fmt/format.go b/libgo/go/fmt/format.go index 74e600cab26..4d12f82f7de 100644 --- a/libgo/go/fmt/format.go +++ b/libgo/go/fmt/format.go @@ -536,6 +536,7 @@ func (f *fmt) fmtFloat(v float64, size int, verb rune, prec int) { tail := tailBuf[:0] hasDecimalPoint := false + sawNonzeroDigit := false // Starting from i = 1 to skip sign at num[0]. for i := 1; i < len(num); i++ { switch num[i] { @@ -552,10 +553,20 @@ func (f *fmt) fmtFloat(v float64, size int, verb rune, prec int) { } fallthrough default: - digits-- + if num[i] != '0' { + sawNonzeroDigit = true + } + // Count significant digits after the first non-zero digit. + if sawNonzeroDigit { + digits-- + } } } if !hasDecimalPoint { + // Leading digit 0 should contribute once to digits. + if len(num) == 2 && num[1] == '0' { + digits-- + } num = append(num, '.') } for digits > 0 { diff --git a/libgo/go/fmt/scan.go b/libgo/go/fmt/scan.go index 8cab0180ee8..381577049c0 100644 --- a/libgo/go/fmt/scan.go +++ b/libgo/go/fmt/scan.go @@ -600,13 +600,13 @@ func (s *ss) scanNumber(digits string, haveDigits bool) string { // scanRune returns the next rune value in the input. func (s *ss) scanRune(bitSize int) int64 { s.notEOF() - r := int64(s.getRune()) + r := s.getRune() n := uint(bitSize) - x := (r << (64 - n)) >> (64 - n) - if x != r { + x := (int64(r) << (64 - n)) >> (64 - n) + if x != int64(r) { s.errorString("overflow on character value " + string(r)) } - return r + return int64(r) } // scanBasePrefix reports whether the integer begins with a base prefix diff --git a/libgo/go/go/ast/ast.go b/libgo/go/go/ast/ast.go index aca510f6a51..81c64589d04 100644 --- a/libgo/go/go/ast/ast.go +++ b/libgo/go/go/ast/ast.go @@ -87,10 +87,10 @@ func stripTrailingWhitespace(s string) string { // Text returns the text of the comment. // Comment markers (//, /*, and */), the first space of a line comment, and -// leading and trailing empty lines are removed. Multiple empty lines are -// reduced to one, and trailing space on lines is trimmed. Unless the result -// is empty, it is newline-terminated. -// +// leading and trailing empty lines are removed. +// Comment directives like "//line" and "//go:noinline" are also removed. +// Multiple empty lines are reduced to one, and trailing space on lines is trimmed. +// Unless the result is empty, it is newline-terminated. func (g *CommentGroup) Text() string { if g == nil { return "" @@ -108,9 +108,18 @@ func (g *CommentGroup) Text() string { case '/': //-style comment (no newline at the end) c = c[2:] - // strip first space - required for Example tests - if len(c) > 0 && c[0] == ' ' { + if len(c) == 0 { + // empty line + break + } + if c[0] == ' ' { + // strip first space - required for Example tests c = c[1:] + break + } + if isDirective(c) { + // Ignore //go:noinline, //line, and so on. + continue } case '*': /*-style comment */ @@ -145,6 +154,32 @@ func (g *CommentGroup) Text() string { return strings.Join(lines, "\n") } +// isDirective reports whether c is a comment directive. +func isDirective(c string) bool { + // "//line " is a line directive. + // (The // has been removed.) + if strings.HasPrefix(c, "line ") { + return true + } + + // "//[a-z0-9]+:[a-z0-9]" + // (The // has been removed.) + colon := strings.Index(c, ":") + if colon <= 0 || colon+1 >= len(c) { + return false + } + for i := 0; i <= colon+1; i++ { + if i == colon { + continue + } + b := c[i] + if !('a' <= b && b <= 'z' || '0' <= b && b <= '9') { + return false + } + } + return true +} + // ---------------------------------------------------------------------------- // Expressions and types @@ -226,8 +261,8 @@ func (f *FieldList) NumFields() int { // or more of the following concrete expression nodes. // type ( - // A BadExpr node is a placeholder for expressions containing - // syntax errors for which no correct expression nodes can be + // A BadExpr node is a placeholder for an expression containing + // syntax errors for which a correct expression node cannot be // created. // BadExpr struct { @@ -897,8 +932,8 @@ func (*TypeSpec) specNode() {} // A declaration is represented by one of the following declaration nodes. // type ( - // A BadDecl node is a placeholder for declarations containing - // syntax errors for which no correct declaration nodes can be + // A BadDecl node is a placeholder for a declaration containing + // syntax errors for which a correct declaration node cannot be // created. // BadDecl struct { diff --git a/libgo/go/go/ast/ast_test.go b/libgo/go/go/ast/ast_test.go index 1a6a283f232..71b2d6ca4b8 100644 --- a/libgo/go/go/ast/ast_test.go +++ b/libgo/go/go/ast/ast_test.go @@ -33,6 +33,9 @@ var comments = []struct { {[]string{"/* Foo*/", "/*\n*/", "//", "/*\n*/", "// Bar"}, " Foo\n\nBar\n"}, {[]string{"/* Foo*/", "// Bar"}, " Foo\nBar\n"}, {[]string{"/* Foo\n Bar*/"}, " Foo\n Bar\n"}, + + {[]string{"// foo", "//go:noinline", "// bar", "//:baz"}, "foo\nbar\n:baz\n"}, + {[]string{"// foo", "//lint123:ignore", "// bar"}, "foo\nbar\n"}, } func TestCommentText(t *testing.T) { @@ -48,3 +51,29 @@ func TestCommentText(t *testing.T) { } } } + +var isDirectiveTests = []struct { + in string + ok bool +}{ + {"abc", false}, + {"go:inline", true}, + {"Go:inline", false}, + {"go:Inline", false}, + {":inline", false}, + {"lint:ignore", true}, + {"lint:1234", true}, + {"1234:lint", true}, + {"go: inline", false}, + {"go:", false}, + {"go:*", false}, + {"go:x*", true}, +} + +func TestIsDirective(t *testing.T) { + for _, tt := range isDirectiveTests { + if ok := isDirective(tt.in); ok != tt.ok { + t.Errorf("isDirective(%q) = %v, want %v", tt.in, ok, tt.ok) + } + } +} diff --git a/libgo/go/go/build/build.go b/libgo/go/go/build/build.go index d5987dd861e..ff5195d8122 100644 --- a/libgo/go/go/build/build.go +++ b/libgo/go/go/build/build.go @@ -16,7 +16,6 @@ import ( "internal/goversion" "io" "io/ioutil" - "log" "os" "os/exec" pathpkg "path" @@ -926,7 +925,7 @@ Found: quoted := spec.Path.Value path, err := strconv.Unquote(quoted) if err != nil { - log.Panicf("%s: parser returned invalid quoted string: <%s>", filename, quoted) + panic(fmt.Sprintf("%s: parser returned invalid quoted string: <%s>", filename, quoted)) } fileImports = append(fileImports, importPos{path, spec.Pos()}) if path == "C" { diff --git a/libgo/go/go/build/build_test.go b/libgo/go/go/build/build_test.go index 4d11223b96c..efdd7cfb8b4 100644 --- a/libgo/go/go/build/build_test.go +++ b/libgo/go/go/build/build_test.go @@ -5,6 +5,7 @@ package build import ( + "flag" "internal/testenv" "io" "io/ioutil" @@ -16,6 +17,14 @@ import ( "testing" ) +func TestMain(m *testing.M) { + flag.Parse() + if goTool, err := testenv.GoTool(); err == nil { + os.Setenv("PATH", filepath.Dir(goTool)+string(os.PathListSeparator)+os.Getenv("PATH")) + } + os.Exit(m.Run()) +} + func TestMatch(t *testing.T) { ctxt := Default what := "default" @@ -112,11 +121,8 @@ func TestMultiplePackageImport(t *testing.T) { func TestLocalDirectory(t *testing.T) { t.Skip("does not work with gccgo") - if runtime.GOOS == "darwin" { - switch runtime.GOARCH { - case "arm", "arm64": - t.Skipf("skipping on %s/%s, no valid GOROOT", runtime.GOOS, runtime.GOARCH) - } + if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" { + t.Skipf("skipping on %s/%s, no valid GOROOT", runtime.GOOS, runtime.GOARCH) } cwd, err := os.Getwd() @@ -246,11 +252,8 @@ func TestMatchFile(t *testing.T) { func TestImportCmd(t *testing.T) { t.Skip("does not work with gccgo") - if runtime.GOOS == "darwin" { - switch runtime.GOARCH { - case "arm", "arm64": - t.Skipf("skipping on %s/%s, no valid GOROOT", runtime.GOOS, runtime.GOARCH) - } + if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" { + t.Skipf("skipping on %s/%s, no valid GOROOT", runtime.GOOS, runtime.GOARCH) } p, err := Import("cmd/internal/objfile", "", 0) diff --git a/libgo/go/go/build/deps_test.go b/libgo/go/go/build/deps_test.go index 8eed6260a2b..fa8ecf10f42 100644 --- a/libgo/go/go/build/deps_test.go +++ b/libgo/go/go/build/deps_test.go @@ -10,6 +10,7 @@ package build import ( "bytes" "fmt" + "internal/testenv" "io/ioutil" "os" "path/filepath" @@ -20,468 +21,470 @@ import ( "testing" ) -// pkgDeps defines the expected dependencies between packages in +// depsRules defines the expected dependencies between packages in // the Go source tree. It is a statement of policy. -// Changes should not be made to this map without prior discussion. -// -// The map contains two kinds of entries: -// 1) Lower-case keys are standard import paths and list the -// allowed imports in that package. -// 2) Upper-case keys define aliases for package sets, which can then -// be used as dependencies by other rules. // // DO NOT CHANGE THIS DATA TO FIX BUILDS. +// Existing packages should not have their constraints relaxed +// without prior discussion. +// Negative assertions should almost never be removed. // -var pkgDeps = map[string][]string{ - // L0 is the lowest level, core, nearly unavoidable packages. - "errors": {"runtime", "internal/reflectlite"}, - "io": {"errors", "sync", "sync/atomic"}, - "runtime": {"unsafe", "runtime/internal/atomic", "runtime/internal/sys", "runtime/internal/math", "internal/cpu", "internal/bytealg"}, - "runtime/internal/sys": {}, - "runtime/internal/atomic": {"unsafe", "internal/cpu"}, - "runtime/internal/math": {"runtime/internal/sys"}, - "internal/race": {"runtime", "unsafe"}, - "sync": {"internal/race", "runtime", "sync/atomic", "unsafe"}, - "sync/atomic": {"unsafe"}, - "unsafe": {}, - "internal/cpu": {}, - "internal/bytealg": {"unsafe", "internal/cpu"}, - "internal/reflectlite": {"runtime", "unsafe"}, - - "L0": { - "errors", - "io", - "runtime", - "runtime/internal/atomic", - "sync", - "sync/atomic", - "unsafe", - "internal/cpu", - "internal/bytealg", - "internal/reflectlite", - }, - - // L1 adds simple functions and strings processing, - // but not Unicode tables. - "math": {"internal/cpu", "unsafe", "math/bits"}, - "math/bits": {"unsafe"}, - "math/cmplx": {"math"}, - "math/rand": {"L0", "math"}, - "strconv": {"L0", "unicode/utf8", "math", "math/bits"}, - "unicode/utf16": {}, - "unicode/utf8": {}, - - "L1": { - "L0", - "math", - "math/bits", - "math/cmplx", - "math/rand", - "sort", - "strconv", - "unicode/utf16", - "unicode/utf8", - }, - - // L2 adds Unicode and strings processing. - "bufio": {"L0", "unicode/utf8", "bytes"}, - "bytes": {"L0", "unicode", "unicode/utf8"}, - "path": {"L0", "unicode/utf8", "strings"}, - "strings": {"L0", "unicode", "unicode/utf8"}, - "unicode": {}, - - "L2": { - "L1", - "bufio", - "bytes", - "path", - "strings", - "unicode", - }, - - // L3 adds reflection and some basic utility packages - // and interface definitions, but nothing that makes - // system calls. - "crypto": {"L2", "hash"}, // interfaces - "crypto/cipher": {"L2", "crypto/subtle", "crypto/internal/subtle", "encoding/binary"}, - "crypto/internal/subtle": {"unsafe", "reflect"}, // reflect behind a appengine tag - "crypto/subtle": {}, - "encoding/base32": {"L2"}, - "encoding/base64": {"L2", "encoding/binary"}, - "encoding/binary": {"L2", "reflect"}, - "hash": {"L2"}, // interfaces - "hash/adler32": {"L2", "hash"}, - "hash/crc32": {"L2", "hash"}, - "hash/crc64": {"L2", "hash"}, - "hash/fnv": {"L2", "hash"}, - "hash/maphash": {"L2", "hash"}, - "image": {"L2", "image/color"}, // interfaces - "image/color": {"L2"}, // interfaces - "image/color/palette": {"L2", "image/color"}, - "internal/fmtsort": {"reflect", "sort"}, - "reflect": {"L2"}, - "sort": {"internal/reflectlite"}, - - "L3": { - "L2", - "crypto", - "crypto/cipher", - "crypto/internal/subtle", - "crypto/subtle", - "encoding/base32", - "encoding/base64", - "encoding/binary", - "hash", - "hash/adler32", - "hash/crc32", - "hash/crc64", - "hash/fnv", - "image", - "image/color", - "image/color/palette", - "internal/fmtsort", - "internal/oserror", - "reflect", - }, - - // End of linear dependency definitions. - - // Operating system access. - "syscall": {"L0", "internal/oserror", "internal/race", "internal/syscall/windows/sysdll", "syscall/js", "unicode/utf16"}, - "syscall/js": {"L0"}, - "internal/oserror": {"L0"}, - "internal/syscall/unix": {"L0", "syscall"}, - "internal/syscall/windows": {"L0", "syscall", "internal/syscall/windows/sysdll", "unicode/utf16"}, - "internal/syscall/windows/registry": {"L0", "syscall", "internal/syscall/windows/sysdll", "unicode/utf16"}, - "internal/syscall/execenv": {"L0", "syscall", "internal/syscall/windows", "unicode/utf16"}, - "time": { - // "L0" without the "io" package: - "errors", - "runtime", - "runtime/internal/atomic", - "sync", - "sync/atomic", - "unsafe", - // Other time dependencies: - "internal/syscall/windows/registry", - "syscall", - "syscall/js", - }, - - "internal/cfg": {"L0"}, - "internal/poll": {"L0", "internal/oserror", "internal/race", "syscall", "time", "unicode/utf16", "unicode/utf8", "internal/syscall/windows", "internal/syscall/unix"}, - "internal/testlog": {"L0"}, - "os": {"L1", "os", "syscall", "time", "internal/oserror", "internal/poll", "internal/syscall/windows", "internal/syscall/unix", "internal/syscall/execenv", "internal/testlog"}, - "path/filepath": {"L2", "os", "syscall", "internal/syscall/windows"}, - "io/ioutil": {"L2", "os", "path/filepath", "time"}, - "os/exec": {"L2", "os", "context", "path/filepath", "syscall", "internal/syscall/execenv"}, - "os/signal": {"L2", "os", "syscall"}, - - // OS enables basic operating system functionality, - // but not direct use of package syscall, nor os/signal. - "OS": { - "io/ioutil", - "os", - "os/exec", - "path/filepath", - "time", - }, - - // Formatted I/O: few dependencies (L1) but we must add reflect and internal/fmtsort. - "fmt": {"L1", "os", "reflect", "internal/fmtsort"}, - "log": {"L1", "os", "fmt", "time"}, - - // Packages used by testing must be low-level (L2+fmt). - "regexp": {"L2", "regexp/syntax"}, - "regexp/syntax": {"L2"}, - "runtime/debug": {"L2", "fmt", "io/ioutil", "os", "time"}, - "runtime/pprof": {"L2", "compress/gzip", "context", "encoding/binary", "fmt", "io/ioutil", "os", "text/tabwriter", "time"}, - "runtime/trace": {"L0", "context", "fmt"}, - "text/tabwriter": {"L2"}, - - "testing": {"L2", "flag", "fmt", "internal/race", "os", "runtime/debug", "runtime/pprof", "runtime/trace", "time"}, - "testing/iotest": {"L2", "log"}, - "testing/quick": {"L2", "flag", "fmt", "reflect", "time"}, - "internal/obscuretestdata": {"L2", "OS", "encoding/base64"}, - "internal/testenv": {"L2", "OS", "flag", "testing", "syscall", "internal/cfg"}, - "internal/lazyregexp": {"L2", "OS", "regexp"}, - "internal/lazytemplate": {"L2", "OS", "text/template"}, - - // L4 is defined as L3+fmt+log+time, because in general once - // you're using L3 packages, use of fmt, log, or time is not a big deal. - "L4": { - "L3", - "fmt", - "log", - "time", - }, - - // Go parser. - "go/ast": {"L4", "OS", "go/scanner", "go/token"}, - "go/doc": {"L4", "OS", "go/ast", "go/token", "regexp", "internal/lazyregexp", "text/template"}, - "go/parser": {"L4", "OS", "go/ast", "go/scanner", "go/token"}, - "go/printer": {"L4", "OS", "go/ast", "go/scanner", "go/token", "text/tabwriter"}, - "go/scanner": {"L4", "OS", "go/token"}, - "go/token": {"L4"}, - - "GOPARSER": { - "go/ast", - "go/doc", - "go/parser", - "go/printer", - "go/scanner", - "go/token", - }, - - "go/format": {"L4", "GOPARSER", "internal/format"}, - "internal/format": {"L4", "GOPARSER"}, - - // Go type checking. - "go/constant": {"L4", "go/token", "math/big"}, - "go/importer": {"L4", "go/build", "go/internal/gccgoimporter", "go/internal/gcimporter", "go/internal/srcimporter", "go/token", "go/types"}, - "go/internal/gcimporter": {"L4", "OS", "go/build", "go/constant", "go/token", "go/types", "text/scanner"}, - "go/internal/gccgoimporter": {"L4", "OS", "debug/elf", "go/constant", "go/token", "go/types", "internal/xcoff", "text/scanner"}, - "go/internal/srcimporter": {"L4", "OS", "fmt", "go/ast", "go/build", "go/parser", "go/token", "go/types", "path/filepath"}, - "go/types": {"L4", "GOPARSER", "container/heap", "go/constant"}, - - // One of a kind. - "archive/tar": {"L4", "OS", "syscall", "os/user"}, - "archive/zip": {"L4", "OS", "compress/flate"}, - "container/heap": {"sort"}, - "compress/bzip2": {"L4"}, - "compress/flate": {"L4"}, - "compress/gzip": {"L4", "compress/flate"}, - "compress/lzw": {"L4"}, - "compress/zlib": {"L4", "compress/flate"}, - "context": {"errors", "internal/reflectlite", "sync", "sync/atomic", "time"}, - "database/sql": {"L4", "container/list", "context", "database/sql/driver", "database/sql/internal"}, - "database/sql/driver": {"L4", "context", "time", "database/sql/internal"}, - "debug/dwarf": {"L4"}, - "debug/elf": {"L4", "OS", "debug/dwarf", "compress/zlib"}, - "debug/gosym": {"L4"}, - "debug/macho": {"L4", "OS", "debug/dwarf", "compress/zlib"}, - "debug/pe": {"L4", "OS", "debug/dwarf", "compress/zlib"}, - "debug/plan9obj": {"L4", "OS"}, - "encoding": {"L4"}, - "encoding/ascii85": {"L4"}, - "encoding/asn1": {"L4", "math/big"}, - "encoding/csv": {"L4"}, - "encoding/gob": {"L4", "OS", "encoding"}, - "encoding/hex": {"L4"}, - "encoding/json": {"L4", "encoding"}, - "encoding/pem": {"L4"}, - "encoding/xml": {"L4", "encoding"}, - "flag": {"L4", "OS"}, - "go/build": {"L4", "OS", "GOPARSER", "internal/goroot", "internal/goversion"}, - "html": {"L4"}, - "image/draw": {"L4", "image/internal/imageutil"}, - "image/gif": {"L4", "compress/lzw", "image/color/palette", "image/draw"}, - "image/internal/imageutil": {"L4"}, - "image/jpeg": {"L4", "image/internal/imageutil"}, - "image/png": {"L4", "compress/zlib"}, - "index/suffixarray": {"L4", "regexp"}, - "internal/goroot": {"L4", "OS"}, - "internal/singleflight": {"sync"}, - "internal/trace": {"L4", "OS", "container/heap"}, - "internal/xcoff": {"L4", "OS", "debug/dwarf"}, - "math/big": {"L4"}, - "mime": {"L4", "OS", "syscall", "internal/syscall/windows/registry"}, - "mime/quotedprintable": {"L4"}, - "net/internal/socktest": {"L4", "OS", "syscall", "internal/syscall/windows"}, - "net/url": {"L4"}, - "plugin": {"L0", "OS", "CGO"}, - "runtime/pprof/internal/profile": {"L4", "OS", "compress/gzip", "regexp"}, - "testing/internal/testdeps": {"L4", "internal/testlog", "runtime/pprof", "regexp"}, - "text/scanner": {"L4", "OS"}, - "text/template/parse": {"L4"}, - - "html/template": { - "L4", "OS", "encoding/json", "html", "text/template", - "text/template/parse", - }, - "text/template": { - "L4", "OS", "net/url", "text/template/parse", - }, - - // Cgo. - // If you add a dependency on CGO, you must add the package to - // cgoPackages in cmd/dist/test.go. - "runtime/cgo": {"L0", "C"}, - "CGO": {"C", "runtime/cgo"}, - - // Fake entry to satisfy the pseudo-import "C" - // that shows up in programs that use cgo. - "C": {}, - - // Race detector/MSan uses cgo. - "runtime/race": {"C"}, - "runtime/msan": {"C"}, - - // Plan 9 alone needs io/ioutil and os. - "os/user": {"L4", "CGO", "io/ioutil", "os", "syscall", "internal/syscall/windows", "internal/syscall/windows/registry"}, - - // Internal package used only for testing. - "os/signal/internal/pty": {"CGO", "fmt", "os", "syscall"}, - - // Basic networking. - // Because net must be used by any package that wants to - // do networking portably, it must have a small dependency set: just L0+basic os. - "net": { - "L0", "CGO", - "context", "math/rand", "os", "sort", "syscall", "time", - "internal/nettrace", "internal/poll", "internal/syscall/unix", - "internal/syscall/windows", "internal/singleflight", "internal/race", - "golang.org/x/net/dns/dnsmessage", "golang.org/x/net/lif", "golang.org/x/net/route", - }, - - // NET enables use of basic network-related packages. - "NET": { - "net", - "mime", - "net/textproto", - "net/url", - }, - - // Uses of networking. - "log/syslog": {"L4", "OS", "net"}, - "net/mail": {"L4", "NET", "OS", "mime"}, - "net/textproto": {"L4", "OS", "net"}, - - // Core crypto. - "crypto/aes": {"L3"}, - "crypto/des": {"L3"}, - "crypto/hmac": {"L3"}, - "crypto/internal/randutil": {"io", "sync"}, - "crypto/md5": {"L3"}, - "crypto/rc4": {"L3"}, - "crypto/sha1": {"L3"}, - "crypto/sha256": {"L3"}, - "crypto/sha512": {"L3"}, - - "CRYPTO": { - "crypto/aes", - "crypto/des", - "crypto/hmac", - "crypto/internal/randutil", - "crypto/md5", - "crypto/rc4", - "crypto/sha1", - "crypto/sha256", - "crypto/sha512", - "golang.org/x/crypto/chacha20poly1305", - "golang.org/x/crypto/curve25519", - "golang.org/x/crypto/poly1305", - }, - - // Random byte, number generation. - // This would be part of core crypto except that it imports - // math/big, which imports fmt. - "crypto/rand": {"L4", "CRYPTO", "OS", "math/big", "syscall", "syscall/js", "internal/syscall/unix"}, - - // Not part of CRYPTO because it imports crypto/rand and crypto/sha512. - "crypto/ed25519": {"L3", "CRYPTO", "crypto/rand", "crypto/ed25519/internal/edwards25519"}, - "crypto/ed25519/internal/edwards25519": {"encoding/binary"}, - - // Mathematical crypto: dependencies on fmt (L4) and math/big. - // We could avoid some of the fmt, but math/big imports fmt anyway. - "crypto/dsa": {"L4", "CRYPTO", "math/big"}, - "crypto/ecdsa": {"L4", "CRYPTO", "crypto/elliptic", "math/big", "encoding/asn1"}, - "crypto/elliptic": {"L4", "CRYPTO", "math/big"}, - "crypto/rsa": {"L4", "CRYPTO", "crypto/rand", "math/big"}, - - "CRYPTO-MATH": { - "CRYPTO", - "crypto/dsa", - "crypto/ecdsa", - "crypto/elliptic", - "crypto/rand", - "crypto/rsa", - "encoding/asn1", - "math/big", - }, - - // SSL/TLS. - "crypto/tls": { - "L4", "CRYPTO-MATH", "OS", "golang.org/x/crypto/cryptobyte", "golang.org/x/crypto/hkdf", - "container/list", "crypto/x509", "encoding/pem", "net", "syscall", "crypto/ed25519", - }, - "crypto/x509": { - "L4", "CRYPTO-MATH", "OS", "CGO", "crypto/ed25519", - "crypto/x509/pkix", "encoding/pem", "encoding/hex", "net", "os/user", "syscall", "net/url", - "golang.org/x/crypto/cryptobyte", "golang.org/x/crypto/cryptobyte/asn1", - }, - "crypto/x509/pkix": {"L4", "CRYPTO-MATH", "encoding/hex"}, - - // Simple net+crypto-aware packages. - "mime/multipart": {"L4", "OS", "mime", "crypto/rand", "net/textproto", "mime/quotedprintable"}, - "net/smtp": {"L4", "CRYPTO", "NET", "crypto/tls"}, - - // HTTP, kingpin of dependencies. - "net/http": { - "L4", "NET", "OS", - "compress/gzip", - "container/list", - "context", - "crypto/rand", - "crypto/tls", - "golang.org/x/net/http/httpguts", - "golang.org/x/net/http/httpproxy", - "golang.org/x/net/http2/hpack", - "golang.org/x/net/idna", - "golang.org/x/text/unicode/norm", - "golang.org/x/text/width", - "internal/nettrace", - "mime/multipart", - "net/http/httptrace", - "net/http/internal", - "runtime/debug", - "syscall/js", - }, - "net/http/internal": {"L4"}, - "net/http/httptrace": {"context", "crypto/tls", "internal/nettrace", "net", "net/textproto", "reflect", "time"}, - - // HTTP-using packages. - "expvar": {"L4", "OS", "encoding/json", "net/http"}, - "net/http/cgi": {"L4", "NET", "OS", "crypto/tls", "net/http", "regexp"}, - "net/http/cookiejar": {"L4", "NET", "net/http"}, - "net/http/fcgi": {"L4", "NET", "OS", "context", "net/http", "net/http/cgi"}, - "net/http/httptest": { - "L4", "NET", "OS", "crypto/tls", "flag", "net/http", "net/http/internal", "crypto/x509", - "golang.org/x/net/http/httpguts", - }, - "net/http/httputil": {"L4", "NET", "OS", "context", "net/http", "net/http/internal", "golang.org/x/net/http/httpguts"}, - "net/http/pprof": {"L4", "OS", "html/template", "net/http", "runtime/pprof", "runtime/trace"}, - "net/rpc": {"L4", "NET", "encoding/gob", "html/template", "net/http", "go/token"}, - "net/rpc/jsonrpc": {"L4", "NET", "encoding/json", "net/rpc"}, -} +// The general syntax of a rule is: +// +// a, b < c, d; +// +// which means c and d come after a and b in the partial order +// (that is, c and d can import a and b), +// but doesn't provide a relative order between a vs b or c vs d. +// +// The rules can chain together, as in: +// +// e < f, g < h; +// +// which is equivalent to +// +// e < f, g; +// f, g < h; +// +// Except for the special bottom element "NONE", each name +// must appear exactly once on the right-hand side of a rule. +// That rule serves as the definition of the allowed dependencies +// for that name. The definition must appear before any uses +// of the name on the left-hand side of a rule. (That is, the +// rules themselves must be ordered according to the partial +// order, for easier reading by people.) +// +// Negative assertions double-check the partial order: +// +// i !< j +// +// means that it must NOT be the case that i < j. +// Negative assertions may appear anywhere in the rules, +// even before i and j have been defined. +// +// Comments begin with #. +// +// All-caps names are pseudo-names for specific points +// in the dependency lattice. +// +var depsRules = ` + # No dependencies allowed for any of these packages. + NONE + < container/list, container/ring, + internal/cfg, internal/cpu, + internal/goversion, internal/nettrace, + unicode/utf8, unicode/utf16, unicode, + unsafe; + + # RUNTIME is the core runtime group of packages, all of them very light-weight. + internal/cpu, unsafe + < internal/bytealg + < internal/unsafeheader + < runtime/internal/sys + < runtime/internal/atomic + < runtime/internal/math + < runtime + < sync/atomic + < internal/race + < sync + < internal/reflectlite + < errors + < internal/oserror, math/bits + < RUNTIME; + + RUNTIME + < sort + < container/heap; + + RUNTIME + < io; + + reflect !< sort; + + # SYSCALL is RUNTIME plus the packages necessary for basic system calls. + RUNTIME, unicode/utf8, unicode/utf16, io + < internal/syscall/windows/sysdll, syscall/js + < syscall + < internal/syscall/unix, internal/syscall/windows, internal/syscall/windows/registry + < internal/syscall/execenv + < SYSCALL; + + # TIME is SYSCALL plus the core packages about time, including context. + SYSCALL + < time/tzdata + < time + < context + < TIME; + + # MATH is RUNTIME plus the basic math packages. + RUNTIME + < math + < MATH; + + unicode !< math; + + MATH + < math/cmplx; + + MATH + < math/rand; + + MATH, unicode/utf8 + < strconv; + + unicode !< strconv; + + # STR is basic string and buffer manipulation. + RUNTIME, io, unicode/utf8, unicode/utf16, unicode + < bytes, strings + < bufio, path; + + bufio, path, strconv + < STR; + + # OS is basic OS access, including helpers (path/filepath, os/exec, etc). + # OS includes string routines, but those must be layered above package os. + # OS does not include reflection. + TIME, io, sort + < internal/testlog + < internal/poll + < os + < os/signal; + + unicode, fmt !< os, os/signal; + + os/signal, STR + < path/filepath + < io/ioutil, os/exec + < OS; + + reflect !< OS; + + OS + < golang.org/x/sys/cpu, internal/goroot; + + # FMT is OS (which includes string routines) plus reflect and fmt. + # It does not include package log, which should be avoided in core packages. + strconv, unicode + < reflect; + + os, reflect + < internal/fmtsort + < fmt; + + OS, fmt + < FMT; + + log !< FMT; + + # Misc packages needing only FMT. + FMT + < flag, + html, + mime/quotedprintable, + net/internal/socktest, + net/url, + runtime/debug, + runtime/trace, + text/scanner, + text/tabwriter; + + # encodings + # core ones do not use fmt. + io, strconv + < encoding; + + encoding, reflect + < encoding/binary + < encoding/base32, encoding/base64; + + fmt !< encoding/base32, encoding/base64; + + FMT, encoding/base32, encoding/base64 + < encoding/ascii85, encoding/csv, encoding/gob, encoding/hex, + encoding/json, encoding/pem, encoding/xml, mime; + + # hashes + io + < hash + < hash/adler32, hash/crc32, hash/crc64, hash/fnv, hash/maphash; + + # math/big + FMT, encoding/binary, math/rand + < math/big; + + # compression + FMT, encoding/binary, hash/adler32, hash/crc32 + < compress/bzip2, compress/flate, compress/lzw + < archive/zip, compress/gzip, compress/zlib; + + # templates + FMT + < text/template/parse; + + net/url, text/template/parse + < text/template + < internal/lazytemplate; + + encoding/json, html, text/template + < html/template; + + # regexp + FMT + < regexp/syntax + < regexp + < internal/lazyregexp; + + # suffix array + encoding/binary, regexp + < index/suffixarray; + + # executable parsing + FMT, encoding/binary, compress/zlib + < debug/dwarf + < debug/elf, debug/gosym, debug/macho, debug/pe, debug/plan9obj, internal/xcoff + < DEBUG; + + # go parser and friends. + FMT + < go/token + < go/scanner + < go/ast + < go/parser; + + go/parser, text/tabwriter + < go/printer + < go/format; + + go/parser, internal/lazyregexp, text/template + < go/doc; + + math/big, go/token + < go/constant; + + container/heap, go/constant, go/parser + < go/types; + + go/doc, go/parser, internal/goroot, internal/goversion + < go/build; + + DEBUG, go/build, go/types, text/scanner + < go/internal/gcimporter, go/internal/gccgoimporter, go/internal/srcimporter + < go/importer; + + # databases + FMT + < database/sql/internal + < database/sql/driver + < database/sql; + + # images + FMT, compress/lzw, compress/zlib + < image/color + < image, image/color/palette + < image/internal/imageutil + < image/draw + < image/gif, image/jpeg, image/png; + + # cgo, delayed as long as possible. + # If you add a dependency on CGO, you must add the package + # to cgoPackages in cmd/dist/test.go as well. + RUNTIME + < C + < runtime/cgo + < CGO + < runtime/race, runtime/msan; + + # Bulk of the standard library must not use cgo. + # The prohibition stops at net and os/user. + C !< fmt, go/types, CRYPTO-MATH; + + CGO, OS + < plugin; + + CGO, FMT + < os/user + < archive/tar; + + sync + < internal/singleflight; + + os + < golang.org/x/net/dns/dnsmessage, + golang.org/x/net/lif, + golang.org/x/net/route; + + # net is unavoidable when doing any networking, + # so large dependencies must be kept out. + # This is a long-looking list but most of these + # are small with few dependencies. + # math/rand should probably be removed at some point. + CGO, + golang.org/x/net/dns/dnsmessage, + golang.org/x/net/lif, + golang.org/x/net/route, + internal/nettrace, + internal/poll, + internal/singleflight, + internal/race, + math/rand, + os + < net; + + fmt, unicode !< net; + + # NET is net plus net-helper packages. + FMT, net + < net/textproto; + + mime, net/textproto, net/url + < NET; + + # logging - most packages should not import; http and up is allowed + FMT + < log; + + log !< crypto/tls, database/sql, go/importer, testing; + + FMT, log, net + < log/syslog; + + NET, log + < net/mail; + + # CRYPTO is core crypto algorithms - no cgo, fmt, net. + # Unfortunately, stuck with reflect via encoding/binary. + encoding/binary, golang.org/x/sys/cpu, hash + < crypto + < crypto/subtle + < crypto/internal/subtle + < crypto/cipher + < crypto/aes, crypto/des, crypto/hmac, crypto/md5, crypto/rc4, + crypto/sha1, crypto/sha256, crypto/sha512 + < CRYPTO; + + CGO, fmt, net !< CRYPTO; + + # CRYPTO-MATH is core bignum-based crypto - no cgo, net; fmt now ok. + CRYPTO, FMT, math/big + < crypto/rand + < crypto/internal/randutil + < crypto/ed25519/internal/edwards25519 + < crypto/ed25519 + < encoding/asn1 + < golang.org/x/crypto/cryptobyte/asn1 + < golang.org/x/crypto/cryptobyte + < golang.org/x/crypto/curve25519 + < crypto/dsa, crypto/elliptic, crypto/rsa + < crypto/ecdsa + < CRYPTO-MATH; + + CGO, net !< CRYPTO-MATH; + + # TLS, Prince of Dependencies. + CGO, CRYPTO-MATH, NET, container/list, encoding/hex, encoding/pem + < golang.org/x/crypto/internal/subtle + < golang.org/x/crypto/chacha20 + < golang.org/x/crypto/poly1305 + < golang.org/x/crypto/chacha20poly1305 + < golang.org/x/crypto/hkdf + < crypto/x509/internal/macos + < crypto/x509/pkix + < crypto/x509 + < crypto/tls; + + # crypto-aware packages + + NET, crypto/rand, mime/quotedprintable + < mime/multipart; + + crypto/tls + < net/smtp; + + # HTTP, King of Dependencies. + + FMT + < golang.org/x/net/http2/hpack, net/http/internal; + + FMT, NET, container/list, encoding/binary, log + < golang.org/x/text/transform + < golang.org/x/text/unicode/norm + < golang.org/x/text/unicode/bidi + < golang.org/x/text/secure/bidirule + < golang.org/x/net/idna + < golang.org/x/net/http/httpguts, golang.org/x/net/http/httpproxy; + + NET, crypto/tls + < net/http/httptrace; + + compress/gzip, + golang.org/x/net/http/httpguts, + golang.org/x/net/http/httpproxy, + golang.org/x/net/http2/hpack, + net/http/internal, + net/http/httptrace, + mime/multipart, + log + < net/http; + + # HTTP-aware packages -// isMacro reports whether p is a package dependency macro -// (uppercase name). -func isMacro(p string) bool { - return 'A' <= p[0] && p[0] <= 'Z' -} + encoding/json, net/http + < expvar; -func allowed(pkg string) map[string]bool { - m := map[string]bool{} - var allow func(string) - allow = func(p string) { - if m[p] { - return - } - m[p] = true // set even for macros, to avoid loop on cycle + net/http + < net/http/cookiejar, net/http/httputil; + + net/http, flag + < net/http/httptest; + + net/http, regexp + < net/http/cgi + < net/http/fcgi; + + # Profiling + FMT, compress/gzip, encoding/binary, text/tabwriter + < runtime/pprof; + + OS, compress/gzip, regexp + < internal/profile; + + html/template, internal/profile, net/http, runtime/pprof, runtime/trace + < net/http/pprof; + + # RPC + encoding/gob, encoding/json, go/token, html/template, net/http + < net/rpc + < net/rpc/jsonrpc; + + # Test-only + log + < testing/iotest; - // Upper-case names are macro-expanded. - if isMacro(p) { - for _, pp := range pkgDeps[p] { - allow(pp) - } - } - } - for _, pp := range pkgDeps[pkg] { - allow(pp) - } - return m -} + FMT, flag, math/rand + < testing/quick; + + FMT, flag, runtime/debug, runtime/trace + < testing; + + internal/testlog, runtime/pprof, regexp + < testing/internal/testdeps; + + OS, flag, testing, internal/cfg + < internal/testenv; + + OS, encoding/base64 + < internal/obscuretestdata; + + CGO, OS, fmt + < os/signal/internal/pty; + + NET, testing + < golang.org/x/net/nettest; + + FMT, container/heap, math/rand + < internal/trace; +` // listStdPkgs returns the same list of packages as "go list std". func listStdPkgs(goroot string) ([]string, error) { @@ -500,11 +503,11 @@ func listStdPkgs(goroot string) ([]string, error) { } name := filepath.ToSlash(path[len(src):]) - if name == "builtin" || name == "cmd" || strings.Contains(name, "golang.org/x/") { + if name == "builtin" || name == "cmd" { return filepath.SkipDir } - pkgs = append(pkgs, name) + pkgs = append(pkgs, strings.TrimPrefix(name, "vendor/")) return nil } if err := filepath.Walk(src, walkFn); err != nil { @@ -514,8 +517,7 @@ func listStdPkgs(goroot string) ([]string, error) { } func TestDependencies(t *testing.T) { - iOS := runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") - if iOS { + if !testenv.HasSrc() { // Tests run in a limited file system and we do not // provide access to every source file. t.Skipf("skipping on %s/%s, missing full GOROOT", runtime.GOOS, runtime.GOARCH) @@ -529,6 +531,7 @@ func TestDependencies(t *testing.T) { sort.Strings(all) sawImport := map[string]map[string]bool{} // from package => to package => true + policy := depsPolicy(t) for _, pkg := range all { imports, err := findImports(pkg) @@ -539,7 +542,7 @@ func TestDependencies(t *testing.T) { if sawImport[pkg] == nil { sawImport[pkg] = map[string]bool{} } - ok := allowed(pkg) + ok := policy[pkg] var bad []string for _, imp := range imports { sawImport[pkg][imp] = true @@ -566,26 +569,16 @@ func TestDependencies(t *testing.T) { } return "" } - - // Also test some high-level policy goals are being met by not finding - // these dependency paths: - badPaths := []struct{ from, to string }{ - {"net", "unicode"}, - {"os", "unicode"}, - } - - for _, path := range badPaths { - if how := depPath(path.from, path.to); how != "" { - t.Errorf("policy violation: %s", how) - } - } - } var buildIgnore = []byte("\n// +build ignore") func findImports(pkg string) ([]string, error) { - dir := filepath.Join(Default.GOROOT, "src", pkg) + vpkg := pkg + if strings.HasPrefix(pkg, "golang.org") { + vpkg = "vendor/" + pkg + } + dir := filepath.Join(Default.GOROOT, "src", vpkg) files, err := ioutil.ReadDir(dir) if err != nil { return nil, err @@ -628,3 +621,207 @@ func findImports(pkg string) ([]string, error) { sort.Strings(imports) return imports, nil } + +// depsPolicy returns a map m such that m[p][d] == true when p can import d. +func depsPolicy(t *testing.T) map[string]map[string]bool { + allowed := map[string]map[string]bool{"NONE": {}} + disallowed := [][2][]string{} + + parseDepsRules(t, func(deps []string, op string, users []string) { + if op == "!<" { + disallowed = append(disallowed, [2][]string{deps, users}) + return + } + for _, u := range users { + if allowed[u] != nil { + t.Errorf("multiple deps lists for %s", u) + } + allowed[u] = make(map[string]bool) + for _, d := range deps { + if allowed[d] == nil { + t.Errorf("use of %s before its deps list", d) + } + allowed[u][d] = true + } + } + }) + + // Check for missing deps info. + for _, deps := range allowed { + for d := range deps { + if allowed[d] == nil { + t.Errorf("missing deps list for %s", d) + } + } + } + + // Complete transitive allowed deps. + for k := range allowed { + for i := range allowed { + for j := range allowed { + if i != k && k != j && allowed[i][k] && allowed[k][j] { + if i == j { + // Can only happen along with a "use of X before deps" error above, + // but this error is more specific - it makes clear that reordering the + // rules will not be enough to fix the problem. + t.Errorf("deps policy cycle: %s < %s < %s", j, k, i) + } + allowed[i][j] = true + } + } + } + } + + // Check negative assertions against completed allowed deps. + for _, bad := range disallowed { + deps, users := bad[0], bad[1] + for _, d := range deps { + for _, u := range users { + if allowed[u][d] { + t.Errorf("deps policy incorrect: assertion failed: %s !< %s", d, u) + } + } + } + } + + if t.Failed() { + t.FailNow() + } + + return allowed +} + +// parseDepsRules parses depsRules, calling save(deps, op, users) +// for each deps < users or deps !< users rule +// (op is "<" or "!<"). +func parseDepsRules(t *testing.T, save func(deps []string, op string, users []string)) { + p := &depsParser{t: t, lineno: 1, text: depsRules} + + var prev []string + var op string + for { + list, tok := p.nextList() + if tok == "" { + if prev == nil { + break + } + p.syntaxError("unexpected EOF") + } + if prev != nil { + save(prev, op, list) + } + prev = list + if tok == ";" { + prev = nil + op = "" + continue + } + if tok != "<" && tok != "!<" { + p.syntaxError("missing <") + } + op = tok + } +} + +// A depsParser parses the depsRules syntax described above. +type depsParser struct { + t *testing.T + lineno int + lastWord string + text string +} + +// syntaxError reports a parsing error. +func (p *depsParser) syntaxError(msg string) { + p.t.Fatalf("deps:%d: syntax error: %s near %s", p.lineno, msg, p.lastWord) +} + +// nextList parses and returns a comma-separated list of names. +func (p *depsParser) nextList() (list []string, token string) { + for { + tok := p.nextToken() + switch tok { + case "": + if len(list) == 0 { + return nil, "" + } + fallthrough + case ",", "<", "!<", ";": + p.syntaxError("bad list syntax") + } + list = append(list, tok) + + tok = p.nextToken() + if tok != "," { + return list, tok + } + } +} + +// nextToken returns the next token in the deps rules, +// one of ";" "," "<" "!<" or a name. +func (p *depsParser) nextToken() string { + for { + if p.text == "" { + return "" + } + switch p.text[0] { + case ';', ',', '<': + t := p.text[:1] + p.text = p.text[1:] + return t + + case '!': + if len(p.text) < 2 || p.text[1] != '<' { + p.syntaxError("unexpected token !") + } + p.text = p.text[2:] + return "!<" + + case '#': + i := strings.Index(p.text, "\n") + if i < 0 { + i = len(p.text) + } + p.text = p.text[i:] + continue + + case '\n': + p.lineno++ + fallthrough + case ' ', '\t': + p.text = p.text[1:] + continue + + default: + i := strings.IndexAny(p.text, "!;,<#\n \t") + if i < 0 { + i = len(p.text) + } + t := p.text[:i] + p.text = p.text[i:] + p.lastWord = t + return t + } + } +} + +// TestStdlibLowercase tests that all standard library package names are +// lowercase. See Issue 40065. +func TestStdlibLowercase(t *testing.T) { + if !testenv.HasSrc() { + t.Skipf("skipping on %s/%s, missing full GOROOT", runtime.GOOS, runtime.GOARCH) + } + + ctxt := Default + all, err := listStdPkgs(ctxt.GOROOT) + if err != nil { + t.Fatal(err) + } + + for _, pkgname := range all { + if strings.ToLower(pkgname) != pkgname { + t.Errorf("package %q should not use upper-case path", pkgname) + } + } +} diff --git a/libgo/go/go/build/doc.go b/libgo/go/go/build/doc.go index 47dec5a05df..2c6f0a83bea 100644 --- a/libgo/go/go/build/doc.go +++ b/libgo/go/go/build/doc.go @@ -59,98 +59,15 @@ // // A build constraint, also known as a build tag, is a line comment that begins // -// // +build +// // +build // -// that lists the conditions under which a file should be included in the package. -// Constraints may appear in any kind of source file (not just Go), but -// they must appear near the top of the file, preceded -// only by blank lines and other line comments. These rules mean that in Go -// files a build constraint must appear before the package clause. +// that lists the conditions under which a file should be included in the +// package. Build constraints may also be part of a file's name +// (for example, source_windows.go will only be included if the target +// operating system is windows). // -// To distinguish build constraints from package documentation, a series of -// build constraints must be followed by a blank line. -// -// A build constraint is evaluated as the OR of space-separated options. -// Each option evaluates as the AND of its comma-separated terms. -// Each term consists of letters, digits, underscores, and dots. -// A term may be negated with a preceding !. -// For example, the build constraint: -// -// // +build linux,386 darwin,!cgo -// -// corresponds to the boolean formula: -// -// (linux AND 386) OR (darwin AND (NOT cgo)) -// -// A file may have multiple build constraints. The overall constraint is the AND -// of the individual constraints. That is, the build constraints: -// -// // +build linux darwin -// // +build 386 -// -// corresponds to the boolean formula: -// -// (linux OR darwin) AND 386 -// -// During a particular build, the following words are satisfied: -// -// - the target operating system, as spelled by runtime.GOOS -// - the target architecture, as spelled by runtime.GOARCH -// - the compiler being used, either "gc" or "gccgo" -// - "cgo", if ctxt.CgoEnabled is true -// - "go1.1", from Go version 1.1 onward -// - "go1.2", from Go version 1.2 onward -// - "go1.3", from Go version 1.3 onward -// - "go1.4", from Go version 1.4 onward -// - "go1.5", from Go version 1.5 onward -// - "go1.6", from Go version 1.6 onward -// - "go1.7", from Go version 1.7 onward -// - "go1.8", from Go version 1.8 onward -// - "go1.9", from Go version 1.9 onward -// - "go1.10", from Go version 1.10 onward -// - "go1.11", from Go version 1.11 onward -// - "go1.12", from Go version 1.12 onward -// - "go1.13", from Go version 1.13 onward -// - "go1.14", from Go version 1.14 onward -// - any additional words listed in ctxt.BuildTags -// -// There are no build tags for beta or minor releases. -// -// If a file's name, after stripping the extension and a possible _test suffix, -// matches any of the following patterns: -// *_GOOS -// *_GOARCH -// *_GOOS_GOARCH -// (example: source_windows_amd64.go) where GOOS and GOARCH represent -// any known operating system and architecture values respectively, then -// the file is considered to have an implicit build constraint requiring -// those terms (in addition to any explicit constraints in the file). -// -// To keep a file from being considered for the build: -// -// // +build ignore -// -// (any other unsatisfied word will work as well, but ``ignore'' is conventional.) -// -// To build a file only when using cgo, and only on Linux and OS X: -// -// // +build linux,cgo darwin,cgo -// -// Such a file is usually paired with another file implementing the -// default functionality for other systems, which in this case would -// carry the constraint: -// -// // +build !linux,!darwin !cgo -// -// Naming a file dns_windows.go will cause it to be included only when -// building the package for Windows; similarly, math_386.s will be included -// only when building the package for 32-bit x86. -// -// Using GOOS=android matches build tags and files as for GOOS=linux -// in addition to android tags and files. -// -// Using GOOS=illumos matches build tags and files as for GOOS=solaris -// in addition to illumos tags and files. +// See 'go help buildconstraint' +// (https://golang.org/cmd/go/#hdr-Build_constraints) for details. // // Binary-Only Packages // diff --git a/libgo/go/go/constant/value.go b/libgo/go/go/constant/value.go index cd77b376d12..08bcb3bf871 100644 --- a/libgo/go/go/constant/value.go +++ b/libgo/go/go/constant/value.go @@ -381,17 +381,8 @@ func MakeFromLiteral(lit string, tok token.Token, zero uint) Value { panic("MakeFromLiteral called with non-zero last argument") } - // TODO(gri) Remove stripSep and, for token.INT, 0o-octal handling - // below once strconv and math/big can handle separators - // and 0o-octals. - switch tok { case token.INT: - // TODO(gri) remove 0o-special case once strconv and math/big can handle 0o-octals - lit = stripSep(lit) - if len(lit) >= 2 && lit[0] == '0' && (lit[1] == 'o' || lit[1] == 'O') { - lit = "0" + lit[2:] - } if x, err := strconv.ParseInt(lit, 0, 64); err == nil { return int64Val(x) } @@ -400,13 +391,11 @@ func MakeFromLiteral(lit string, tok token.Token, zero uint) Value { } case token.FLOAT: - lit = stripSep(lit) if x := makeFloatFromLiteral(lit); x != nil { return x } case token.IMAG: - lit = stripSep(lit) if n := len(lit); n > 0 && lit[n-1] == 'i' { if im := makeFloatFromLiteral(lit[:n-1]); im != nil { return makeComplex(int64Val(0), im) @@ -432,26 +421,6 @@ func MakeFromLiteral(lit string, tok token.Token, zero uint) Value { return unknownVal{} } -func stripSep(s string) string { - // avoid making a copy if there are no separators (common case) - i := 0 - for i < len(s) && s[i] != '_' { - i++ - } - if i == len(s) { - return s - } - - // make a copy of s without separators - var buf []byte - for i := 0; i < len(s); i++ { - if c := s[i]; c != '_' { - buf = append(buf, c) - } - } - return string(buf) -} - // ---------------------------------------------------------------------------- // Accessors // diff --git a/libgo/go/go/format/format.go b/libgo/go/go/format/format.go index 9aa28fc63b2..a603d9630e6 100644 --- a/libgo/go/go/format/format.go +++ b/libgo/go/go/format/format.go @@ -24,7 +24,19 @@ import ( "io" ) -var config = printer.Config{Mode: printer.UseSpaces | printer.TabIndent, Tabwidth: 8} +// Keep these in sync with cmd/gofmt/gofmt.go. +const ( + tabWidth = 8 + printerMode = printer.UseSpaces | printer.TabIndent | printerNormalizeNumbers + + // printerNormalizeNumbers means to canonicalize number literal prefixes + // and exponents while printing. See https://golang.org/doc/go1.13#gofmt. + // + // This value is defined in go/printer specifically for go/format and cmd/gofmt. + printerNormalizeNumbers = 1 << 30 +) + +var config = printer.Config{Mode: printerMode, Tabwidth: tabWidth} const parserMode = parser.ParseComments diff --git a/libgo/go/go/format/format_test.go b/libgo/go/go/format/format_test.go index b5817a5dd18..58e088ede31 100644 --- a/libgo/go/go/format/format_test.go +++ b/libgo/go/go/format/format_test.go @@ -6,6 +6,7 @@ package format import ( "bytes" + "go/ast" "go/parser" "go/token" "io/ioutil" @@ -57,6 +58,43 @@ func TestNode(t *testing.T) { diff(t, buf.Bytes(), src) } +// Node is documented to not modify the AST. +// Test that it is so even when numbers are normalized. +func TestNodeNoModify(t *testing.T) { + const ( + src = "package p\n\nconst _ = 0000000123i\n" + golden = "package p\n\nconst _ = 123i\n" + ) + + fset := token.NewFileSet() + file, err := parser.ParseFile(fset, "", src, parser.ParseComments) + if err != nil { + t.Fatal(err) + } + + // Capture original address and value of a BasicLit node + // which will undergo formatting changes during printing. + wantLit := file.Decls[0].(*ast.GenDecl).Specs[0].(*ast.ValueSpec).Values[0].(*ast.BasicLit) + wantVal := wantLit.Value + + var buf bytes.Buffer + if err = Node(&buf, fset, file); err != nil { + t.Fatal("Node failed:", err) + } + diff(t, buf.Bytes(), []byte(golden)) + + // Check if anything changed after Node returned. + gotLit := file.Decls[0].(*ast.GenDecl).Specs[0].(*ast.ValueSpec).Values[0].(*ast.BasicLit) + gotVal := gotLit.Value + + if gotLit != wantLit { + t.Errorf("got *ast.BasicLit address %p, want %p", gotLit, wantLit) + } + if gotVal != wantVal { + t.Errorf("got *ast.BasicLit value %q, want %q", gotVal, wantVal) + } +} + func TestSource(t *testing.T) { src, err := ioutil.ReadFile(testfile) if err != nil { diff --git a/libgo/go/go/format/internal.go b/libgo/go/go/format/internal.go index 4918681de57..2f3b0e43bac 100644 --- a/libgo/go/go/format/internal.go +++ b/libgo/go/go/format/internal.go @@ -72,7 +72,7 @@ func parse(fset *token.FileSet, filename string, src []byte, fragmentOk bool) ( indent = 0 } // Remove the wrapping. - // Gofmt has turned the ';' into a '\n'. + // Gofmt has turned the "; " into a "\n\n". // There will be two non-blank lines with indent, hence 2*indent. src = src[2*indent+len("package p\n\nfunc _() {"):] // Remove only the "}\n" suffix: remaining whitespaces will be trimmed anyway diff --git a/libgo/go/go/internal/gccgoimporter/parser.go b/libgo/go/go/internal/gccgoimporter/parser.go index 9204b004f9b..e2ef33f7ae6 100644 --- a/libgo/go/go/internal/gccgoimporter/parser.go +++ b/libgo/go/go/internal/gccgoimporter/parser.go @@ -326,7 +326,7 @@ func (p *parser) parseConstValue(pkg *types.Package) (val constant.Value, typ ty if p.tok == '$' { p.next() if p.tok != scanner.Ident { - p.errorf("expected identifer after '$', got %s (%q)", scanner.TokenString(p.tok), p.lit) + p.errorf("expected identifier after '$', got %s (%q)", scanner.TokenString(p.tok), p.lit) } } diff --git a/libgo/go/go/internal/gcimporter/bimport.go b/libgo/go/go/internal/gcimporter/bimport.go deleted file mode 100644 index 1019ccb8f77..00000000000 --- a/libgo/go/go/internal/gcimporter/bimport.go +++ /dev/null @@ -1,1021 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gcimporter - -import ( - "encoding/binary" - "fmt" - "go/constant" - "go/token" - "go/types" - "sort" - "strconv" - "strings" - "sync" -) - -type importer struct { - imports map[string]*types.Package - data []byte - importpath string - buf []byte // for reading strings - version int // export format version - - // object lists - strList []string // in order of appearance - pathList []string // in order of appearance - pkgList []*types.Package // in order of appearance - typList []types.Type // in order of appearance - interfaceList []*types.Interface // for delayed completion only - trackAllTypes bool - - // position encoding - posInfoFormat bool - prevFile string - prevLine int - fake fakeFileSet - - // debugging support - debugFormat bool - read int // bytes read -} - -// BImportData imports a package from the serialized package data -// and returns the number of bytes consumed and a reference to the package. -// If the export data version is not recognized or the format is otherwise -// compromised, an error is returned. -func BImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { - // catch panics and return them as errors - const currentVersion = 6 - version := -1 // unknown version - defer func() { - if e := recover(); e != nil { - // Return a (possibly nil or incomplete) package unchanged (see #16088). - if version > currentVersion { - err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e) - } else { - err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e) - } - } - }() - - p := importer{ - imports: imports, - data: data, - importpath: path, - version: version, - strList: []string{""}, // empty string is mapped to 0 - pathList: []string{""}, // empty string is mapped to 0 - fake: fakeFileSet{ - fset: fset, - files: make(map[string]*token.File), - }, - } - - // read version info - var versionstr string - if b := p.rawByte(); b == 'c' || b == 'd' { - // Go1.7 encoding; first byte encodes low-level - // encoding format (compact vs debug). - // For backward-compatibility only (avoid problems with - // old installed packages). Newly compiled packages use - // the extensible format string. - // TODO(gri) Remove this support eventually; after Go1.8. - if b == 'd' { - p.debugFormat = true - } - p.trackAllTypes = p.rawByte() == 'a' - p.posInfoFormat = p.int() != 0 - versionstr = p.string() - if versionstr == "v1" { - version = 0 - } - } else { - // Go1.8 extensible encoding - // read version string and extract version number (ignore anything after the version number) - versionstr = p.rawStringln(b) - if s := strings.SplitN(versionstr, " ", 3); len(s) >= 2 && s[0] == "version" { - if v, err := strconv.Atoi(s[1]); err == nil && v > 0 { - version = v - } - } - } - p.version = version - - // read version specific flags - extend as necessary - switch p.version { - // case currentVersion: - // ... - // fallthrough - case currentVersion, 5, 4, 3, 2, 1: - p.debugFormat = p.rawStringln(p.rawByte()) == "debug" - p.trackAllTypes = p.int() != 0 - p.posInfoFormat = p.int() != 0 - case 0: - // Go1.7 encoding format - nothing to do here - default: - errorf("unknown bexport format version %d (%q)", p.version, versionstr) - } - - // --- generic export data --- - - // populate typList with predeclared "known" types - p.typList = append(p.typList, predeclared...) - - // read package data - pkg = p.pkg() - - // read objects of phase 1 only (see cmd/compile/internal/gc/bexport.go) - objcount := 0 - for { - tag := p.tagOrIndex() - if tag == endTag { - break - } - p.obj(tag) - objcount++ - } - - // self-verification - if count := p.int(); count != objcount { - errorf("got %d objects; want %d", objcount, count) - } - - // ignore compiler-specific import data - - // complete interfaces - // TODO(gri) re-investigate if we still need to do this in a delayed fashion - for _, typ := range p.interfaceList { - typ.Complete() - } - - // record all referenced packages as imports - list := append(([]*types.Package)(nil), p.pkgList[1:]...) - sort.Sort(byPath(list)) - pkg.SetImports(list) - - // package was imported completely and without errors - pkg.MarkComplete() - - return p.read, pkg, nil -} - -func errorf(format string, args ...interface{}) { - panic(fmt.Sprintf(format, args...)) -} - -func (p *importer) pkg() *types.Package { - // if the package was seen before, i is its index (>= 0) - i := p.tagOrIndex() - if i >= 0 { - return p.pkgList[i] - } - - // otherwise, i is the package tag (< 0) - if i != packageTag { - errorf("unexpected package tag %d version %d", i, p.version) - } - - // read package data - name := p.string() - var path string - if p.version >= 5 { - path = p.path() - } else { - path = p.string() - } - if p.version >= 6 { - p.int() // package height; unused by go/types - } - - // we should never see an empty package name - if name == "" { - errorf("empty package name in import") - } - - // an empty path denotes the package we are currently importing; - // it must be the first package we see - if (path == "") != (len(p.pkgList) == 0) { - errorf("package path %q for pkg index %d", path, len(p.pkgList)) - } - - // if the package was imported before, use that one; otherwise create a new one - if path == "" { - path = p.importpath - } - pkg := p.imports[path] - if pkg == nil { - pkg = types.NewPackage(path, name) - p.imports[path] = pkg - } else if pkg.Name() != name { - errorf("conflicting names %s and %s for package %q", pkg.Name(), name, path) - } - p.pkgList = append(p.pkgList, pkg) - - return pkg -} - -// objTag returns the tag value for each object kind. -func objTag(obj types.Object) int { - switch obj.(type) { - case *types.Const: - return constTag - case *types.TypeName: - return typeTag - case *types.Var: - return varTag - case *types.Func: - return funcTag - default: - errorf("unexpected object: %v (%T)", obj, obj) // panics - panic("unreachable") - } -} - -func sameObj(a, b types.Object) bool { - // Because unnamed types are not canonicalized, we cannot simply compare types for - // (pointer) identity. - // Ideally we'd check equality of constant values as well, but this is good enough. - return objTag(a) == objTag(b) && types.Identical(a.Type(), b.Type()) -} - -func (p *importer) declare(obj types.Object) { - pkg := obj.Pkg() - if alt := pkg.Scope().Insert(obj); alt != nil { - // This can only trigger if we import a (non-type) object a second time. - // Excluding type aliases, this cannot happen because 1) we only import a package - // once; and b) we ignore compiler-specific export data which may contain - // functions whose inlined function bodies refer to other functions that - // were already imported. - // However, type aliases require reexporting the original type, so we need - // to allow it (see also the comment in cmd/compile/internal/gc/bimport.go, - // method importer.obj, switch case importing functions). - // TODO(gri) review/update this comment once the gc compiler handles type aliases. - if !sameObj(obj, alt) { - errorf("inconsistent import:\n\t%v\npreviously imported as:\n\t%v\n", obj, alt) - } - } -} - -func (p *importer) obj(tag int) { - switch tag { - case constTag: - pos := p.pos() - pkg, name := p.qualifiedName() - typ := p.typ(nil, nil) - val := p.value() - p.declare(types.NewConst(pos, pkg, name, typ, val)) - - case aliasTag: - // TODO(gri) verify type alias hookup is correct - pos := p.pos() - pkg, name := p.qualifiedName() - typ := p.typ(nil, nil) - p.declare(types.NewTypeName(pos, pkg, name, typ)) - - case typeTag: - p.typ(nil, nil) - - case varTag: - pos := p.pos() - pkg, name := p.qualifiedName() - typ := p.typ(nil, nil) - p.declare(types.NewVar(pos, pkg, name, typ)) - - case funcTag: - pos := p.pos() - pkg, name := p.qualifiedName() - params, isddd := p.paramList() - result, _ := p.paramList() - sig := types.NewSignature(nil, params, result, isddd) - p.declare(types.NewFunc(pos, pkg, name, sig)) - - default: - errorf("unexpected object tag %d", tag) - } -} - -const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go - -func (p *importer) pos() token.Pos { - if !p.posInfoFormat { - return token.NoPos - } - - file := p.prevFile - line := p.prevLine - delta := p.int() - line += delta - if p.version >= 5 { - if delta == deltaNewFile { - if n := p.int(); n >= 0 { - // file changed - file = p.path() - line = n - } - } - } else { - if delta == 0 { - if n := p.int(); n >= 0 { - // file changed - file = p.prevFile[:n] + p.string() - line = p.int() - } - } - } - p.prevFile = file - p.prevLine = line - - return p.fake.pos(file, line, 0) -} - -// Synthesize a token.Pos -type fakeFileSet struct { - fset *token.FileSet - files map[string]*token.File -} - -func (s *fakeFileSet) pos(file string, line, column int) token.Pos { - // TODO(mdempsky): Make use of column. - - // Since we don't know the set of needed file positions, we - // reserve maxlines positions per file. - const maxlines = 64 * 1024 - f := s.files[file] - if f == nil { - f = s.fset.AddFile(file, -1, maxlines) - s.files[file] = f - // Allocate the fake linebreak indices on first use. - // TODO(adonovan): opt: save ~512KB using a more complex scheme? - fakeLinesOnce.Do(func() { - fakeLines = make([]int, maxlines) - for i := range fakeLines { - fakeLines[i] = i - } - }) - f.SetLines(fakeLines) - } - - if line > maxlines { - line = 1 - } - - // Treat the file as if it contained only newlines - // and column=1: use the line number as the offset. - return f.Pos(line - 1) -} - -var ( - fakeLines []int - fakeLinesOnce sync.Once -) - -func (p *importer) qualifiedName() (pkg *types.Package, name string) { - name = p.string() - pkg = p.pkg() - return -} - -func (p *importer) record(t types.Type) { - p.typList = append(p.typList, t) -} - -// A dddSlice is a types.Type representing ...T parameters. -// It only appears for parameter types and does not escape -// the importer. -type dddSlice struct { - elem types.Type -} - -func (t *dddSlice) Underlying() types.Type { return t } -func (t *dddSlice) String() string { return "..." + t.elem.String() } - -// parent is the package which declared the type; parent == nil means -// the package currently imported. The parent package is needed for -// exported struct fields and interface methods which don't contain -// explicit package information in the export data. -// -// A non-nil tname is used as the "owner" of the result type; i.e., -// the result type is the underlying type of tname. tname is used -// to give interface methods a named receiver type where possible. -func (p *importer) typ(parent *types.Package, tname *types.Named) types.Type { - // if the type was seen before, i is its index (>= 0) - i := p.tagOrIndex() - if i >= 0 { - return p.typList[i] - } - - // otherwise, i is the type tag (< 0) - switch i { - case namedTag: - // read type object - pos := p.pos() - parent, name := p.qualifiedName() - scope := parent.Scope() - obj := scope.Lookup(name) - - // if the object doesn't exist yet, create and insert it - if obj == nil { - obj = types.NewTypeName(pos, parent, name, nil) - scope.Insert(obj) - } - - if _, ok := obj.(*types.TypeName); !ok { - errorf("pkg = %s, name = %s => %s", parent, name, obj) - } - - // associate new named type with obj if it doesn't exist yet - t0 := types.NewNamed(obj.(*types.TypeName), nil, nil) - - // but record the existing type, if any - tname := obj.Type().(*types.Named) // tname is either t0 or the existing type - p.record(tname) - - // read underlying type - t0.SetUnderlying(p.typ(parent, t0)) - - // interfaces don't have associated methods - if types.IsInterface(t0) { - return tname - } - - // read associated methods - for i := p.int(); i > 0; i-- { - // TODO(gri) replace this with something closer to fieldName - pos := p.pos() - name := p.string() - if !token.IsExported(name) { - p.pkg() - } - - recv, _ := p.paramList() // TODO(gri) do we need a full param list for the receiver? - params, isddd := p.paramList() - result, _ := p.paramList() - p.int() // go:nointerface pragma - discarded - - sig := types.NewSignature(recv.At(0), params, result, isddd) - t0.AddMethod(types.NewFunc(pos, parent, name, sig)) - } - - return tname - - case arrayTag: - t := new(types.Array) - if p.trackAllTypes { - p.record(t) - } - - n := p.int64() - *t = *types.NewArray(p.typ(parent, nil), n) - return t - - case sliceTag: - t := new(types.Slice) - if p.trackAllTypes { - p.record(t) - } - - *t = *types.NewSlice(p.typ(parent, nil)) - return t - - case dddTag: - t := new(dddSlice) - if p.trackAllTypes { - p.record(t) - } - - t.elem = p.typ(parent, nil) - return t - - case structTag: - t := new(types.Struct) - if p.trackAllTypes { - p.record(t) - } - - *t = *types.NewStruct(p.fieldList(parent)) - return t - - case pointerTag: - t := new(types.Pointer) - if p.trackAllTypes { - p.record(t) - } - - *t = *types.NewPointer(p.typ(parent, nil)) - return t - - case signatureTag: - t := new(types.Signature) - if p.trackAllTypes { - p.record(t) - } - - params, isddd := p.paramList() - result, _ := p.paramList() - *t = *types.NewSignature(nil, params, result, isddd) - return t - - case interfaceTag: - // Create a dummy entry in the type list. This is safe because we - // cannot expect the interface type to appear in a cycle, as any - // such cycle must contain a named type which would have been - // first defined earlier. - // TODO(gri) Is this still true now that we have type aliases? - // See issue #23225. - n := len(p.typList) - if p.trackAllTypes { - p.record(nil) - } - - var embeddeds []types.Type - for n := p.int(); n > 0; n-- { - p.pos() - embeddeds = append(embeddeds, p.typ(parent, nil)) - } - - t := types.NewInterfaceType(p.methodList(parent, tname), embeddeds) - p.interfaceList = append(p.interfaceList, t) - if p.trackAllTypes { - p.typList[n] = t - } - return t - - case mapTag: - t := new(types.Map) - if p.trackAllTypes { - p.record(t) - } - - key := p.typ(parent, nil) - val := p.typ(parent, nil) - *t = *types.NewMap(key, val) - return t - - case chanTag: - t := new(types.Chan) - if p.trackAllTypes { - p.record(t) - } - - dir := chanDir(p.int()) - val := p.typ(parent, nil) - *t = *types.NewChan(dir, val) - return t - - default: - errorf("unexpected type tag %d", i) // panics - panic("unreachable") - } -} - -func chanDir(d int) types.ChanDir { - // tag values must match the constants in cmd/compile/internal/gc/go.go - switch d { - case 1 /* Crecv */ : - return types.RecvOnly - case 2 /* Csend */ : - return types.SendOnly - case 3 /* Cboth */ : - return types.SendRecv - default: - errorf("unexpected channel dir %d", d) - return 0 - } -} - -func (p *importer) fieldList(parent *types.Package) (fields []*types.Var, tags []string) { - if n := p.int(); n > 0 { - fields = make([]*types.Var, n) - tags = make([]string, n) - for i := range fields { - fields[i], tags[i] = p.field(parent) - } - } - return -} - -func (p *importer) field(parent *types.Package) (*types.Var, string) { - pos := p.pos() - pkg, name, alias := p.fieldName(parent) - typ := p.typ(parent, nil) - tag := p.string() - - anonymous := false - if name == "" { - // anonymous field - typ must be T or *T and T must be a type name - switch typ := deref(typ).(type) { - case *types.Basic: // basic types are named types - pkg = nil // // objects defined in Universe scope have no package - name = typ.Name() - case *types.Named: - name = typ.Obj().Name() - default: - errorf("named base type expected") - } - anonymous = true - } else if alias { - // anonymous field: we have an explicit name because it's an alias - anonymous = true - } - - return types.NewField(pos, pkg, name, typ, anonymous), tag -} - -func (p *importer) methodList(parent *types.Package, baseType *types.Named) (methods []*types.Func) { - if n := p.int(); n > 0 { - methods = make([]*types.Func, n) - for i := range methods { - methods[i] = p.method(parent, baseType) - } - } - return -} - -func (p *importer) method(parent *types.Package, baseType *types.Named) *types.Func { - pos := p.pos() - pkg, name, _ := p.fieldName(parent) - // If we don't have a baseType, use a nil receiver. - // A receiver using the actual interface type (which - // we don't know yet) will be filled in when we call - // types.Interface.Complete. - var recv *types.Var - if baseType != nil { - recv = types.NewVar(token.NoPos, parent, "", baseType) - } - params, isddd := p.paramList() - result, _ := p.paramList() - sig := types.NewSignature(recv, params, result, isddd) - return types.NewFunc(pos, pkg, name, sig) -} - -func (p *importer) fieldName(parent *types.Package) (pkg *types.Package, name string, alias bool) { - name = p.string() - pkg = parent - if pkg == nil { - // use the imported package instead - pkg = p.pkgList[0] - } - if p.version == 0 && name == "_" { - // version 0 didn't export a package for _ fields - return - } - switch name { - case "": - // 1) field name matches base type name and is exported: nothing to do - case "?": - // 2) field name matches base type name and is not exported: need package - name = "" - pkg = p.pkg() - case "@": - // 3) field name doesn't match type name (alias) - name = p.string() - alias = true - fallthrough - default: - if !token.IsExported(name) { - pkg = p.pkg() - } - } - return -} - -func (p *importer) paramList() (*types.Tuple, bool) { - n := p.int() - if n == 0 { - return nil, false - } - // negative length indicates unnamed parameters - named := true - if n < 0 { - n = -n - named = false - } - // n > 0 - params := make([]*types.Var, n) - isddd := false - for i := range params { - params[i], isddd = p.param(named) - } - return types.NewTuple(params...), isddd -} - -func (p *importer) param(named bool) (*types.Var, bool) { - t := p.typ(nil, nil) - td, isddd := t.(*dddSlice) - if isddd { - t = types.NewSlice(td.elem) - } - - var pkg *types.Package - var name string - if named { - name = p.string() - if name == "" { - errorf("expected named parameter") - } - if name != "_" { - pkg = p.pkg() - } - if i := strings.Index(name, "·"); i > 0 { - name = name[:i] // cut off gc-specific parameter numbering - } - } - - // read and discard compiler-specific info - p.string() - - return types.NewVar(token.NoPos, pkg, name, t), isddd -} - -func (p *importer) value() constant.Value { - switch tag := p.tagOrIndex(); tag { - case falseTag: - return constant.MakeBool(false) - case trueTag: - return constant.MakeBool(true) - case int64Tag: - return constant.MakeInt64(p.int64()) - case floatTag: - return p.float() - case complexTag: - re := p.float() - im := p.float() - return constant.BinaryOp(re, token.ADD, constant.MakeImag(im)) - case stringTag: - return constant.MakeString(p.string()) - case unknownTag: - return constant.MakeUnknown() - default: - errorf("unexpected value tag %d", tag) // panics - panic("unreachable") - } -} - -func (p *importer) float() constant.Value { - sign := p.int() - if sign == 0 { - return constant.MakeInt64(0) - } - - exp := p.int() - mant := []byte(p.string()) // big endian - - // remove leading 0's if any - for len(mant) > 0 && mant[0] == 0 { - mant = mant[1:] - } - - // convert to little endian - // TODO(gri) go/constant should have a more direct conversion function - // (e.g., once it supports a big.Float based implementation) - for i, j := 0, len(mant)-1; i < j; i, j = i+1, j-1 { - mant[i], mant[j] = mant[j], mant[i] - } - - // adjust exponent (constant.MakeFromBytes creates an integer value, - // but mant represents the mantissa bits such that 0.5 <= mant < 1.0) - exp -= len(mant) << 3 - if len(mant) > 0 { - for msd := mant[len(mant)-1]; msd&0x80 == 0; msd <<= 1 { - exp++ - } - } - - x := constant.MakeFromBytes(mant) - switch { - case exp < 0: - d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp)) - x = constant.BinaryOp(x, token.QUO, d) - case exp > 0: - x = constant.Shift(x, token.SHL, uint(exp)) - } - - if sign < 0 { - x = constant.UnaryOp(token.SUB, x, 0) - } - return x -} - -// ---------------------------------------------------------------------------- -// Low-level decoders - -func (p *importer) tagOrIndex() int { - if p.debugFormat { - p.marker('t') - } - - return int(p.rawInt64()) -} - -func (p *importer) int() int { - x := p.int64() - if int64(int(x)) != x { - errorf("exported integer too large") - } - return int(x) -} - -func (p *importer) int64() int64 { - if p.debugFormat { - p.marker('i') - } - - return p.rawInt64() -} - -func (p *importer) path() string { - if p.debugFormat { - p.marker('p') - } - // if the path was seen before, i is its index (>= 0) - // (the empty string is at index 0) - i := p.rawInt64() - if i >= 0 { - return p.pathList[i] - } - // otherwise, i is the negative path length (< 0) - a := make([]string, -i) - for n := range a { - a[n] = p.string() - } - s := strings.Join(a, "/") - p.pathList = append(p.pathList, s) - return s -} - -func (p *importer) string() string { - if p.debugFormat { - p.marker('s') - } - // if the string was seen before, i is its index (>= 0) - // (the empty string is at index 0) - i := p.rawInt64() - if i >= 0 { - return p.strList[i] - } - // otherwise, i is the negative string length (< 0) - if n := int(-i); n <= cap(p.buf) { - p.buf = p.buf[:n] - } else { - p.buf = make([]byte, n) - } - for i := range p.buf { - p.buf[i] = p.rawByte() - } - s := string(p.buf) - p.strList = append(p.strList, s) - return s -} - -func (p *importer) marker(want byte) { - if got := p.rawByte(); got != want { - errorf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.read) - } - - pos := p.read - if n := int(p.rawInt64()); n != pos { - errorf("incorrect position: got %d; want %d", n, pos) - } -} - -// rawInt64 should only be used by low-level decoders. -func (p *importer) rawInt64() int64 { - i, err := binary.ReadVarint(p) - if err != nil { - errorf("read error: %v", err) - } - return i -} - -// rawStringln should only be used to read the initial version string. -func (p *importer) rawStringln(b byte) string { - p.buf = p.buf[:0] - for b != '\n' { - p.buf = append(p.buf, b) - b = p.rawByte() - } - return string(p.buf) -} - -// needed for binary.ReadVarint in rawInt64 -func (p *importer) ReadByte() (byte, error) { - return p.rawByte(), nil -} - -// byte is the bottleneck interface for reading p.data. -// It unescapes '|' 'S' to '$' and '|' '|' to '|'. -// rawByte should only be used by low-level decoders. -func (p *importer) rawByte() byte { - b := p.data[0] - r := 1 - if b == '|' { - b = p.data[1] - r = 2 - switch b { - case 'S': - b = '$' - case '|': - // nothing to do - default: - errorf("unexpected escape sequence in export data") - } - } - p.data = p.data[r:] - p.read += r - return b - -} - -// ---------------------------------------------------------------------------- -// Export format - -// Tags. Must be < 0. -const ( - // Objects - packageTag = -(iota + 1) - constTag - typeTag - varTag - funcTag - endTag - - // Types - namedTag - arrayTag - sliceTag - dddTag - structTag - pointerTag - signatureTag - interfaceTag - mapTag - chanTag - - // Values - falseTag - trueTag - int64Tag - floatTag - fractionTag // not used by gc - complexTag - stringTag - nilTag // only used by gc (appears in exported inlined function bodies) - unknownTag // not used by gc (only appears in packages with errors) - - // Type aliases - aliasTag -) - -var predeclared = []types.Type{ - // basic types - types.Typ[types.Bool], - types.Typ[types.Int], - types.Typ[types.Int8], - types.Typ[types.Int16], - types.Typ[types.Int32], - types.Typ[types.Int64], - types.Typ[types.Uint], - types.Typ[types.Uint8], - types.Typ[types.Uint16], - types.Typ[types.Uint32], - types.Typ[types.Uint64], - types.Typ[types.Uintptr], - types.Typ[types.Float32], - types.Typ[types.Float64], - types.Typ[types.Complex64], - types.Typ[types.Complex128], - types.Typ[types.String], - - // basic type aliases - types.Universe.Lookup("byte").Type(), - types.Universe.Lookup("rune").Type(), - - // error - types.Universe.Lookup("error").Type(), - - // untyped types - types.Typ[types.UntypedBool], - types.Typ[types.UntypedInt], - types.Typ[types.UntypedRune], - types.Typ[types.UntypedFloat], - types.Typ[types.UntypedComplex], - types.Typ[types.UntypedString], - types.Typ[types.UntypedNil], - - // package unsafe - types.Typ[types.UnsafePointer], - - // invalid type - types.Typ[types.Invalid], // only appears in packages with errors - - // used internally by gc; never used by this package or in .a files - anyType{}, -} - -type anyType struct{} - -func (t anyType) Underlying() types.Type { return t } -func (t anyType) String() string { return "any" } diff --git a/libgo/go/go/internal/gcimporter/gcimporter.go b/libgo/go/go/internal/gcimporter/gcimporter.go index 3aed6de6ae0..fda15eaaaed 100644 --- a/libgo/go/go/internal/gcimporter/gcimporter.go +++ b/libgo/go/go/internal/gcimporter/gcimporter.go @@ -143,7 +143,7 @@ func Import(fset *token.FileSet, packages map[string]*types.Package, path, srcDi switch hdr { case "$$\n": - err = fmt.Errorf("import %q: old export format no longer supported (recompile library)", path) + err = fmt.Errorf("import %q: old textual export format no longer supported (recompile library)", path) case "$$B\n": var data []byte @@ -158,23 +158,16 @@ func Import(fset *token.FileSet, packages map[string]*types.Package, path, srcDi if len(data) > 0 && data[0] == 'i' { _, pkg, err = iImportData(fset, packages, data[1:], id) } else { - _, pkg, err = BImportData(fset, packages, data, id) + err = fmt.Errorf("import %q: old binary export format no longer supported (recompile library)", path) } default: - err = fmt.Errorf("unknown export data header: %q", hdr) + err = fmt.Errorf("import %q: unknown export data header: %q", path, hdr) } return } -func deref(typ types.Type) types.Type { - if p, _ := typ.(*types.Pointer); p != nil { - return p.Elem() - } - return typ -} - type byPath []*types.Package func (a byPath) Len() int { return len(a) } diff --git a/libgo/go/go/internal/gcimporter/gcimporter_test.go b/libgo/go/go/internal/gcimporter/gcimporter_test.go index df93f3f0628..663753a18a0 100644 --- a/libgo/go/go/internal/gcimporter/gcimporter_test.go +++ b/libgo/go/go/internal/gcimporter/gcimporter_test.go @@ -26,8 +26,7 @@ import ( // import. func skipSpecialPlatforms(t *testing.T) { switch platform := runtime.GOOS + "-" + runtime.GOARCH; platform { - case "darwin-arm", - "darwin-arm64": + case "darwin-arm64": t.Skipf("no compiled packages available for import on %s", platform) } } @@ -176,10 +175,20 @@ func TestVersionHandling(t *testing.T) { // test that export data can be imported _, err := Import(fset, make(map[string]*types.Package), pkgpath, dir, nil) if err != nil { + // ok to fail if it fails with a no longer supported error for select files + if strings.Contains(err.Error(), "no longer supported") { + switch name { + case "test_go1.7_0.a", "test_go1.7_1.a", + "test_go1.8_4.a", "test_go1.8_5.a", + "test_go1.11_6b.a", "test_go1.11_999b.a": + continue + } + // fall through + } // ok to fail if it fails with a newer version error for select files if strings.Contains(err.Error(), "newer version") { switch name { - case "test_go1.11_999b.a", "test_go1.11_999i.a": + case "test_go1.11_999i.a": continue } // fall through @@ -247,7 +256,7 @@ var importedObjectTests = []struct { {"math.Pi", "const Pi untyped float"}, {"math.Sin", "func Sin(x float64) float64"}, {"go/ast.NotNilFilter", "func NotNilFilter(_ string, v reflect.Value) bool"}, - {"go/internal/gcimporter.BImportData", "func BImportData(fset *go/token.FileSet, imports map[string]*go/types.Package, data []byte, path string) (_ int, pkg *go/types.Package, err error)"}, + {"go/internal/gcimporter.FindPkg", "func FindPkg(path string, srcDir string) (filename string, id string)"}, // interfaces {"context.Context", "type Context interface{Deadline() (deadline time.Time, ok bool); Done() <-chan struct{}; Err() error; Value(key interface{}) interface{}}"}, diff --git a/libgo/go/go/internal/gcimporter/support.go b/libgo/go/go/internal/gcimporter/support.go new file mode 100644 index 00000000000..2de7cacd2d9 --- /dev/null +++ b/libgo/go/go/internal/gcimporter/support.go @@ -0,0 +1,127 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements support functionality for iimport.go. + +package gcimporter + +import ( + "fmt" + "go/token" + "go/types" + "sync" +) + +func errorf(format string, args ...interface{}) { + panic(fmt.Sprintf(format, args...)) +} + +const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go + +// Synthesize a token.Pos +type fakeFileSet struct { + fset *token.FileSet + files map[string]*token.File +} + +func (s *fakeFileSet) pos(file string, line, column int) token.Pos { + // TODO(mdempsky): Make use of column. + + // Since we don't know the set of needed file positions, we + // reserve maxlines positions per file. + const maxlines = 64 * 1024 + f := s.files[file] + if f == nil { + f = s.fset.AddFile(file, -1, maxlines) + s.files[file] = f + // Allocate the fake linebreak indices on first use. + // TODO(adonovan): opt: save ~512KB using a more complex scheme? + fakeLinesOnce.Do(func() { + fakeLines = make([]int, maxlines) + for i := range fakeLines { + fakeLines[i] = i + } + }) + f.SetLines(fakeLines) + } + + if line > maxlines { + line = 1 + } + + // Treat the file as if it contained only newlines + // and column=1: use the line number as the offset. + return f.Pos(line - 1) +} + +var ( + fakeLines []int + fakeLinesOnce sync.Once +) + +func chanDir(d int) types.ChanDir { + // tag values must match the constants in cmd/compile/internal/gc/go.go + switch d { + case 1 /* Crecv */ : + return types.RecvOnly + case 2 /* Csend */ : + return types.SendOnly + case 3 /* Cboth */ : + return types.SendRecv + default: + errorf("unexpected channel dir %d", d) + return 0 + } +} + +var predeclared = []types.Type{ + // basic types + types.Typ[types.Bool], + types.Typ[types.Int], + types.Typ[types.Int8], + types.Typ[types.Int16], + types.Typ[types.Int32], + types.Typ[types.Int64], + types.Typ[types.Uint], + types.Typ[types.Uint8], + types.Typ[types.Uint16], + types.Typ[types.Uint32], + types.Typ[types.Uint64], + types.Typ[types.Uintptr], + types.Typ[types.Float32], + types.Typ[types.Float64], + types.Typ[types.Complex64], + types.Typ[types.Complex128], + types.Typ[types.String], + + // basic type aliases + types.Universe.Lookup("byte").Type(), + types.Universe.Lookup("rune").Type(), + + // error + types.Universe.Lookup("error").Type(), + + // untyped types + types.Typ[types.UntypedBool], + types.Typ[types.UntypedInt], + types.Typ[types.UntypedRune], + types.Typ[types.UntypedFloat], + types.Typ[types.UntypedComplex], + types.Typ[types.UntypedString], + types.Typ[types.UntypedNil], + + // package unsafe + types.Typ[types.UnsafePointer], + + // invalid type + types.Typ[types.Invalid], // only appears in packages with errors + + // used internally by gc; never used by this package or in .a files + anyType{}, +} + +type anyType struct{} + +func (t anyType) Underlying() types.Type { return t } +func (t anyType) String() string { return "any" } diff --git a/libgo/go/go/internal/srcimporter/srcimporter.go b/libgo/go/go/internal/srcimporter/srcimporter.go index 2a6c274424d..90bb3a9bc11 100644 --- a/libgo/go/go/internal/srcimporter/srcimporter.go +++ b/libgo/go/go/internal/srcimporter/srcimporter.go @@ -14,9 +14,13 @@ import ( "go/token" "go/types" "io" + "io/ioutil" "os" + "os/exec" "path/filepath" + "strings" "sync" + _ "unsafe" // for go:linkname ) // An Importer provides the context for importing packages from source code. @@ -115,7 +119,6 @@ func (p *Importer) ImportFrom(path, srcDir string, mode types.ImportMode) (*type var firstHardErr error conf := types.Config{ IgnoreFuncBodies: true, - FakeImportC: true, // continue type-checking after the first error Error: func(err error) { if firstHardErr == nil && !err.(types.Error).Soft { @@ -125,6 +128,21 @@ func (p *Importer) ImportFrom(path, srcDir string, mode types.ImportMode) (*type Importer: p, Sizes: p.sizes, } + if len(bp.CgoFiles) > 0 { + if p.ctxt.OpenFile != nil { + // cgo, gcc, pkg-config, etc. do not support + // build.Context's VFS. + conf.FakeImportC = true + } else { + setUsesCgo(&conf) + file, err := p.cgo(bp) + if err != nil { + return nil, err + } + files = append(files, file) + } + } + pkg, err = conf.Check(bp.ImportPath, p.fset, files, nil) if err != nil { // If there was a hard error it is possibly unsafe @@ -181,6 +199,47 @@ func (p *Importer) parseFiles(dir string, filenames []string) ([]*ast.File, erro return files, nil } +func (p *Importer) cgo(bp *build.Package) (*ast.File, error) { + tmpdir, err := ioutil.TempDir("", "srcimporter") + if err != nil { + return nil, err + } + defer os.RemoveAll(tmpdir) + + args := []string{"go", "tool", "cgo", "-objdir", tmpdir} + if bp.Goroot { + switch bp.ImportPath { + case "runtime/cgo": + args = append(args, "-import_runtime_cgo=false", "-import_syscall=false") + case "runtime/race": + args = append(args, "-import_syscall=false") + } + } + args = append(args, "--") + args = append(args, strings.Fields(os.Getenv("CGO_CPPFLAGS"))...) + args = append(args, bp.CgoCPPFLAGS...) + if len(bp.CgoPkgConfig) > 0 { + cmd := exec.Command("pkg-config", append([]string{"--cflags"}, bp.CgoPkgConfig...)...) + out, err := cmd.CombinedOutput() + if err != nil { + return nil, err + } + args = append(args, strings.Fields(string(out))...) + } + args = append(args, "-I", tmpdir) + args = append(args, strings.Fields(os.Getenv("CGO_CFLAGS"))...) + args = append(args, bp.CgoCFLAGS...) + args = append(args, bp.CgoFiles...) + + cmd := exec.Command(args[0], args[1:]...) + cmd.Dir = bp.Dir + if err := cmd.Run(); err != nil { + return nil, err + } + + return parser.ParseFile(p.fset, filepath.Join(tmpdir, "_cgo_gotypes.go"), nil, 0) +} + // context-controlled file system operations func (p *Importer) absPath(path string) (string, error) { @@ -202,3 +261,6 @@ func (p *Importer) joinPath(elem ...string) string { } return filepath.Join(elem...) } + +//go:linkname setUsesCgo go/types.srcimporter_setUsesCgo +func setUsesCgo(conf *types.Config) diff --git a/libgo/go/go/internal/srcimporter/srcimporter_test.go b/libgo/go/go/internal/srcimporter/srcimporter_test.go index 56549434d14..102ac43f945 100644 --- a/libgo/go/go/internal/srcimporter/srcimporter_test.go +++ b/libgo/go/go/internal/srcimporter/srcimporter_test.go @@ -5,11 +5,13 @@ package srcimporter import ( + "flag" "go/build" "go/token" "go/types" "internal/testenv" "io/ioutil" + "os" "path" "path/filepath" "runtime" @@ -18,6 +20,14 @@ import ( "time" ) +func TestMain(m *testing.M) { + flag.Parse() + if goTool, err := testenv.GoTool(); err == nil { + os.Setenv("PATH", filepath.Dir(goTool)+string(os.PathListSeparator)+os.Getenv("PATH")) + } + os.Exit(m.Run()) +} + const maxTime = 2 * time.Second var importer = New(&build.Default, token.NewFileSet(), make(map[string]*types.Package)) @@ -232,3 +242,14 @@ func TestIssue23092(t *testing.T) { func TestIssue24392(t *testing.T) { testImportPath(t, "go/internal/srcimporter/testdata/issue24392") } + +func TestCgo(t *testing.T) { + testenv.MustHaveGoBuild(t) + testenv.MustHaveCGO(t) + + importer := New(&build.Default, token.NewFileSet(), make(map[string]*types.Package)) + _, err := importer.ImportFrom("./misc/cgo/test", runtime.GOROOT(), 0) + if err != nil { + t.Fatalf("Import failed: %v", err) + } +} diff --git a/libgo/go/go/printer/nodes.go b/libgo/go/go/printer/nodes.go index e4cb58a87fc..95b9e918917 100644 --- a/libgo/go/go/printer/nodes.go +++ b/libgo/go/go/printer/nodes.go @@ -791,6 +791,9 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) { } case *ast.BasicLit: + if p.Config.Mode&normalizeNumbers != 0 { + x = normalizedNumber(x) + } p.print(x) case *ast.FuncLit: @@ -971,6 +974,66 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) { } } +// normalizedNumber rewrites base prefixes and exponents +// of numbers to use lower-case letters (0X123 to 0x123 and 1.2E3 to 1.2e3), +// and removes leading 0's from integer imaginary literals (0765i to 765i). +// It leaves hexadecimal digits alone. +// +// normalizedNumber doesn't modify the ast.BasicLit value lit points to. +// If lit is not a number or a number in canonical format already, +// lit is returned as is. Otherwise a new ast.BasicLit is created. +func normalizedNumber(lit *ast.BasicLit) *ast.BasicLit { + if lit.Kind != token.INT && lit.Kind != token.FLOAT && lit.Kind != token.IMAG { + return lit // not a number - nothing to do + } + if len(lit.Value) < 2 { + return lit // only one digit (common case) - nothing to do + } + // len(lit.Value) >= 2 + + // We ignore lit.Kind because for lit.Kind == token.IMAG the literal may be an integer + // or floating-point value, decimal or not. Instead, just consider the literal pattern. + x := lit.Value + switch x[:2] { + default: + // 0-prefix octal, decimal int, or float (possibly with 'i' suffix) + if i := strings.LastIndexByte(x, 'E'); i >= 0 { + x = x[:i] + "e" + x[i+1:] + break + } + // remove leading 0's from integer (but not floating-point) imaginary literals + if x[len(x)-1] == 'i' && strings.IndexByte(x, '.') < 0 && strings.IndexByte(x, 'e') < 0 { + x = strings.TrimLeft(x, "0_") + if x == "i" { + x = "0i" + } + } + case "0X": + x = "0x" + x[2:] + // possibly a hexadecimal float + if i := strings.LastIndexByte(x, 'P'); i >= 0 { + x = x[:i] + "p" + x[i+1:] + } + case "0x": + // possibly a hexadecimal float + i := strings.LastIndexByte(x, 'P') + if i == -1 { + return lit // nothing to do + } + x = x[:i] + "p" + x[i+1:] + case "0O": + x = "0o" + x[2:] + case "0o": + return lit // nothing to do + case "0B": + x = "0b" + x[2:] + case "0b": + return lit // nothing to do + } + + return &ast.BasicLit{ValuePos: lit.ValuePos, Kind: lit.Kind, Value: x} +} + func (p *printer) possibleSelectorExpr(expr ast.Expr, prec1, depth int) bool { if x, ok := expr.(*ast.SelectorExpr); ok { return p.selectorExpr(x, depth, true) diff --git a/libgo/go/go/printer/performance_test.go b/libgo/go/go/printer/performance_test.go index 5b29affcb7d..2e67154e6b4 100644 --- a/libgo/go/go/printer/performance_test.go +++ b/libgo/go/go/printer/performance_test.go @@ -20,7 +20,7 @@ import ( var testfile *ast.File func testprint(out io.Writer, file *ast.File) { - if err := (&Config{TabIndent | UseSpaces, 8, 0}).Fprint(out, fset, file); err != nil { + if err := (&Config{TabIndent | UseSpaces | normalizeNumbers, 8, 0}).Fprint(out, fset, file); err != nil { log.Fatalf("print error: %s", err) } } diff --git a/libgo/go/go/printer/printer.go b/libgo/go/go/printer/printer.go index 9143442a27c..0077afeaff7 100644 --- a/libgo/go/go/printer/printer.go +++ b/libgo/go/go/printer/printer.go @@ -1278,6 +1278,22 @@ const ( SourcePos // emit //line directives to preserve original source positions ) +// The mode below is not included in printer's public API because +// editing code text is deemed out of scope. Because this mode is +// unexported, it's also possible to modify or remove it based on +// the evolving needs of go/format and cmd/gofmt without breaking +// users. See discussion in CL 240683. +const ( + // normalizeNumbers means to canonicalize number + // literal prefixes and exponents while printing. + // + // This value is known in and used by go/format and cmd/gofmt. + // It is currently more convenient and performant for those + // packages to apply number normalization during printing, + // rather than by modifying the AST in advance. + normalizeNumbers Mode = 1 << 30 +) + // A Config node controls the output of Fprint. type Config struct { Mode Mode // default: 0 diff --git a/libgo/go/go/printer/printer_test.go b/libgo/go/go/printer/printer_test.go index 8f9cd534b43..b64bc6bfb7d 100644 --- a/libgo/go/go/printer/printer_test.go +++ b/libgo/go/go/printer/printer_test.go @@ -33,6 +33,7 @@ type checkMode uint const ( export checkMode = 1 << iota rawFormat + normNumber idempotent ) @@ -57,6 +58,9 @@ func format(src []byte, mode checkMode) ([]byte, error) { if mode&rawFormat != 0 { cfg.Mode |= RawFormat } + if mode&normNumber != 0 { + cfg.Mode |= normalizeNumbers + } // print AST var buf bytes.Buffer @@ -165,7 +169,7 @@ func runcheck(t *testing.T, source, golden string, mode checkMode) { func check(t *testing.T, source, golden string, mode checkMode) { // run the test - cc := make(chan int) + cc := make(chan int, 1) go func() { runcheck(t, source, golden, mode) cc <- 0 @@ -200,6 +204,8 @@ var data = []entry{ {"statements.input", "statements.golden", 0}, {"slow.input", "slow.golden", idempotent}, {"complit.input", "complit.x", export}, + {"go2numbers.input", "go2numbers.golden", idempotent}, + {"go2numbers.input", "go2numbers.norm", normNumber | idempotent}, } func TestFiles(t *testing.T) { diff --git a/libgo/go/go/printer/testdata/go2numbers.golden b/libgo/go/go/printer/testdata/go2numbers.golden new file mode 100644 index 00000000000..3c12049860d --- /dev/null +++ b/libgo/go/go/printer/testdata/go2numbers.golden @@ -0,0 +1,186 @@ +package p + +const ( + // 0-octals + _ = 0 + _ = 0123 + _ = 0123456 + + _ = 0_123 + _ = 0123_456 + + // decimals + _ = 1 + _ = 1234 + _ = 1234567 + + _ = 1_234 + _ = 1_234_567 + + // hexadecimals + _ = 0x0 + _ = 0x1234 + _ = 0xcafef00d + + _ = 0X0 + _ = 0X1234 + _ = 0XCAFEf00d + + _ = 0X_0 + _ = 0X_1234 + _ = 0X_CAFE_f00d + + // octals + _ = 0o0 + _ = 0o1234 + _ = 0o01234567 + + _ = 0O0 + _ = 0O1234 + _ = 0O01234567 + + _ = 0o_0 + _ = 0o_1234 + _ = 0o0123_4567 + + _ = 0O_0 + _ = 0O_1234 + _ = 0O0123_4567 + + // binaries + _ = 0b0 + _ = 0b1011 + _ = 0b00101101 + + _ = 0B0 + _ = 0B1011 + _ = 0B00101101 + + _ = 0b_0 + _ = 0b10_11 + _ = 0b_0010_1101 + + // decimal floats + _ = 0. + _ = 123. + _ = 0123. + + _ = .0 + _ = .123 + _ = .0123 + + _ = 0e0 + _ = 123e+0 + _ = 0123E-1 + + _ = 0e-0 + _ = 123E+0 + _ = 0123E123 + + _ = 0.e+1 + _ = 123.E-10 + _ = 0123.e123 + + _ = .0e-1 + _ = .123E+10 + _ = .0123E123 + + _ = 0.0 + _ = 123.123 + _ = 0123.0123 + + _ = 0.0e1 + _ = 123.123E-10 + _ = 0123.0123e+456 + + _ = 1_2_3. + _ = 0_123. + + _ = 0_0e0 + _ = 1_2_3e0 + _ = 0_123e0 + + _ = 0e-0_0 + _ = 1_2_3E+0 + _ = 0123E1_2_3 + + _ = 0.e+1 + _ = 123.E-1_0 + _ = 01_23.e123 + + _ = .0e-1 + _ = .123E+10 + _ = .0123E123 + + _ = 1_2_3.123 + _ = 0123.01_23 + + // hexadecimal floats + _ = 0x0.p+0 + _ = 0Xdeadcafe.p-10 + _ = 0x1234.P123 + + _ = 0x.1p-0 + _ = 0X.deadcafep2 + _ = 0x.1234P+10 + + _ = 0x0p0 + _ = 0Xdeadcafep+1 + _ = 0x1234P-10 + + _ = 0x0.0p0 + _ = 0Xdead.cafep+1 + _ = 0x12.34P-10 + + _ = 0Xdead_cafep+1 + _ = 0x_1234P-10 + + _ = 0X_dead_cafe.p-10 + _ = 0x12_34.P1_2_3 + _ = 0X1_2_3_4.P-1_2_3 + + // imaginaries + _ = 0i + _ = 00i + _ = 08i + _ = 0000000000i + _ = 0123i + _ = 0000000123i + _ = 0000056789i + _ = 1234i + _ = 1234567i + + _ = 0i + _ = 0_0i + _ = 0_8i + _ = 0_000_000_000i + _ = 0_123i + _ = 0_000_000_123i + _ = 0_000_056_789i + _ = 1_234i + _ = 1_234_567i + + _ = 0.i + _ = 123.i + _ = 0123.i + _ = 000123.i + + _ = 0e0i + _ = 123e0i + _ = 0123E0i + _ = 000123E0i + + _ = 0.e+1i + _ = 123.E-1_0i + _ = 01_23.e123i + _ = 00_01_23.e123i + + _ = 0b1010i + _ = 0B1010i + _ = 0o660i + _ = 0O660i + _ = 0xabcDEFi + _ = 0XabcDEFi + _ = 0xabcDEFP0i + _ = 0XabcDEFp0i +) diff --git a/libgo/go/go/printer/testdata/go2numbers.input b/libgo/go/go/printer/testdata/go2numbers.input new file mode 100644 index 00000000000..f3e7828d948 --- /dev/null +++ b/libgo/go/go/printer/testdata/go2numbers.input @@ -0,0 +1,186 @@ +package p + +const ( + // 0-octals + _ = 0 + _ = 0123 + _ = 0123456 + + _ = 0_123 + _ = 0123_456 + + // decimals + _ = 1 + _ = 1234 + _ = 1234567 + + _ = 1_234 + _ = 1_234_567 + + // hexadecimals + _ = 0x0 + _ = 0x1234 + _ = 0xcafef00d + + _ = 0X0 + _ = 0X1234 + _ = 0XCAFEf00d + + _ = 0X_0 + _ = 0X_1234 + _ = 0X_CAFE_f00d + + // octals + _ = 0o0 + _ = 0o1234 + _ = 0o01234567 + + _ = 0O0 + _ = 0O1234 + _ = 0O01234567 + + _ = 0o_0 + _ = 0o_1234 + _ = 0o0123_4567 + + _ = 0O_0 + _ = 0O_1234 + _ = 0O0123_4567 + + // binaries + _ = 0b0 + _ = 0b1011 + _ = 0b00101101 + + _ = 0B0 + _ = 0B1011 + _ = 0B00101101 + + _ = 0b_0 + _ = 0b10_11 + _ = 0b_0010_1101 + + // decimal floats + _ = 0. + _ = 123. + _ = 0123. + + _ = .0 + _ = .123 + _ = .0123 + + _ = 0e0 + _ = 123e+0 + _ = 0123E-1 + + _ = 0e-0 + _ = 123E+0 + _ = 0123E123 + + _ = 0.e+1 + _ = 123.E-10 + _ = 0123.e123 + + _ = .0e-1 + _ = .123E+10 + _ = .0123E123 + + _ = 0.0 + _ = 123.123 + _ = 0123.0123 + + _ = 0.0e1 + _ = 123.123E-10 + _ = 0123.0123e+456 + + _ = 1_2_3. + _ = 0_123. + + _ = 0_0e0 + _ = 1_2_3e0 + _ = 0_123e0 + + _ = 0e-0_0 + _ = 1_2_3E+0 + _ = 0123E1_2_3 + + _ = 0.e+1 + _ = 123.E-1_0 + _ = 01_23.e123 + + _ = .0e-1 + _ = .123E+10 + _ = .0123E123 + + _ = 1_2_3.123 + _ = 0123.01_23 + + // hexadecimal floats + _ = 0x0.p+0 + _ = 0Xdeadcafe.p-10 + _ = 0x1234.P123 + + _ = 0x.1p-0 + _ = 0X.deadcafep2 + _ = 0x.1234P+10 + + _ = 0x0p0 + _ = 0Xdeadcafep+1 + _ = 0x1234P-10 + + _ = 0x0.0p0 + _ = 0Xdead.cafep+1 + _ = 0x12.34P-10 + + _ = 0Xdead_cafep+1 + _ = 0x_1234P-10 + + _ = 0X_dead_cafe.p-10 + _ = 0x12_34.P1_2_3 + _ = 0X1_2_3_4.P-1_2_3 + + // imaginaries + _ = 0i + _ = 00i + _ = 08i + _ = 0000000000i + _ = 0123i + _ = 0000000123i + _ = 0000056789i + _ = 1234i + _ = 1234567i + + _ = 0i + _ = 0_0i + _ = 0_8i + _ = 0_000_000_000i + _ = 0_123i + _ = 0_000_000_123i + _ = 0_000_056_789i + _ = 1_234i + _ = 1_234_567i + + _ = 0.i + _ = 123.i + _ = 0123.i + _ = 000123.i + + _ = 0e0i + _ = 123e0i + _ = 0123E0i + _ = 000123E0i + + _ = 0.e+1i + _ = 123.E-1_0i + _ = 01_23.e123i + _ = 00_01_23.e123i + + _ = 0b1010i + _ = 0B1010i + _ = 0o660i + _ = 0O660i + _ = 0xabcDEFi + _ = 0XabcDEFi + _ = 0xabcDEFP0i + _ = 0XabcDEFp0i +) diff --git a/libgo/go/go/printer/testdata/go2numbers.norm b/libgo/go/go/printer/testdata/go2numbers.norm new file mode 100644 index 00000000000..855f0fc6087 --- /dev/null +++ b/libgo/go/go/printer/testdata/go2numbers.norm @@ -0,0 +1,186 @@ +package p + +const ( + // 0-octals + _ = 0 + _ = 0123 + _ = 0123456 + + _ = 0_123 + _ = 0123_456 + + // decimals + _ = 1 + _ = 1234 + _ = 1234567 + + _ = 1_234 + _ = 1_234_567 + + // hexadecimals + _ = 0x0 + _ = 0x1234 + _ = 0xcafef00d + + _ = 0x0 + _ = 0x1234 + _ = 0xCAFEf00d + + _ = 0x_0 + _ = 0x_1234 + _ = 0x_CAFE_f00d + + // octals + _ = 0o0 + _ = 0o1234 + _ = 0o01234567 + + _ = 0o0 + _ = 0o1234 + _ = 0o01234567 + + _ = 0o_0 + _ = 0o_1234 + _ = 0o0123_4567 + + _ = 0o_0 + _ = 0o_1234 + _ = 0o0123_4567 + + // binaries + _ = 0b0 + _ = 0b1011 + _ = 0b00101101 + + _ = 0b0 + _ = 0b1011 + _ = 0b00101101 + + _ = 0b_0 + _ = 0b10_11 + _ = 0b_0010_1101 + + // decimal floats + _ = 0. + _ = 123. + _ = 0123. + + _ = .0 + _ = .123 + _ = .0123 + + _ = 0e0 + _ = 123e+0 + _ = 0123e-1 + + _ = 0e-0 + _ = 123e+0 + _ = 0123e123 + + _ = 0.e+1 + _ = 123.e-10 + _ = 0123.e123 + + _ = .0e-1 + _ = .123e+10 + _ = .0123e123 + + _ = 0.0 + _ = 123.123 + _ = 0123.0123 + + _ = 0.0e1 + _ = 123.123e-10 + _ = 0123.0123e+456 + + _ = 1_2_3. + _ = 0_123. + + _ = 0_0e0 + _ = 1_2_3e0 + _ = 0_123e0 + + _ = 0e-0_0 + _ = 1_2_3e+0 + _ = 0123e1_2_3 + + _ = 0.e+1 + _ = 123.e-1_0 + _ = 01_23.e123 + + _ = .0e-1 + _ = .123e+10 + _ = .0123e123 + + _ = 1_2_3.123 + _ = 0123.01_23 + + // hexadecimal floats + _ = 0x0.p+0 + _ = 0xdeadcafe.p-10 + _ = 0x1234.p123 + + _ = 0x.1p-0 + _ = 0x.deadcafep2 + _ = 0x.1234p+10 + + _ = 0x0p0 + _ = 0xdeadcafep+1 + _ = 0x1234p-10 + + _ = 0x0.0p0 + _ = 0xdead.cafep+1 + _ = 0x12.34p-10 + + _ = 0xdead_cafep+1 + _ = 0x_1234p-10 + + _ = 0x_dead_cafe.p-10 + _ = 0x12_34.p1_2_3 + _ = 0x1_2_3_4.p-1_2_3 + + // imaginaries + _ = 0i + _ = 0i + _ = 8i + _ = 0i + _ = 123i + _ = 123i + _ = 56789i + _ = 1234i + _ = 1234567i + + _ = 0i + _ = 0i + _ = 8i + _ = 0i + _ = 123i + _ = 123i + _ = 56_789i + _ = 1_234i + _ = 1_234_567i + + _ = 0.i + _ = 123.i + _ = 0123.i + _ = 000123.i + + _ = 0e0i + _ = 123e0i + _ = 0123e0i + _ = 000123e0i + + _ = 0.e+1i + _ = 123.e-1_0i + _ = 01_23.e123i + _ = 00_01_23.e123i + + _ = 0b1010i + _ = 0b1010i + _ = 0o660i + _ = 0o660i + _ = 0xabcDEFi + _ = 0xabcDEFi + _ = 0xabcDEFp0i + _ = 0xabcDEFp0i +) diff --git a/libgo/go/go/token/position.go b/libgo/go/go/token/position.go index 3f5a390078d..d0dbc2998f7 100644 --- a/libgo/go/go/token/position.go +++ b/libgo/go/go/token/position.go @@ -58,8 +58,11 @@ func (pos Position) String() string { // larger, representation. // // The Pos value for a given file is a number in the range [base, base+size], -// where base and size are specified when adding the file to the file set via -// AddFile. +// where base and size are specified when a file is added to the file set. +// The difference between a Pos value and the corresponding file base +// corresponds to the byte offset of that position (represented by the Pos value) +// from the beginning of the file. Thus, the file base offset is the Pos value +// representing the first byte in the file. // // To create the Pos value for a specific source offset (measured in bytes), // first add the respective file to the current file set using FileSet.AddFile @@ -364,6 +367,22 @@ func (f *File) Position(p Pos) (pos Position) { // Methods of file sets are synchronized; multiple goroutines // may invoke them concurrently. // +// The byte offsets for each file in a file set are mapped into +// distinct (integer) intervals, one interval [base, base+size] +// per file. Base represents the first byte in the file, and size +// is the corresponding file size. A Pos value is a value in such +// an interval. By determining the interval a Pos value belongs +// to, the file, its file base, and thus the byte offset (position) +// the Pos value is representing can be computed. +// +// When adding a new file, a file base must be provided. That can +// be any integer value that is past the end of any interval of any +// file already in the file set. For convenience, FileSet.Base provides +// such a value, which is simply the end of the Pos interval of the most +// recently added file, plus one. Unless there is a need to extend an +// interval later, using the FileSet.Base should be used as argument +// for FileSet.AddFile. +// type FileSet struct { mutex sync.RWMutex // protects the file set base int // base offset for the next file diff --git a/libgo/go/go/types/api.go b/libgo/go/go/types/api.go index 2a21ad0c53f..2e2e08dce62 100644 --- a/libgo/go/go/types/api.go +++ b/libgo/go/go/types/api.go @@ -32,6 +32,7 @@ import ( "go/ast" "go/constant" "go/token" + _ "unsafe" // for go:linkname ) // An Error describes a type-checking error; it implements the error interface. @@ -105,6 +106,15 @@ type Config struct { // Do not use casually! FakeImportC bool + // If go115UsesCgo is set, the type checker expects the + // _cgo_gotypes.go file generated by running cmd/cgo to be + // provided as a package source file. Qualified identifiers + // referring to package C will be resolved to cgo-provided + // declarations within _cgo_gotypes.go. + // + // It is an error to set both FakeImportC and go115UsesCgo. + go115UsesCgo bool + // If Error != nil, it is called with each error found // during type checking; err has dynamic type Error. // Secondary errors (for instance, to enumerate all types @@ -131,6 +141,11 @@ type Config struct { DisableUnusedImportCheck bool } +//go:linkname srcimporter_setUsesCgo +func srcimporter_setUsesCgo(conf *Config) { + conf.go115UsesCgo = true +} + // Info holds result type information for a type-checked package. // Only the information for which a map is provided is collected. // If the package has type errors, the collected information may @@ -281,7 +296,7 @@ func (tv TypeAndValue) IsBuiltin() bool { // nil Value. func (tv TypeAndValue) IsValue() bool { switch tv.mode { - case constant_, variable, mapindex, value, commaok: + case constant_, variable, mapindex, value, commaok, commaerr: return true } return false diff --git a/libgo/go/go/types/assignments.go b/libgo/go/go/types/assignments.go index efa0cbba502..34a9d7843d9 100644 --- a/libgo/go/go/types/assignments.go +++ b/libgo/go/go/types/assignments.go @@ -22,7 +22,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) { switch x.mode { case invalid: return // error reported before - case constant_, variable, mapindex, value, commaok: + case constant_, variable, mapindex, value, commaok, commaerr: // ok default: unreachable() diff --git a/libgo/go/go/types/builtins.go b/libgo/go/go/types/builtins.go index 3756303dfbc..a445ebf1c6b 100644 --- a/libgo/go/go/types/builtins.go +++ b/libgo/go/go/types/builtins.go @@ -441,10 +441,13 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b check.errorf(call.Pos(), "%v expects %d or %d arguments; found %d", call, min, min+1, nargs) return } + types := []Type{T} var sizes []int64 // constant integer arguments, if any for _, arg := range call.Args[1:] { - if s, ok := check.index(arg, -1); ok && s >= 0 { - sizes = append(sizes, s) + typ, size := check.index(arg, -1) // ok to continue with typ == Typ[Invalid] + types = append(types, typ) + if size >= 0 { + sizes = append(sizes, size) } } if len(sizes) == 2 && sizes[0] > sizes[1] { @@ -454,8 +457,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b x.mode = value x.typ = T if check.Types != nil { - params := [...]Type{T, Typ[Int], Typ[Int]} - check.recordBuiltinType(call.Fun, makeSig(x.typ, params[:1+len(sizes)]...)) + check.recordBuiltinType(call.Fun, makeSig(x.typ, types...)) } case _New: diff --git a/libgo/go/go/types/builtins_test.go b/libgo/go/go/types/builtins_test.go index 67c49732bf5..092e524b87c 100644 --- a/libgo/go/go/types/builtins_test.go +++ b/libgo/go/go/types/builtins_test.go @@ -71,6 +71,22 @@ var builtinCalls = []struct { {"make", `_ = make([]int, 10)`, `func([]int, int) []int`}, {"make", `type T []byte; _ = make(T, 10, 20)`, `func(p.T, int, int) p.T`}, + // issue #37349 + {"make", ` _ = make([]int, 0 )`, `func([]int, int) []int`}, + {"make", `var l int; _ = make([]int, l )`, `func([]int, int) []int`}, + {"make", ` _ = make([]int, 0, 0)`, `func([]int, int, int) []int`}, + {"make", `var l int; _ = make([]int, l, 0)`, `func([]int, int, int) []int`}, + {"make", `var c int; _ = make([]int, 0, c)`, `func([]int, int, int) []int`}, + {"make", `var l, c int; _ = make([]int, l, c)`, `func([]int, int, int) []int`}, + + // issue #37393 + {"make", ` _ = make([]int , 0 )`, `func([]int, int) []int`}, + {"make", `var l byte ; _ = make([]int8 , l )`, `func([]int8, byte) []int8`}, + {"make", ` _ = make([]int16 , 0, 0)`, `func([]int16, int, int) []int16`}, + {"make", `var l int16; _ = make([]string , l, 0)`, `func([]string, int16, int) []string`}, + {"make", `var c int32; _ = make([]float64 , 0, c)`, `func([]float64, int, int32) []float64`}, + {"make", `var l, c uint ; _ = make([]complex128, l, c)`, `func([]complex128, uint, uint) []complex128`}, + {"new", `_ = new(int)`, `func(int) *int`}, {"new", `type T struct{}; _ = new(T)`, `func(p.T) *p.T`}, diff --git a/libgo/go/go/types/call.go b/libgo/go/go/types/call.go index 689ef8744c4..be4cfdf9eb4 100644 --- a/libgo/go/go/types/call.go +++ b/libgo/go/go/types/call.go @@ -9,6 +9,8 @@ package types import ( "go/ast" "go/token" + "strings" + "unicode" ) func (check *Checker) call(x *operand, e *ast.CallExpr) exprKind { @@ -54,6 +56,8 @@ func (check *Checker) call(x *operand, e *ast.CallExpr) exprKind { default: // function/method call + cgocall := x.mode == cgofunc + sig, _ := x.typ.Underlying().(*Signature) if sig == nil { check.invalidOp(x.pos(), "cannot call non-function %s", x) @@ -74,7 +78,11 @@ func (check *Checker) call(x *operand, e *ast.CallExpr) exprKind { case 0: x.mode = novalue case 1: - x.mode = value + if cgocall { + x.mode = commaerr + } else { + x.mode = value + } x.typ = sig.results.vars[0].typ // unpack tuple default: x.mode = value @@ -192,10 +200,13 @@ func unpack(get getter, n int, allowCommaOk bool) (getter, int, bool) { }, t.Len(), false } - if x0.mode == mapindex || x0.mode == commaok { + if x0.mode == mapindex || x0.mode == commaok || x0.mode == commaerr { // comma-ok value if allowCommaOk { a := [2]Type{x0.typ, Typ[UntypedBool]} + if x0.mode == commaerr { + a[1] = universeError + } return func(x *operand, i int) { x.mode = value x.expr = x0.expr @@ -302,6 +313,17 @@ func (check *Checker) argument(sig *Signature, i int, x *operand, ellipsis token check.assignment(x, typ, context) } +var cgoPrefixes = [...]string{ + "_Ciconst_", + "_Cfconst_", + "_Csconst_", + "_Ctype_", + "_Cvar_", // actually a pointer to the var + "_Cfpvar_fp_", + "_Cfunc_", + "_Cmacro_", // function to evaluate the expanded expression +} + func (check *Checker) selector(x *operand, e *ast.SelectorExpr) { // these must be declared before the "goto Error" statements var ( @@ -322,16 +344,43 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) { check.recordUse(ident, pname) pname.used = true pkg := pname.imported - exp := pkg.scope.Lookup(sel) - if exp == nil { - if !pkg.fake { - check.errorf(e.Sel.Pos(), "%s not declared by package %s", sel, pkg.name) + + var exp Object + funcMode := value + if pkg.cgo { + // cgo special cases C.malloc: it's + // rewritten to _CMalloc and does not + // support two-result calls. + if sel == "malloc" { + sel = "_CMalloc" + } else { + funcMode = cgofunc + } + for _, prefix := range cgoPrefixes { + // cgo objects are part of the current package (in file + // _cgo_gotypes.go). Use regular lookup. + _, exp = check.scope.LookupParent(prefix+sel, check.pos) + if exp != nil { + break + } + } + if exp == nil { + check.errorf(e.Sel.Pos(), "%s not declared by package C", sel) + goto Error + } + check.objDecl(exp, nil) + } else { + exp = pkg.scope.Lookup(sel) + if exp == nil { + if !pkg.fake { + check.errorf(e.Sel.Pos(), "%s not declared by package %s", sel, pkg.name) + } + goto Error + } + if !exp.Exported() { + check.errorf(e.Sel.Pos(), "%s not exported by package %s", sel, pkg.name) + // ok to continue } - goto Error - } - if !exp.Exported() { - check.errorf(e.Sel.Pos(), "%s not exported by package %s", sel, pkg.name) - // ok to continue } check.recordUse(e.Sel, exp) @@ -349,9 +398,16 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) { case *Var: x.mode = variable x.typ = exp.typ + if pkg.cgo && strings.HasPrefix(exp.name, "_Cvar_") { + x.typ = x.typ.(*Pointer).base + } case *Func: - x.mode = value + x.mode = funcMode x.typ = exp.typ + if pkg.cgo && strings.HasPrefix(exp.name, "_Cmacro_") { + x.mode = value + x.typ = x.typ.(*Signature).results.vars[0].typ + } case *Builtin: x.mode = builtin x.typ = exp.typ @@ -375,12 +431,24 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) { switch { case index != nil: // TODO(gri) should provide actual type where the conflict happens - check.errorf(e.Sel.Pos(), "ambiguous selector %s", sel) + check.errorf(e.Sel.Pos(), "ambiguous selector %s.%s", x.expr, sel) case indirect: - // TODO(gri) be more specific with this error message - check.errorf(e.Sel.Pos(), "%s is not in method set of %s", sel, x.typ) + check.errorf(e.Sel.Pos(), "cannot call pointer method %s on %s", sel, x.typ) default: - // TODO(gri) should check if capitalization of sel matters and provide better error message in that case + // Check if capitalization of sel matters and provide better error + // message in that case. + if len(sel) > 0 { + var changeCase string + if r := rune(sel[0]); unicode.IsUpper(r) { + changeCase = string(unicode.ToLower(r)) + sel[1:] + } else { + changeCase = string(unicode.ToUpper(r)) + sel[1:] + } + if obj, _, _ = check.lookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, changeCase); obj != nil { + check.errorf(e.Sel.Pos(), "%s.%s undefined (type %s has no field or method %s, but does have %s)", x.expr, sel, x.typ, sel, changeCase) + break + } + } check.errorf(e.Sel.Pos(), "%s.%s undefined (type %s has no field or method %s)", x.expr, sel, x.typ, sel) } goto Error diff --git a/libgo/go/go/types/check.go b/libgo/go/go/types/check.go index b599df1c50d..007babdf9d6 100644 --- a/libgo/go/go/types/check.go +++ b/libgo/go/go/types/check.go @@ -7,6 +7,7 @@ package types import ( + "errors" "go/ast" "go/constant" "go/token" @@ -247,7 +248,13 @@ func (check *Checker) handleBailout(err *error) { // Files checks the provided files as part of the checker's package. func (check *Checker) Files(files []*ast.File) error { return check.checkFiles(files) } +var errBadCgo = errors.New("cannot use FakeImportC and go115UsesCgo together") + func (check *Checker) checkFiles(files []*ast.File) (err error) { + if check.conf.FakeImportC && check.conf.go115UsesCgo { + return errBadCgo + } + defer check.handleBailout(&err) check.initFiles(files) @@ -316,7 +323,6 @@ func (check *Checker) recordTypeAndValue(x ast.Expr, mode operandMode, typ Type, if mode == invalid { return // omit } - assert(typ != nil) if mode == constant_ { assert(val != nil) assert(typ == Typ[Invalid] || isConstType(typ)) @@ -349,7 +355,7 @@ func (check *Checker) recordCommaOkTypes(x ast.Expr, a [2]Type) { if a[0] == nil || a[1] == nil { return } - assert(isTyped(a[0]) && isTyped(a[1]) && isBoolean(a[1])) + assert(isTyped(a[0]) && isTyped(a[1]) && (isBoolean(a[1]) || a[1] == universeError)) if m := check.Types; m != nil { for { tv := m[x] diff --git a/libgo/go/go/types/conversions.go b/libgo/go/go/types/conversions.go index 7ea8fd70aab..4a6bddb24c1 100644 --- a/libgo/go/go/types/conversions.go +++ b/libgo/go/go/types/conversions.go @@ -28,7 +28,7 @@ func (check *Checker) conversion(x *operand, T Type) { // If codepoint < 0 the absolute value is too large (or unknown) for // conversion. This is the same as converting any other out-of-range // value - let string(codepoint) do the work. - x.val = constant.MakeString(string(codepoint)) + x.val = constant.MakeString(string(rune(codepoint))) ok = true } case x.convertibleTo(check, T): diff --git a/libgo/go/go/types/example_test.go b/libgo/go/go/types/example_test.go index d041087ff7d..95bb2702ef3 100644 --- a/libgo/go/go/types/example_test.go +++ b/libgo/go/go/types/example_test.go @@ -120,6 +120,9 @@ import "fmt" type Celsius float64 func (c Celsius) String() string { return fmt.Sprintf("%g°C", c) } func (c *Celsius) SetF(f float64) { *c = Celsius(f - 32 / 9 * 5) } + +type S struct { I; m int } +type I interface { m() byte } ` fset := token.NewFileSet() f, err := parser.ParseFile(fset, "celsius.go", input, 0) @@ -147,6 +150,11 @@ func (c *Celsius) SetF(f float64) { *c = Celsius(f - 32 / 9 * 5) } fmt.Println() } + // Print the method set of S. + styp := pkg.Scope().Lookup("S").Type() + fmt.Printf("Method set of %s:\n", styp) + fmt.Println(types.NewMethodSet(styp)) + // no output for gccgo--can't import "fmt" // Method set of temperature.Celsius: // method (temperature.Celsius) String() string @@ -154,6 +162,9 @@ func (c *Celsius) SetF(f float64) { *c = Celsius(f - 32 / 9 * 5) } // Method set of *temperature.Celsius: // method (*temperature.Celsius) SetF(f float64) // method (*temperature.Celsius) String() string + // + // Method set of temperature.S: + // MethodSet {} } // ExampleInfo prints various facts recorded by the type checker in a diff --git a/libgo/go/go/types/expr.go b/libgo/go/go/types/expr.go index d49ccdf67e7..d1e892a9b70 100644 --- a/libgo/go/go/types/expr.go +++ b/libgo/go/go/types/expr.go @@ -868,8 +868,12 @@ func (check *Checker) binary(x *operand, e *ast.BinaryExpr, lhs, rhs ast.Expr, o // index checks an index expression for validity. // If max >= 0, it is the upper bound for index. -// If index is valid and the result i >= 0, then i is the constant value of index. -func (check *Checker) index(index ast.Expr, max int64) (i int64, valid bool) { +// If the result typ is != Typ[Invalid], index is valid and typ is its (possibly named) integer type. +// If the result val >= 0, index is valid and val is its constant int value. +func (check *Checker) index(index ast.Expr, max int64) (typ Type, val int64) { + typ = Typ[Invalid] + val = -1 + var x operand check.expr(&x, index) if x.mode == invalid { @@ -888,22 +892,24 @@ func (check *Checker) index(index ast.Expr, max int64) (i int64, valid bool) { return } + if x.mode != constant_ { + return x.typ, -1 + } + // a constant index i must be in bounds - if x.mode == constant_ { - if constant.Sign(x.val) < 0 { - check.invalidArg(x.pos(), "index %s must not be negative", &x) - return - } - i, valid = constant.Int64Val(constant.ToInt(x.val)) - if !valid || max >= 0 && i >= max { - check.errorf(x.pos(), "index %s is out of bounds", &x) - return i, false - } - // 0 <= i [ && i < max ] - return i, true + if constant.Sign(x.val) < 0 { + check.invalidArg(x.pos(), "index %s must not be negative", &x) + return + } + + v, valid := constant.Int64Val(constant.ToInt(x.val)) + if !valid || max >= 0 && v >= max { + check.errorf(x.pos(), "index %s is out of bounds", &x) + return } - return -1, true + // 0 <= v [ && v < max ] + return Typ[Int], v } // indexElts checks the elements (elts) of an array or slice composite literal @@ -919,7 +925,7 @@ func (check *Checker) indexedElts(elts []ast.Expr, typ Type, length int64) int64 validIndex := false eval := e if kv, _ := e.(*ast.KeyValueExpr); kv != nil { - if i, ok := check.index(kv.Key, length); ok { + if typ, i := check.index(kv.Key, length); typ != Typ[Invalid] { if i >= 0 { index = i validIndex = true @@ -1411,8 +1417,8 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { if length >= 0 { max = length + 1 } - if t, ok := check.index(expr, max); ok && t >= 0 { - x = t + if _, v := check.index(expr, max); v >= 0 { + x = v } case i == 0: // default is 0 for the first index @@ -1560,14 +1566,17 @@ func (check *Checker) typeAssertion(pos token.Pos, x *operand, xtyp *Interface, if method == nil { return } - var msg string - if wrongType { - msg = "wrong type for method" + if wrongType != nil { + if check.identical(method.typ, wrongType.typ) { + msg = fmt.Sprintf("missing method %s (%s has pointer receiver)", method.name, method.name) + } else { + msg = fmt.Sprintf("wrong type for method %s (have %s, want %s)", method.name, wrongType.typ, method.typ) + } } else { - msg = "missing method" + msg = "missing method " + method.name } - check.errorf(pos, "%s cannot have dynamic type %s (%s %s)", x, T, msg, method.name) + check.errorf(pos, "%s cannot have dynamic type %s (%s)", x, T, msg) } func (check *Checker) singleValue(x *operand) { diff --git a/libgo/go/go/types/lookup.go b/libgo/go/go/types/lookup.go index 342c8baab24..3c9ff182ec7 100644 --- a/libgo/go/go/types/lookup.go +++ b/libgo/go/go/types/lookup.go @@ -263,14 +263,19 @@ func (check *Checker) lookupType(m map[Type]int, typ Type) (int, bool) { // x is of interface type V). // func MissingMethod(V Type, T *Interface, static bool) (method *Func, wrongType bool) { - return (*Checker)(nil).missingMethod(V, T, static) + m, typ := (*Checker)(nil).missingMethod(V, T, static) + return m, typ != nil } // missingMethod is like MissingMethod but accepts a receiver. // The receiver may be nil if missingMethod is invoked through // an exported API call (such as MissingMethod), i.e., when all // methods have been type-checked. -func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method *Func, wrongType bool) { +// If the type has the correctly named method, but with the wrong +// signature, the existing method is returned as well. +// To improve error messages, also report the wrong signature +// when the method exists on *V instead of V. +func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method, wrongType *Func) { check.completeInterface(T) // fast path for common case @@ -286,10 +291,10 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method * switch { case obj == nil: if static { - return m, false + return m, nil } case !check.identical(obj.Type(), m.typ): - return m, true + return m, obj } } return @@ -299,10 +304,19 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method * for _, m := range T.allMethods { obj, _, _ := check.rawLookupFieldOrMethod(V, false, m.pkg, m.name) + // Check if *V implements this method of T. + if obj == nil { + ptr := NewPointer(V) + obj, _, _ = check.rawLookupFieldOrMethod(ptr, false, m.pkg, m.name) + if obj != nil { + return m, obj.(*Func) + } + } + // we must have a method (not a field of matching function type) f, _ := obj.(*Func) if f == nil { - return m, false + return m, nil } // methods may not have a fully set up signature yet @@ -311,7 +325,7 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method * } if !check.identical(f.typ, m.typ) { - return m, true + return m, f } } @@ -323,7 +337,7 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method * // method required by V and whether it is missing or just has the wrong type. // The receiver may be nil if assertableTo is invoked through an exported API call // (such as AssertableTo), i.e., when all methods have been type-checked. -func (check *Checker) assertableTo(V *Interface, T Type) (method *Func, wrongType bool) { +func (check *Checker) assertableTo(V *Interface, T Type) (method, wrongType *Func) { // no static check is required if T is an interface // spec: "If T is an interface type, x.(T) asserts that the // dynamic type of x implements the interface T." diff --git a/libgo/go/go/types/methodset.go b/libgo/go/go/types/methodset.go index a236fe2ea8b..c34d732b7ac 100644 --- a/libgo/go/go/types/methodset.go +++ b/libgo/go/go/types/methodset.go @@ -99,8 +99,8 @@ func NewMethodSet(T Type) *MethodSet { for len(current) > 0 { var next []embeddedType // embedded types found at current depth - // field and method sets at current depth, allocated lazily - var fset fieldSet + // field and method sets at current depth, indexed by names (Id's), and allocated lazily + var fset map[string]bool // we only care about the field names var mset methodSet for _, e := range current { @@ -131,7 +131,10 @@ func NewMethodSet(T Type) *MethodSet { switch t := typ.(type) { case *Struct: for i, f := range t.fields { - fset = fset.add(f, e.multiples) + if fset == nil { + fset = make(map[string]bool) + } + fset[f.Id()] = true // Embedded fields are always of the form T or *T where // T is a type name. If typ appeared multiple times at @@ -156,7 +159,7 @@ func NewMethodSet(T Type) *MethodSet { for k, m := range mset { if _, found := base[k]; !found { // Fields collide with methods of the same name at this depth. - if _, found := fset[k]; found { + if fset[k] { m = nil // collision } if base == nil { @@ -166,17 +169,14 @@ func NewMethodSet(T Type) *MethodSet { } } - // Multiple fields with matching names collide at this depth and shadow all - // entries further down; add them as collisions to base if no entries with - // matching names exist already. - for k, f := range fset { - if f == nil { - if _, found := base[k]; !found { - if base == nil { - base = make(methodSet) - } - base[k] = nil // collision + // Add all (remaining) fields at this depth as collisions (since they will + // hide any method further down) if no entries with matching names exist already. + for k := range fset { + if _, found := base[k]; !found { + if base == nil { + base = make(methodSet) } + base[k] = nil // collision } } @@ -207,33 +207,9 @@ func NewMethodSet(T Type) *MethodSet { return &MethodSet{list} } -// A fieldSet is a set of fields and name collisions. -// A collision indicates that multiple fields with the -// same unique id appeared. -type fieldSet map[string]*Var // a nil entry indicates a name collision - -// Add adds field f to the field set s. -// If multiples is set, f appears multiple times -// and is treated as a collision. -func (s fieldSet) add(f *Var, multiples bool) fieldSet { - if s == nil { - s = make(fieldSet) - } - key := f.Id() - // if f is not in the set, add it - if !multiples { - if _, found := s[key]; !found { - s[key] = f - return s - } - } - s[key] = nil // collision - return s -} - // A methodSet is a set of methods and name collisions. // A collision indicates that multiple methods with the -// same unique id appeared. +// same unique id, or a field with that id appeared. type methodSet map[string]*Selection // a nil entry indicates a name collision // Add adds all functions in list to the method set s. diff --git a/libgo/go/go/types/operand.go b/libgo/go/go/types/operand.go index 1259f443000..80d11e2f215 100644 --- a/libgo/go/go/types/operand.go +++ b/libgo/go/go/types/operand.go @@ -8,6 +8,7 @@ package types import ( "bytes" + "fmt" "go/ast" "go/constant" "go/token" @@ -26,6 +27,8 @@ const ( mapindex // operand is a map index expression (acts like a variable on lhs, commaok on rhs of an assignment) value // operand is a computed value commaok // like value, but operand may be used in a comma,ok expression + commaerr // like commaok, but second value is error, not boolean + cgofunc // operand is a cgo function ) var operandModeString = [...]string{ @@ -38,6 +41,8 @@ var operandModeString = [...]string{ mapindex: "map index expression", value: "value", commaok: "comma, ok expression", + commaerr: "comma, error expression", + cgofunc: "cgo function", } // An operand represents an intermediate value during type checking. @@ -93,6 +98,12 @@ func (x *operand) pos() token.Pos { // commaok ( ) // commaok ( of type ) // +// commaerr ( ) +// commaerr ( of type ) +// +// cgofunc ( ) +// cgofunc ( of type ) +// func operandString(x *operand, qf Qualifier) string { var buf bytes.Buffer @@ -252,10 +263,15 @@ func (x *operand) assignableTo(check *Checker, T Type, reason *string) bool { // T is an interface type and x implements T if Ti, ok := Tu.(*Interface); ok { - if m, wrongType := check.missingMethod(x.typ, Ti, true); m != nil /* Implements(x.typ, Ti) */ { + if m, wrongType := check.missingMethod(V, Ti, true); m != nil /* Implements(V, Ti) */ { if reason != nil { - if wrongType { - *reason = "wrong type for method " + m.Name() + if wrongType != nil { + if check.identical(m.typ, wrongType.typ) { + *reason = fmt.Sprintf("missing method %s (%s has pointer receiver)", m.name, m.name) + } else { + *reason = fmt.Sprintf("wrong type for method %s (have %s, want %s)", m.Name(), wrongType.typ, m.typ) + } + } else { *reason = "missing method " + m.Name() } diff --git a/libgo/go/go/types/package.go b/libgo/go/go/types/package.go index cd202a0ed9f..7b89def1b5d 100644 --- a/libgo/go/go/types/package.go +++ b/libgo/go/go/types/package.go @@ -17,6 +17,7 @@ type Package struct { complete bool imports []*Package fake bool // scope lookup errors are silently dropped if package is fake (internal use only) + cgo bool // uses of this package will be rewritten into uses of declarations from _cgo_gotypes.go } // NewPackage returns a new Package for the given package path and name. diff --git a/libgo/go/go/types/resolver.go b/libgo/go/go/types/resolver.go index 839d076e361..078adc5ec78 100644 --- a/libgo/go/go/types/resolver.go +++ b/libgo/go/go/types/resolver.go @@ -141,9 +141,10 @@ func (check *Checker) importPackage(pos token.Pos, path, dir string) *Package { } // no package yet => import it - if path == "C" && check.conf.FakeImportC { + if path == "C" && (check.conf.FakeImportC || check.conf.go115UsesCgo) { imp = NewPackage("C", "C") - imp.fake = true + imp.fake = true // package scope is not populated + imp.cgo = check.conf.go115UsesCgo } else { // ordinary import var err error diff --git a/libgo/go/go/types/stdlib_test.go b/libgo/go/go/types/stdlib_test.go index 4257bd9005b..5c9fec7a633 100644 --- a/libgo/go/go/types/stdlib_test.go +++ b/libgo/go/go/types/stdlib_test.go @@ -161,6 +161,7 @@ func TestStdTest(t *testing.T) { testTestDir(t, filepath.Join(runtime.GOROOT(), "test"), "cmplxdivide.go", // also needs file cmplxdivide1.go - ignore + "directive.go", // tests compiler rejection of bad directive placement - ignore ) } diff --git a/libgo/go/go/types/testdata/decls3.src b/libgo/go/go/types/testdata/decls3.src index 18ddf5859c6..745175c7109 100644 --- a/libgo/go/go/types/testdata/decls3.src +++ b/libgo/go/go/types/testdata/decls3.src @@ -19,7 +19,7 @@ func _() { ) var t T3 - _ = t.X /* ERROR "ambiguous selector" */ + _ = t.X /* ERROR "ambiguous selector t.X" */ } func _() { @@ -31,7 +31,7 @@ func _() { ) var t T4 - _ = t.X /* ERROR "ambiguous selector" */ + _ = t.X /* ERROR "ambiguous selector t.X" */ } func issue4355() { @@ -44,7 +44,7 @@ func issue4355() { ) var t T5 - _ = t.X /* ERROR "ambiguous selector" */ + _ = t.X /* ERROR "ambiguous selector t.X" */ } func _() { @@ -54,7 +54,7 @@ func _() { type T struct{ A; B } var t T - _ = t.State /* ERROR "ambiguous selector" */ + _ = t.State /* ERROR "ambiguous selector t.State" */ } // Embedded fields can be predeclared types. @@ -221,16 +221,16 @@ func _() { _ = S2{}.B _ = S2{}.C _ = S2{}.D /* ERROR "no field or method" */ - _ = S3{}.S1 /* ERROR "ambiguous selector" */ + _ = S3{}.S1 /* ERROR "ambiguous selector \(S3 literal\).S1" */ _ = S3{}.A - _ = S3{}.B /* ERROR "ambiguous selector" */ + _ = S3{}.B /* ERROR "ambiguous selector" \(S3 literal\).B */ _ = S3{}.D _ = S3{}.E _ = S4{}.A _ = S4{}.B /* ERROR "no field or method" */ - _ = S5{}.X /* ERROR "ambiguous selector" */ + _ = S5{}.X /* ERROR "ambiguous selector \(S5 literal\).X" */ _ = S5{}.Y - _ = S10{}.X /* ERROR "ambiguous selector" */ + _ = S10{}.X /* ERROR "ambiguous selector \(S10 literal\).X" */ _ = S10{}.Y } @@ -306,4 +306,4 @@ type R22 R21 type R23 R21 type R24 R21 -var _ = R0{}.X /* ERROR "ambiguous selector" */ \ No newline at end of file +var _ = R0{}.X /* ERROR "ambiguous selector \(R0 literal\).X" */ \ No newline at end of file diff --git a/libgo/go/go/types/testdata/decls4.src b/libgo/go/go/types/testdata/decls4.src index ab7c67988b1..140bbfd31fd 100644 --- a/libgo/go/go/types/testdata/decls4.src +++ b/libgo/go/go/types/testdata/decls4.src @@ -190,8 +190,8 @@ type eD struct { } var ( - _ = eD{}.xf /* ERROR ambiguous selector */ - _ = eD{}.xm /* ERROR ambiguous selector */ + _ = eD{}.xf /* ERROR ambiguous selector \(eD literal\).xf */ + _ = eD{}.xm /* ERROR ambiguous selector \(eD literal\).xm */ ) var ( diff --git a/libgo/go/go/types/testdata/expr3.src b/libgo/go/go/types/testdata/expr3.src index d562f0b16b6..63af9fc867c 100644 --- a/libgo/go/go/types/testdata/expr3.src +++ b/libgo/go/go/types/testdata/expr3.src @@ -155,10 +155,10 @@ func (*T) m() {} func method_expressions() { _ = T.a /* ERROR "no field or method" */ _ = T.x /* ERROR "has no method" */ - _ = T.m /* ERROR "not in method set" */ + _ = T.m /* ERROR "cannot call pointer method m on T" */ _ = (*T).m - var f func(*T) = T.m /* ERROR "not in method set" */ + var f func(*T) = T.m /* ERROR "cannot call pointer method m on T" */ var g func(*T) = (*T).m _, _ = f, g diff --git a/libgo/go/go/types/testdata/issue28251.src b/libgo/go/go/types/testdata/issue28251.src index a456f5c27ed..cd79e0e8b5d 100644 --- a/libgo/go/go/types/testdata/issue28251.src +++ b/libgo/go/go/types/testdata/issue28251.src @@ -41,7 +41,7 @@ type ( ) func (T4) m4() {} -func _() { (T{}).m4 /* ERROR m4 is not in method set of T */ () } +func _() { (T{}).m4 /* ERROR "cannot call pointer method m4 on T" */ () } func _() { (&T{}).m4() } type ( @@ -51,7 +51,7 @@ type ( ) func (T6) m6() {} -func _() { (T{}).m6 /* ERROR m6 is not in method set of T */ () } +func _() { (T{}).m6 /* ERROR "cannot call pointer method m6 on T" */ () } func _() { (&T{}).m6() } type ( diff --git a/libgo/go/go/types/testdata/issues.src b/libgo/go/go/types/testdata/issues.src index fe2407999c5..4944f6f6187 100644 --- a/libgo/go/go/types/testdata/issues.src +++ b/libgo/go/go/types/testdata/issues.src @@ -129,6 +129,16 @@ func issue10260() { t1 *T1 t2 *T2 ) + + var x I1 + x = T1 /* ERROR cannot use .*: missing method foo \(foo has pointer receiver\) */ {} + _ = x /* ERROR .* cannot have dynamic type T1 \(missing method foo \(foo has pointer receiver\)\) */ .(T1) + + T1{}.foo /* ERROR cannot call pointer method foo on T1 */ () + x.Foo /* ERROR "x.Foo undefined \(type I1 has no field or method Foo, but does have foo\)" */ () + + _ = i2 /* ERROR i2 .* cannot have dynamic type \*T1 \(wrong type for method foo \(have func\(\), want func\(x int\)\)\) */ .(*T1) + i1 = i0 /* ERROR cannot use .* missing method foo */ i1 = t0 /* ERROR cannot use .* missing method foo */ i1 = i2 /* ERROR cannot use .* wrong type for method foo */ @@ -146,7 +156,7 @@ func issue10260() { // a few more - less exhaustive now f := func(I1, I2){} - f(i0 /* ERROR cannot use .* missing method foo */ , i1 /* ERROR cannot use .* wrong type for method foo */) + f(i0 /* ERROR cannot use .* missing method foo */ , i1 /* ERROR cannot use .* wrong type for method foo \(have func\(\), want func\(x int\)\) */ ) _ = [...]I1{i0 /* ERROR cannot use .* missing method foo */ } _ = [...]I1{i2 /* ERROR cannot use .* wrong type for method foo */ } @@ -335,7 +345,7 @@ type E1 struct{ f int } type E2 struct{ f int } func issue26234b(x T) { - _ = x.f /* ERROR ambiguous selector f */ + _ = x.f /* ERROR ambiguous selector x.f */ } func issue26234c() { @@ -352,4 +362,4 @@ func issue35895() { // Because both t1 and t2 have the same global package name (template), // qualify packages with full path name in this case. var _ t1.Template = t2 /* ERROR cannot use .* \(value of type "html/template".Template\) as "text/template".Template */ .Template{} -} \ No newline at end of file +} diff --git a/libgo/go/go/types/testdata/methodsets.src b/libgo/go/go/types/testdata/methodsets.src index 2f21faf1e48..9fb10deb9a2 100644 --- a/libgo/go/go/types/testdata/methodsets.src +++ b/libgo/go/go/types/testdata/methodsets.src @@ -29,7 +29,7 @@ type T3 struct { func _() { var ( _ func(T0) = T0.v0 - _ = T0.p0 /* ERROR "not in method set" */ + _ = T0.p0 /* ERROR "cannot call pointer method p0 on T0" */ _ func (*T0) = (*T0).v0 _ func (*T0) = (*T0).p0 @@ -40,7 +40,7 @@ func _() { _ func(T2) = T2.p2 _ func(T3) = T3.v0 - _ func(T3) = T3.p0 /* ERROR "not in method set" */ + _ func(T3) = T3.p0 /* ERROR "cannot call pointer method p0 on T3" */ _ func(T3) = T3.v1 _ func(T3) = T3.p1 _ func(T3) = T3.v2 @@ -135,7 +135,7 @@ func _() { func _() { var ( _ func() = T0{}.v0 - _ func() = T0{}.p0 /* ERROR "not in method set" */ + _ func() = T0{}.p0 /* ERROR "cannot call pointer method p0 on T0" */ _ func() = (&T0{}).v0 _ func() = (&T0{}).p0 @@ -145,7 +145,7 @@ func _() { // no values for T2 _ func() = T3{}.v0 - _ func() = T3{}.p0 /* ERROR "not in method set" */ + _ func() = T3{}.p0 /* ERROR "cannot call pointer method p0 on T3" */ _ func() = T3{}.v1 _ func() = T3{}.p1 _ func() = T3{}.v2 @@ -163,7 +163,7 @@ func _() { // Method calls with value receivers func _() { T0{}.v0() - T0{}.p0 /* ERROR "not in method set" */ () + T0{}.p0 /* ERROR "cannot call pointer method p0 on T0" */ () (&T0{}).v0() (&T0{}).p0() @@ -173,7 +173,7 @@ func _() { // no values for T2 T3{}.v0() - T3{}.p0 /* ERROR "not in method set" */ () + T3{}.p0 /* ERROR "cannot call pointer method p0 on T3" */ () T3{}.v1() T3{}.p1() T3{}.v2() diff --git a/libgo/go/go/types/universe.go b/libgo/go/go/types/universe.go index 7af6dab320e..ff5b89118ad 100644 --- a/libgo/go/go/types/universe.go +++ b/libgo/go/go/types/universe.go @@ -21,9 +21,10 @@ var Universe *Scope var Unsafe *Package var ( - universeIota *Const - universeByte *Basic // uint8 alias, but has name "byte" - universeRune *Basic // int32 alias, but has name "rune" + universeIota *Const + universeByte *Basic // uint8 alias, but has name "byte" + universeRune *Basic // int32 alias, but has name "rune" + universeError *Named ) // Typ contains the predeclared *Basic types indexed by their @@ -200,6 +201,7 @@ func init() { universeIota = Universe.Lookup("iota").(*Const) universeByte = Universe.Lookup("byte").(*TypeName).typ.(*Basic) universeRune = Universe.Lookup("rune").(*TypeName).typ.(*Basic) + universeError = Universe.Lookup("error").(*TypeName).typ.(*Named) } // Objects with names containing blanks are internal and not entered into diff --git a/libgo/go/golang.org/x/crypto/chacha20/chacha_arm64.go b/libgo/go/golang.org/x/crypto/chacha20/chacha_arm64.go index 87f1e369cc2..b799e440b4a 100644 --- a/libgo/go/golang.org/x/crypto/chacha20/chacha_arm64.go +++ b/libgo/go/golang.org/x/crypto/chacha20/chacha_arm64.go @@ -2,8 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build go1.11 -// +build !gccgo,!appengine +// +build go1.11,!gccgo,!purego package chacha20 diff --git a/libgo/go/golang.org/x/crypto/chacha20/chacha_generic.go b/libgo/go/golang.org/x/crypto/chacha20/chacha_generic.go index 098ec9f6be0..a2ecf5c325b 100644 --- a/libgo/go/golang.org/x/crypto/chacha20/chacha_generic.go +++ b/libgo/go/golang.org/x/crypto/chacha20/chacha_generic.go @@ -42,10 +42,14 @@ type Cipher struct { // The last len bytes of buf are leftover key stream bytes from the previous // XORKeyStream invocation. The size of buf depends on how many blocks are - // computed at a time. + // computed at a time by xorKeyStreamBlocks. buf [bufSize]byte len int + // overflow is set when the counter overflowed, no more blocks can be + // generated, and the next XORKeyStream call should panic. + overflow bool + // The counter-independent results of the first round are cached after they // are computed the first time. precompDone bool @@ -89,6 +93,7 @@ func newUnauthenticatedCipher(c *Cipher, key, nonce []byte) (*Cipher, error) { return nil, errors.New("chacha20: wrong nonce size") } + key, nonce = key[:KeySize], nonce[:NonceSize] // bounds check elimination hint c.key = [8]uint32{ binary.LittleEndian.Uint32(key[0:4]), binary.LittleEndian.Uint32(key[4:8]), @@ -136,6 +141,36 @@ func quarterRound(a, b, c, d uint32) (uint32, uint32, uint32, uint32) { return a, b, c, d } +// SetCounter sets the Cipher counter. The next invocation of XORKeyStream will +// behave as if (64 * counter) bytes had been encrypted so far. +// +// To prevent accidental counter reuse, SetCounter panics if counter is less +// than the current value. +// +// Note that the execution time of XORKeyStream is not independent of the +// counter value. +func (s *Cipher) SetCounter(counter uint32) { + // Internally, s may buffer multiple blocks, which complicates this + // implementation slightly. When checking whether the counter has rolled + // back, we must use both s.counter and s.len to determine how many blocks + // we have already output. + outputCounter := s.counter - uint32(s.len)/blockSize + if s.overflow || counter < outputCounter { + panic("chacha20: SetCounter attempted to rollback counter") + } + + // In the general case, we set the new counter value and reset s.len to 0, + // causing the next call to XORKeyStream to refill the buffer. However, if + // we're advancing within the existing buffer, we can save work by simply + // setting s.len. + if counter < s.counter { + s.len = int(s.counter-counter) * blockSize + } else { + s.counter = counter + s.len = 0 + } +} + // XORKeyStream XORs each byte in the given slice with a byte from the // cipher's key stream. Dst and src must overlap entirely or not at all. // @@ -169,34 +204,52 @@ func (s *Cipher) XORKeyStream(dst, src []byte) { dst[i] = src[i] ^ b } s.len -= len(keyStream) - src = src[len(keyStream):] - dst = dst[len(keyStream):] + dst, src = dst[len(keyStream):], src[len(keyStream):] + } + if len(src) == 0 { + return } - const blocksPerBuf = bufSize / blockSize - numBufs := (uint64(len(src)) + bufSize - 1) / bufSize - if uint64(s.counter)+numBufs*blocksPerBuf >= 1<<32 { + // If we'd need to let the counter overflow and keep generating output, + // panic immediately. If instead we'd only reach the last block, remember + // not to generate any more output after the buffer is drained. + numBlocks := (uint64(len(src)) + blockSize - 1) / blockSize + if s.overflow || uint64(s.counter)+numBlocks > 1<<32 { panic("chacha20: counter overflow") + } else if uint64(s.counter)+numBlocks == 1<<32 { + s.overflow = true } // xorKeyStreamBlocks implementations expect input lengths that are a // multiple of bufSize. Platform-specific ones process multiple blocks at a // time, so have bufSizes that are a multiple of blockSize. - rem := len(src) % bufSize - full := len(src) - rem - + full := len(src) - len(src)%bufSize if full > 0 { s.xorKeyStreamBlocks(dst[:full], src[:full]) } + dst, src = dst[full:], src[full:] + + // If using a multi-block xorKeyStreamBlocks would overflow, use the generic + // one that does one block at a time. + const blocksPerBuf = bufSize / blockSize + if uint64(s.counter)+blocksPerBuf > 1<<32 { + s.buf = [bufSize]byte{} + numBlocks := (len(src) + blockSize - 1) / blockSize + buf := s.buf[bufSize-numBlocks*blockSize:] + copy(buf, src) + s.xorKeyStreamBlocksGeneric(buf, buf) + s.len = len(buf) - copy(dst, buf) + return + } // If we have a partial (multi-)block, pad it for xorKeyStreamBlocks, and // keep the leftover keystream for the next XORKeyStream invocation. - if rem > 0 { + if len(src) > 0 { s.buf = [bufSize]byte{} - copy(s.buf[:], src[full:]) + copy(s.buf[:], src) s.xorKeyStreamBlocks(s.buf[:], s.buf[:]) - s.len = bufSize - copy(dst[full:], s.buf[:]) + s.len = bufSize - copy(dst, s.buf[:]) } } @@ -233,7 +286,9 @@ func (s *Cipher) xorKeyStreamBlocksGeneric(dst, src []byte) { s.precompDone = true } - for i := 0; i < len(src); i += blockSize { + // A condition of len(src) > 0 would be sufficient, but this also + // acts as a bounds check elimination hint. + for len(src) >= 64 && len(dst) >= 64 { // The remainder of the first column round. fcr0, fcr4, fcr8, fcr12 := quarterRound(c0, c4, c8, s.counter) @@ -258,49 +313,28 @@ func (s *Cipher) xorKeyStreamBlocksGeneric(dst, src []byte) { x3, x4, x9, x14 = quarterRound(x3, x4, x9, x14) } - // Finally, add back the initial state to generate the key stream. - x0 += c0 - x1 += c1 - x2 += c2 - x3 += c3 - x4 += c4 - x5 += c5 - x6 += c6 - x7 += c7 - x8 += c8 - x9 += c9 - x10 += c10 - x11 += c11 - x12 += s.counter - x13 += c13 - x14 += c14 - x15 += c15 + // Add back the initial state to generate the key stream, then + // XOR the key stream with the source and write out the result. + addXor(dst[0:4], src[0:4], x0, c0) + addXor(dst[4:8], src[4:8], x1, c1) + addXor(dst[8:12], src[8:12], x2, c2) + addXor(dst[12:16], src[12:16], x3, c3) + addXor(dst[16:20], src[16:20], x4, c4) + addXor(dst[20:24], src[20:24], x5, c5) + addXor(dst[24:28], src[24:28], x6, c6) + addXor(dst[28:32], src[28:32], x7, c7) + addXor(dst[32:36], src[32:36], x8, c8) + addXor(dst[36:40], src[36:40], x9, c9) + addXor(dst[40:44], src[40:44], x10, c10) + addXor(dst[44:48], src[44:48], x11, c11) + addXor(dst[48:52], src[48:52], x12, s.counter) + addXor(dst[52:56], src[52:56], x13, c13) + addXor(dst[56:60], src[56:60], x14, c14) + addXor(dst[60:64], src[60:64], x15, c15) s.counter += 1 - if s.counter == 0 { - panic("chacha20: internal error: counter overflow") - } - in, out := src[i:], dst[i:] - in, out = in[:blockSize], out[:blockSize] // bounds check elimination hint - - // XOR the key stream with the source and write out the result. - xor(out[0:], in[0:], x0) - xor(out[4:], in[4:], x1) - xor(out[8:], in[8:], x2) - xor(out[12:], in[12:], x3) - xor(out[16:], in[16:], x4) - xor(out[20:], in[20:], x5) - xor(out[24:], in[24:], x6) - xor(out[28:], in[28:], x7) - xor(out[32:], in[32:], x8) - xor(out[36:], in[36:], x9) - xor(out[40:], in[40:], x10) - xor(out[44:], in[44:], x11) - xor(out[48:], in[48:], x12) - xor(out[52:], in[52:], x13) - xor(out[56:], in[56:], x14) - xor(out[60:], in[60:], x15) + src, dst = src[blockSize:], dst[blockSize:] } } diff --git a/libgo/go/golang.org/x/crypto/chacha20/chacha_noasm.go b/libgo/go/golang.org/x/crypto/chacha20/chacha_noasm.go index ec609ed868b..4635307b8f2 100644 --- a/libgo/go/golang.org/x/crypto/chacha20/chacha_noasm.go +++ b/libgo/go/golang.org/x/crypto/chacha20/chacha_noasm.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !arm64,!s390x,!ppc64le arm64,!go1.11 gccgo appengine +// +build !arm64,!s390x,!ppc64le arm64,!go1.11 gccgo purego package chacha20 diff --git a/libgo/go/golang.org/x/crypto/chacha20/chacha_ppc64le.go b/libgo/go/golang.org/x/crypto/chacha20/chacha_ppc64le.go index d0ec61f08d9..b7993303415 100644 --- a/libgo/go/golang.org/x/crypto/chacha20/chacha_ppc64le.go +++ b/libgo/go/golang.org/x/crypto/chacha20/chacha_ppc64le.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo,!appengine +// +build !gccgo,!purego package chacha20 diff --git a/libgo/go/golang.org/x/crypto/chacha20/chacha_s390x.go b/libgo/go/golang.org/x/crypto/chacha20/chacha_s390x.go index cd55f45a333..a9244bdf4db 100644 --- a/libgo/go/golang.org/x/crypto/chacha20/chacha_s390x.go +++ b/libgo/go/golang.org/x/crypto/chacha20/chacha_s390x.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !gccgo,!appengine +// +build !gccgo,!purego package chacha20 diff --git a/libgo/go/golang.org/x/crypto/chacha20/xor.go b/libgo/go/golang.org/x/crypto/chacha20/xor.go index 0110c9865af..c2d04851e0d 100644 --- a/libgo/go/golang.org/x/crypto/chacha20/xor.go +++ b/libgo/go/golang.org/x/crypto/chacha20/xor.go @@ -13,10 +13,10 @@ const unaligned = runtime.GOARCH == "386" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "s390x" -// xor reads a little endian uint32 from src, XORs it with u and +// addXor reads a little endian uint32 from src, XORs it with (a + b) and // places the result in little endian byte order in dst. -func xor(dst, src []byte, u uint32) { - _, _ = src[3], dst[3] // eliminate bounds checks +func addXor(dst, src []byte, a, b uint32) { + _, _ = src[3], dst[3] // bounds check elimination hint if unaligned { // The compiler should optimize this code into // 32-bit unaligned little endian loads and stores. @@ -27,15 +27,16 @@ func xor(dst, src []byte, u uint32) { v |= uint32(src[1]) << 8 v |= uint32(src[2]) << 16 v |= uint32(src[3]) << 24 - v ^= u + v ^= a + b dst[0] = byte(v) dst[1] = byte(v >> 8) dst[2] = byte(v >> 16) dst[3] = byte(v >> 24) } else { - dst[0] = src[0] ^ byte(u) - dst[1] = src[1] ^ byte(u>>8) - dst[2] = src[2] ^ byte(u>>16) - dst[3] = src[3] ^ byte(u>>24) + a += b + dst[0] = src[0] ^ byte(a) + dst[1] = src[1] ^ byte(a>>8) + dst[2] = src[2] ^ byte(a>>16) + dst[3] = src[3] ^ byte(a>>24) } } diff --git a/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go b/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go index 737e46aa5a4..cda77819b84 100644 --- a/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go +++ b/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build go1.7,amd64,!gccgo,!appengine +// +build !gccgo,!purego package chacha20poly1305 diff --git a/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go b/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go index 91b38568ce1..fe191d395d5 100644 --- a/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go +++ b/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go @@ -12,56 +12,64 @@ import ( "golang.org/x/crypto/poly1305" ) -func roundTo16(n int) int { - return 16 * ((n + 15) / 16) +func writeWithPadding(p *poly1305.MAC, b []byte) { + p.Write(b) + if rem := len(b) % 16; rem != 0 { + var buf [16]byte + padLen := 16 - rem + p.Write(buf[:padLen]) + } +} + +func writeUint64(p *poly1305.MAC, n int) { + var buf [8]byte + binary.LittleEndian.PutUint64(buf[:], uint64(n)) + p.Write(buf[:]) } func (c *chacha20poly1305) sealGeneric(dst, nonce, plaintext, additionalData []byte) []byte { ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize) + ciphertext, tag := out[:len(plaintext)], out[len(plaintext):] if subtle.InexactOverlap(out, plaintext) { panic("chacha20poly1305: invalid buffer overlap") } - var polyKey, discardBuf [32]byte + var polyKey [32]byte s, _ := chacha20.NewUnauthenticatedCipher(c.key[:], nonce) s.XORKeyStream(polyKey[:], polyKey[:]) - s.XORKeyStream(discardBuf[:], discardBuf[:]) // skip the next 32 bytes - s.XORKeyStream(out, plaintext) - - polyInput := make([]byte, roundTo16(len(additionalData))+roundTo16(len(plaintext))+8+8) - copy(polyInput, additionalData) - copy(polyInput[roundTo16(len(additionalData)):], out[:len(plaintext)]) - binary.LittleEndian.PutUint64(polyInput[len(polyInput)-16:], uint64(len(additionalData))) - binary.LittleEndian.PutUint64(polyInput[len(polyInput)-8:], uint64(len(plaintext))) + s.SetCounter(1) // set the counter to 1, skipping 32 bytes + s.XORKeyStream(ciphertext, plaintext) - var tag [poly1305.TagSize]byte - poly1305.Sum(&tag, polyInput, &polyKey) - copy(out[len(plaintext):], tag[:]) + p := poly1305.New(&polyKey) + writeWithPadding(p, additionalData) + writeWithPadding(p, ciphertext) + writeUint64(p, len(additionalData)) + writeUint64(p, len(plaintext)) + p.Sum(tag[:0]) return ret } func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { - var tag [poly1305.TagSize]byte - copy(tag[:], ciphertext[len(ciphertext)-16:]) + tag := ciphertext[len(ciphertext)-16:] ciphertext = ciphertext[:len(ciphertext)-16] - var polyKey, discardBuf [32]byte + var polyKey [32]byte s, _ := chacha20.NewUnauthenticatedCipher(c.key[:], nonce) s.XORKeyStream(polyKey[:], polyKey[:]) - s.XORKeyStream(discardBuf[:], discardBuf[:]) // skip the next 32 bytes + s.SetCounter(1) // set the counter to 1, skipping 32 bytes - polyInput := make([]byte, roundTo16(len(additionalData))+roundTo16(len(ciphertext))+8+8) - copy(polyInput, additionalData) - copy(polyInput[roundTo16(len(additionalData)):], ciphertext) - binary.LittleEndian.PutUint64(polyInput[len(polyInput)-16:], uint64(len(additionalData))) - binary.LittleEndian.PutUint64(polyInput[len(polyInput)-8:], uint64(len(ciphertext))) + p := poly1305.New(&polyKey) + writeWithPadding(p, additionalData) + writeWithPadding(p, ciphertext) + writeUint64(p, len(additionalData)) + writeUint64(p, len(ciphertext)) ret, out := sliceForAppend(dst, len(ciphertext)) if subtle.InexactOverlap(out, ciphertext) { panic("chacha20poly1305: invalid buffer overlap") } - if !poly1305.Verify(&tag, polyInput, &polyKey) { + if !p.Verify(tag) { for i := range out { out[i] = 0 } diff --git a/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go b/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go index 4c2eb703c32..9ce4aa9fe65 100644 --- a/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go +++ b/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !amd64 !go1.7 gccgo appengine +// +build !amd64 gccgo purego package chacha20poly1305 diff --git a/libgo/go/golang.org/x/crypto/cryptobyte/asn1.go b/libgo/go/golang.org/x/crypto/cryptobyte/asn1.go index f930f7e5266..d3596ee66fd 100644 --- a/libgo/go/golang.org/x/crypto/cryptobyte/asn1.go +++ b/libgo/go/golang.org/x/crypto/cryptobyte/asn1.go @@ -81,7 +81,7 @@ func (b *Builder) AddASN1BigInt(n *big.Int) { for i := range bytes { bytes[i] ^= 0xff } - if bytes[0]&0x80 == 0 { + if len(bytes) == 0 || bytes[0]&0x80 == 0 { c.add(0xff) } c.add(bytes...) @@ -230,12 +230,12 @@ func (b *Builder) AddASN1(tag asn1.Tag, f BuilderContinuation) { // String -// ReadASN1Boolean decodes an ASN.1 INTEGER and converts it to a boolean +// ReadASN1Boolean decodes an ASN.1 BOOLEAN and converts it to a boolean // representation into out and advances. It reports whether the read // was successful. func (s *String) ReadASN1Boolean(out *bool) bool { var bytes String - if !s.ReadASN1(&bytes, asn1.INTEGER) || len(bytes) != 1 { + if !s.ReadASN1(&bytes, asn1.BOOLEAN) || len(bytes) != 1 { return false } diff --git a/libgo/go/golang.org/x/crypto/poly1305/mac_noasm.go b/libgo/go/golang.org/x/crypto/poly1305/mac_noasm.go index a8dd589ae39..d118f30ed56 100644 --- a/libgo/go/golang.org/x/crypto/poly1305/mac_noasm.go +++ b/libgo/go/golang.org/x/crypto/poly1305/mac_noasm.go @@ -2,10 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !amd64,!ppc64le gccgo appengine +// +build !amd64,!ppc64le,!s390x gccgo purego package poly1305 type mac struct{ macGeneric } - -func newMAC(key *[32]byte) mac { return mac{newMACGeneric(key)} } diff --git a/libgo/go/golang.org/x/crypto/poly1305/poly1305.go b/libgo/go/golang.org/x/crypto/poly1305/poly1305.go index 066159b797d..9d7a6af09fe 100644 --- a/libgo/go/golang.org/x/crypto/poly1305/poly1305.go +++ b/libgo/go/golang.org/x/crypto/poly1305/poly1305.go @@ -26,7 +26,9 @@ const TagSize = 16 // 16-byte result into out. Authenticating two different messages with the same // key allows an attacker to forge messages at will. func Sum(out *[16]byte, m []byte, key *[32]byte) { - sum(out, m, key) + h := New(key) + h.Write(m) + h.Sum(out[:0]) } // Verify returns true if mac is a valid authenticator for m with the given key. @@ -46,10 +48,9 @@ func Verify(mac *[16]byte, m []byte, key *[32]byte) bool { // two different messages with the same key allows an attacker // to forge messages at will. func New(key *[32]byte) *MAC { - return &MAC{ - mac: newMAC(key), - finalized: false, - } + m := &MAC{} + initialize(key, &m.macState) + return m } // MAC is an io.Writer computing an authentication tag @@ -58,7 +59,7 @@ func New(key *[32]byte) *MAC { // MAC cannot be used like common hash.Hash implementations, // because using a poly1305 key twice breaks its security. // Therefore writing data to a running MAC after calling -// Sum causes it to panic. +// Sum or Verify causes it to panic. type MAC struct { mac // platform-dependent implementation @@ -71,10 +72,10 @@ func (h *MAC) Size() int { return TagSize } // Write adds more data to the running message authentication code. // It never returns an error. // -// It must not be called after the first call of Sum. +// It must not be called after the first call of Sum or Verify. func (h *MAC) Write(p []byte) (n int, err error) { if h.finalized { - panic("poly1305: write to MAC after Sum") + panic("poly1305: write to MAC after Sum or Verify") } return h.mac.Write(p) } @@ -87,3 +88,12 @@ func (h *MAC) Sum(b []byte) []byte { h.finalized = true return append(b, mac[:]...) } + +// Verify returns whether the authenticator of all data written to +// the message authentication code matches the expected value. +func (h *MAC) Verify(expected []byte) bool { + var mac [TagSize]byte + h.mac.Sum(&mac) + h.finalized = true + return subtle.ConstantTimeCompare(expected, mac[:]) == 1 +} diff --git a/libgo/go/golang.org/x/crypto/poly1305/sum_amd64.go b/libgo/go/golang.org/x/crypto/poly1305/sum_amd64.go index df56a652ff0..99e5a1d50ef 100644 --- a/libgo/go/golang.org/x/crypto/poly1305/sum_amd64.go +++ b/libgo/go/golang.org/x/crypto/poly1305/sum_amd64.go @@ -2,24 +2,13 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build amd64,!gccgo,!appengine +// +build !gccgo,!purego package poly1305 //go:noescape func update(state *macState, msg []byte) -func sum(out *[16]byte, m []byte, key *[32]byte) { - h := newMAC(key) - h.Write(m) - h.Sum(out) -} - -func newMAC(key *[32]byte) (h mac) { - initialize(key, &h.r, &h.s) - return -} - // mac is a wrapper for macGeneric that redirects calls that would have gone to // updateGeneric to update. // diff --git a/libgo/go/golang.org/x/crypto/poly1305/sum_arm.go b/libgo/go/golang.org/x/crypto/poly1305/sum_arm.go deleted file mode 100644 index 6e695e4272e..00000000000 --- a/libgo/go/golang.org/x/crypto/poly1305/sum_arm.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build arm,!gccgo,!appengine,!nacl - -package poly1305 - -// poly1305_auth_armv6 is implemented in sum_arm.s -//go:noescape -func poly1305_auth_armv6(out *[16]byte, m *byte, mlen uint32, key *[32]byte) - -func sum(out *[16]byte, m []byte, key *[32]byte) { - var mPtr *byte - if len(m) > 0 { - mPtr = &m[0] - } - poly1305_auth_armv6(out, mPtr, uint32(len(m)), key) -} diff --git a/libgo/go/golang.org/x/crypto/poly1305/sum_generic.go b/libgo/go/golang.org/x/crypto/poly1305/sum_generic.go index 1187eab78fd..c942a65904f 100644 --- a/libgo/go/golang.org/x/crypto/poly1305/sum_generic.go +++ b/libgo/go/golang.org/x/crypto/poly1305/sum_generic.go @@ -31,16 +31,18 @@ func sumGeneric(out *[TagSize]byte, msg []byte, key *[32]byte) { h.Sum(out) } -func newMACGeneric(key *[32]byte) (h macGeneric) { - initialize(key, &h.r, &h.s) - return +func newMACGeneric(key *[32]byte) macGeneric { + m := macGeneric{} + initialize(key, &m.macState) + return m } // macState holds numbers in saturated 64-bit little-endian limbs. That is, // the value of [x0, x1, x2] is x[0] + x[1] * 2⁶⁴ + x[2] * 2¹²⁸. type macState struct { // h is the main accumulator. It is to be interpreted modulo 2¹³⁰ - 5, but - // can grow larger during and after rounds. + // can grow larger during and after rounds. It must, however, remain below + // 2 * (2¹³⁰ - 5). h [3]uint64 // r and s are the private key components. r [2]uint64 @@ -97,11 +99,12 @@ const ( rMask1 = 0x0FFFFFFC0FFFFFFC ) -func initialize(key *[32]byte, r, s *[2]uint64) { - r[0] = binary.LittleEndian.Uint64(key[0:8]) & rMask0 - r[1] = binary.LittleEndian.Uint64(key[8:16]) & rMask1 - s[0] = binary.LittleEndian.Uint64(key[16:24]) - s[1] = binary.LittleEndian.Uint64(key[24:32]) +// initialize loads the 256-bit key into the two 128-bit secret values r and s. +func initialize(key *[32]byte, m *macState) { + m.r[0] = binary.LittleEndian.Uint64(key[0:8]) & rMask0 + m.r[1] = binary.LittleEndian.Uint64(key[8:16]) & rMask1 + m.s[0] = binary.LittleEndian.Uint64(key[16:24]) + m.s[1] = binary.LittleEndian.Uint64(key[24:32]) } // uint128 holds a 128-bit number as two 64-bit limbs, for use with the diff --git a/libgo/go/golang.org/x/crypto/poly1305/sum_noasm.go b/libgo/go/golang.org/x/crypto/poly1305/sum_noasm.go deleted file mode 100644 index 32a9cef6bbf..00000000000 --- a/libgo/go/golang.org/x/crypto/poly1305/sum_noasm.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build s390x,!go1.11 !amd64,!s390x,!ppc64le gccgo appengine nacl - -package poly1305 - -func sum(out *[TagSize]byte, msg []byte, key *[32]byte) { - h := newMAC(key) - h.Write(msg) - h.Sum(out) -} diff --git a/libgo/go/golang.org/x/crypto/poly1305/sum_ppc64le.go b/libgo/go/golang.org/x/crypto/poly1305/sum_ppc64le.go index 3233616935b..2e7a120b192 100644 --- a/libgo/go/golang.org/x/crypto/poly1305/sum_ppc64le.go +++ b/libgo/go/golang.org/x/crypto/poly1305/sum_ppc64le.go @@ -2,24 +2,13 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build ppc64le,!gccgo,!appengine +// +build !gccgo,!purego package poly1305 //go:noescape func update(state *macState, msg []byte) -func sum(out *[16]byte, m []byte, key *[32]byte) { - h := newMAC(key) - h.Write(m) - h.Sum(out) -} - -func newMAC(key *[32]byte) (h mac) { - initialize(key, &h.r, &h.s) - return -} - // mac is a wrapper for macGeneric that redirects calls that would have gone to // updateGeneric to update. // diff --git a/libgo/go/golang.org/x/crypto/poly1305/sum_s390x.go b/libgo/go/golang.org/x/crypto/poly1305/sum_s390x.go index a8920ee9d21..958fedc0790 100644 --- a/libgo/go/golang.org/x/crypto/poly1305/sum_s390x.go +++ b/libgo/go/golang.org/x/crypto/poly1305/sum_s390x.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build s390x,go1.11,!gccgo,!appengine +// +build !gccgo,!purego package poly1305 @@ -10,30 +10,66 @@ import ( "golang.org/x/sys/cpu" ) -// poly1305vx is an assembly implementation of Poly1305 that uses vector +// updateVX is an assembly implementation of Poly1305 that uses vector // instructions. It must only be called if the vector facility (vx) is // available. //go:noescape -func poly1305vx(out *[16]byte, m *byte, mlen uint64, key *[32]byte) +func updateVX(state *macState, msg []byte) -// poly1305vmsl is an assembly implementation of Poly1305 that uses vector -// instructions, including VMSL. It must only be called if the vector facility (vx) is -// available and if VMSL is supported. -//go:noescape -func poly1305vmsl(out *[16]byte, m *byte, mlen uint64, key *[32]byte) +// mac is a replacement for macGeneric that uses a larger buffer and redirects +// calls that would have gone to updateGeneric to updateVX if the vector +// facility is installed. +// +// A larger buffer is required for good performance because the vector +// implementation has a higher fixed cost per call than the generic +// implementation. +type mac struct { + macState + + buffer [16 * TagSize]byte // size must be a multiple of block size (16) + offset int +} -func sum(out *[16]byte, m []byte, key *[32]byte) { - if cpu.S390X.HasVX { - var mPtr *byte - if len(m) > 0 { - mPtr = &m[0] +func (h *mac) Write(p []byte) (int, error) { + nn := len(p) + if h.offset > 0 { + n := copy(h.buffer[h.offset:], p) + if h.offset+n < len(h.buffer) { + h.offset += n + return nn, nil } - if cpu.S390X.HasVXE && len(m) > 256 { - poly1305vmsl(out, mPtr, uint64(len(m)), key) + p = p[n:] + h.offset = 0 + if cpu.S390X.HasVX { + updateVX(&h.macState, h.buffer[:]) } else { - poly1305vx(out, mPtr, uint64(len(m)), key) + updateGeneric(&h.macState, h.buffer[:]) } - } else { - sumGeneric(out, m, key) } + + tail := len(p) % len(h.buffer) // number of bytes to copy into buffer + body := len(p) - tail // number of bytes to process now + if body > 0 { + if cpu.S390X.HasVX { + updateVX(&h.macState, p[:body]) + } else { + updateGeneric(&h.macState, p[:body]) + } + } + h.offset = copy(h.buffer[:], p[body:]) // copy tail bytes - can be 0 + return nn, nil +} + +func (h *mac) Sum(out *[TagSize]byte) { + state := h.macState + remainder := h.buffer[:h.offset] + + // Use the generic implementation if we have 2 or fewer blocks left + // to sum. The vector implementation has a higher startup time. + if cpu.S390X.HasVX && len(remainder) > 2*TagSize { + updateVX(&state, remainder) + } else if len(remainder) > 0 { + updateGeneric(&state, remainder) + } + finalize(out, &state.h, &state.s) } diff --git a/libgo/go/golang.org/x/mod/modfile/print.go b/libgo/go/golang.org/x/mod/modfile/print.go index 3bbea38529f..524f93022ac 100644 --- a/libgo/go/golang.org/x/mod/modfile/print.go +++ b/libgo/go/golang.org/x/mod/modfile/print.go @@ -138,16 +138,11 @@ func (p *printer) expr(x Expr) { p.printf(")") case *Line: - sep := "" - for _, tok := range x.Token { - p.printf("%s%s", sep, tok) - sep = " " - } + p.tokens(x.Token) case *LineBlock: - for _, tok := range x.Token { - p.printf("%s ", tok) - } + p.tokens(x.Token) + p.printf(" ") p.expr(&x.LParen) p.margin++ for _, l := range x.Line { @@ -163,3 +158,17 @@ func (p *printer) expr(x Expr) { // reach the end of the line. p.comment = append(p.comment, x.Comment().Suffix...) } + +func (p *printer) tokens(tokens []string) { + sep := "" + for _, t := range tokens { + if t == "," || t == ")" || t == "]" || t == "}" { + sep = "" + } + p.printf("%s%s", sep, t) + sep = " " + if t == "(" || t == "[" || t == "{" { + sep = "" + } + } +} diff --git a/libgo/go/golang.org/x/mod/modfile/read.go b/libgo/go/golang.org/x/mod/modfile/read.go index 616d00efdb1..c1f2008ee4c 100644 --- a/libgo/go/golang.org/x/mod/modfile/read.go +++ b/libgo/go/golang.org/x/mod/modfile/read.go @@ -2,13 +2,11 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Module file parser. -// This is a simplified copy of Google's buildifier parser. - package modfile import ( "bytes" + "errors" "fmt" "os" "strconv" @@ -323,18 +321,17 @@ func (x *RParen) Span() (start, end Position) { // An input represents a single input file being parsed. type input struct { // Lexing state. - filename string // name of input file, for errors - complete []byte // entire input - remaining []byte // remaining input - token []byte // token being scanned - lastToken string // most recently returned token, for error messages - pos Position // current input position - comments []Comment // accumulated comments - endRule int // position of end of current rule + filename string // name of input file, for errors + complete []byte // entire input + remaining []byte // remaining input + tokenStart []byte // token being scanned to end of input + token token // next token to be returned by lex, peek + pos Position // current input position + comments []Comment // accumulated comments // Parser state. - file *FileSyntax // returned top-level syntax tree - parseError error // error encountered during parsing + file *FileSyntax // returned top-level syntax tree + parseErrors ErrorList // errors encountered during parsing // Comment assignment state. pre []Expr // all expressions, in preorder traversal @@ -352,25 +349,32 @@ func newInput(filename string, data []byte) *input { // parse parses the input file. func parse(file string, data []byte) (f *FileSyntax, err error) { - in := newInput(file, data) // The parser panics for both routine errors like syntax errors // and for programmer bugs like array index errors. // Turn both into error returns. Catching bug panics is // especially important when processing many files. + in := newInput(file, data) defer func() { - if e := recover(); e != nil { - if e == in.parseError { - err = in.parseError - } else { - err = fmt.Errorf("%s:%d:%d: internal error: %v", in.filename, in.pos.Line, in.pos.LineRune, e) - } + if e := recover(); e != nil && e != &in.parseErrors { + in.parseErrors = append(in.parseErrors, Error{ + Filename: in.filename, + Pos: in.pos, + Err: fmt.Errorf("internal error: %v", e), + }) + } + if err == nil && len(in.parseErrors) > 0 { + err = in.parseErrors } }() + // Prime the lexer by reading in the first token. It will be available + // in the next peek() or lex() call. + in.readToken() + // Invoke the parser. in.parseFile() - if in.parseError != nil { - return nil, in.parseError + if len(in.parseErrors) > 0 { + return nil, in.parseErrors } in.file.Name = in.filename @@ -381,14 +385,14 @@ func parse(file string, data []byte) (f *FileSyntax, err error) { } // Error is called to report an error. -// The reason s is often "syntax error". // Error does not return: it panics. func (in *input) Error(s string) { - if s == "syntax error" && in.lastToken != "" { - s += " near " + in.lastToken - } - in.parseError = fmt.Errorf("%s:%d:%d: %v", in.filename, in.pos.Line, in.pos.LineRune, s) - panic(in.parseError) + in.parseErrors = append(in.parseErrors, Error{ + Filename: in.filename, + Pos: in.pos, + Err: errors.New(s), + }) + panic(&in.parseErrors) } // eof reports whether the input has reached end of file. @@ -434,46 +438,68 @@ func (in *input) readRune() int { return int(r) } -type symType struct { +type token struct { + kind tokenKind pos Position endPos Position text string } +type tokenKind int + +const ( + _EOF tokenKind = -(iota + 1) + _EOLCOMMENT + _IDENT + _STRING + _COMMENT + + // newlines and punctuation tokens are allowed as ASCII codes. +) + +func (k tokenKind) isComment() bool { + return k == _COMMENT || k == _EOLCOMMENT +} + +// isEOL returns whether a token terminates a line. +func (k tokenKind) isEOL() bool { + return k == _EOF || k == _EOLCOMMENT || k == '\n' +} + // startToken marks the beginning of the next input token. -// It must be followed by a call to endToken, once the token has +// It must be followed by a call to endToken, once the token's text has // been consumed using readRune. -func (in *input) startToken(sym *symType) { - in.token = in.remaining - sym.text = "" - sym.pos = in.pos +func (in *input) startToken() { + in.tokenStart = in.remaining + in.token.text = "" + in.token.pos = in.pos } // endToken marks the end of an input token. -// It records the actual token string in sym.text if the caller -// has not done that already. -func (in *input) endToken(sym *symType) { - if sym.text == "" { - tok := string(in.token[:len(in.token)-len(in.remaining)]) - sym.text = tok - in.lastToken = sym.text - } - sym.endPos = in.pos +// It records the actual token string in tok.text. +func (in *input) endToken(kind tokenKind) { + in.token.kind = kind + text := string(in.tokenStart[:len(in.tokenStart)-len(in.remaining)]) + in.token.text = text + in.token.endPos = in.pos +} + +// peek returns the kind of the the next token returned by lex. +func (in *input) peek() tokenKind { + return in.token.kind } // lex is called from the parser to obtain the next input token. -// It returns the token value (either a rune like '+' or a symbolic token _FOR) -// and sets val to the data associated with the token. -// For all our input tokens, the associated data is -// val.Pos (the position where the token begins) -// and val.Token (the input string corresponding to the token). -func (in *input) lex(sym *symType) int { +func (in *input) lex() token { + tok := in.token + in.readToken() + return tok +} + +// readToken lexes the next token from the text and stores it in in.token. +func (in *input) readToken() { // Skip past spaces, stopping at non-space or EOF. - countNL := 0 // number of newlines we've skipped past for !in.eof() { - // Skip over spaces. Count newlines so we can give the parser - // information about where top-level blank lines are, - // for top-level comment assignment. c := in.peekRune() if c == ' ' || c == '\t' || c == '\r' { in.readRune() @@ -482,7 +508,7 @@ func (in *input) lex(sym *symType) int { // Comment runs to end of line. if in.peekPrefix("//") { - in.startToken(sym) + in.startToken() // Is this comment the only thing on its line? // Find the last \n before this // and see if it's all @@ -495,30 +521,23 @@ func (in *input) lex(sym *symType) int { // Consume comment. for len(in.remaining) > 0 && in.readRune() != '\n' { } - in.endToken(sym) - - sym.text = strings.TrimRight(sym.text, "\n") - in.lastToken = "comment" // If we are at top level (not in a statement), hand the comment to // the parser as a _COMMENT token. The grammar is written // to handle top-level comments itself. if !suffix { - // Not in a statement. Tell parser about top-level comment. - return _COMMENT + in.endToken(_COMMENT) + return } // Otherwise, save comment for later attachment to syntax tree. - if countNL > 1 { - in.comments = append(in.comments, Comment{sym.pos, "", false}) - } - in.comments = append(in.comments, Comment{sym.pos, sym.text, suffix}) - countNL = 1 - return _EOL + in.endToken(_EOLCOMMENT) + in.comments = append(in.comments, Comment{in.token.pos, in.token.text, suffix}) + return } if in.peekPrefix("/*") { - in.Error(fmt.Sprintf("mod files must use // comments (not /* */ comments)")) + in.Error("mod files must use // comments (not /* */ comments)") } // Found non-space non-comment. @@ -526,35 +545,27 @@ func (in *input) lex(sym *symType) int { } // Found the beginning of the next token. - in.startToken(sym) - defer in.endToken(sym) + in.startToken() // End of file. if in.eof() { - in.lastToken = "EOF" - return _EOF + in.endToken(_EOF) + return } // Punctuation tokens. switch c := in.peekRune(); c { - case '\n': + case '\n', '(', ')', '[', ']', '{', '}', ',': in.readRune() - return c - - case '(': - in.readRune() - return c - - case ')': - in.readRune() - return c + in.endToken(tokenKind(c)) + return case '"', '`': // quoted string quote := c in.readRune() for { if in.eof() { - in.pos = sym.pos + in.pos = in.token.pos in.Error("unexpected EOF in string") } if in.peekRune() == '\n' { @@ -566,14 +577,14 @@ func (in *input) lex(sym *symType) int { } if c == '\\' && quote != '`' { if in.eof() { - in.pos = sym.pos + in.pos = in.token.pos in.Error("unexpected EOF in string") } in.readRune() } } - in.endToken(sym) - return _STRING + in.endToken(_STRING) + return } // Checked all punctuation. Must be identifier token. @@ -587,17 +598,23 @@ func (in *input) lex(sym *symType) int { break } if in.peekPrefix("/*") { - in.Error(fmt.Sprintf("mod files must use // comments (not /* */ comments)")) + in.Error("mod files must use // comments (not /* */ comments)") } in.readRune() } - return _IDENT + in.endToken(_IDENT) } // isIdent reports whether c is an identifier rune. -// We treat nearly all runes as identifier runes. +// We treat most printable runes as identifier runes, except for a handful of +// ASCII punctuation characters. func isIdent(c int) bool { - return c != 0 && !unicode.IsSpace(rune(c)) + switch r := rune(c); r { + case ' ', '(', ')', '[', ']', '{', '}', ',': + return false + default: + return !unicode.IsSpace(r) && unicode.IsPrint(r) + } } // Comment assignment. @@ -668,7 +685,7 @@ func (in *input) assignComments() { for _, x := range in.pre { start, _ := x.Span() if debug { - fmt.Printf("pre %T :%d:%d #%d\n", x, start.Line, start.LineRune, start.Byte) + fmt.Fprintf(os.Stderr, "pre %T :%d:%d #%d\n", x, start.Line, start.LineRune, start.Byte) } xcom := x.Comment() for len(line) > 0 && start.Byte >= line[0].Start.Byte { @@ -695,7 +712,7 @@ func (in *input) assignComments() { start, end := x.Span() if debug { - fmt.Printf("post %T :%d:%d #%d :%d:%d #%d\n", x, start.Line, start.LineRune, start.Byte, end.Line, end.LineRune, end.Byte) + fmt.Fprintf(os.Stderr, "post %T :%d:%d #%d :%d:%d #%d\n", x, start.Line, start.LineRune, start.Byte, end.Line, end.LineRune, end.Byte) } // Do not assign suffix comments to end of line block or whole file. @@ -745,29 +762,29 @@ func reverseComments(list []Comment) { func (in *input) parseFile() { in.file = new(FileSyntax) - var sym symType var cb *CommentBlock for { - tok := in.lex(&sym) - switch tok { + switch in.peek() { case '\n': + in.lex() if cb != nil { in.file.Stmt = append(in.file.Stmt, cb) cb = nil } case _COMMENT: + tok := in.lex() if cb == nil { - cb = &CommentBlock{Start: sym.pos} + cb = &CommentBlock{Start: tok.pos} } com := cb.Comment() - com.Before = append(com.Before, Comment{Start: sym.pos, Token: sym.text}) + com.Before = append(com.Before, Comment{Start: tok.pos, Token: tok.text}) case _EOF: if cb != nil { in.file.Stmt = append(in.file.Stmt, cb) } return default: - in.parseStmt(&sym) + in.parseStmt() if cb != nil { in.file.Stmt[len(in.file.Stmt)-1].Comment().Before = cb.Before cb = nil @@ -776,60 +793,88 @@ func (in *input) parseFile() { } } -func (in *input) parseStmt(sym *symType) { - start := sym.pos - end := sym.endPos - token := []string{sym.text} +func (in *input) parseStmt() { + tok := in.lex() + start := tok.pos + end := tok.endPos + tokens := []string{tok.text} for { - tok := in.lex(sym) - switch tok { - case '\n', _EOF, _EOL: + tok := in.lex() + switch { + case tok.kind.isEOL(): in.file.Stmt = append(in.file.Stmt, &Line{ Start: start, - Token: token, + Token: tokens, End: end, }) return - case '(': - in.file.Stmt = append(in.file.Stmt, in.parseLineBlock(start, token, sym)) - return + + case tok.kind == '(': + if next := in.peek(); next.isEOL() { + // Start of block: no more tokens on this line. + in.file.Stmt = append(in.file.Stmt, in.parseLineBlock(start, tokens, tok)) + return + } else if next == ')' { + rparen := in.lex() + if in.peek().isEOL() { + // Empty block. + in.lex() + in.file.Stmt = append(in.file.Stmt, &LineBlock{ + Start: start, + Token: tokens, + LParen: LParen{Pos: tok.pos}, + RParen: RParen{Pos: rparen.pos}, + }) + return + } + // '( )' in the middle of the line, not a block. + tokens = append(tokens, tok.text, rparen.text) + } else { + // '(' in the middle of the line, not a block. + tokens = append(tokens, tok.text) + } + default: - token = append(token, sym.text) - end = sym.endPos + tokens = append(tokens, tok.text) + end = tok.endPos } } } -func (in *input) parseLineBlock(start Position, token []string, sym *symType) *LineBlock { +func (in *input) parseLineBlock(start Position, token []string, lparen token) *LineBlock { x := &LineBlock{ Start: start, Token: token, - LParen: LParen{Pos: sym.pos}, + LParen: LParen{Pos: lparen.pos}, } var comments []Comment for { - tok := in.lex(sym) - switch tok { - case _EOL: - // ignore + switch in.peek() { + case _EOLCOMMENT: + // Suffix comment, will be attached later by assignComments. + in.lex() case '\n': + // Blank line. Add an empty comment to preserve it. + in.lex() if len(comments) == 0 && len(x.Line) > 0 || len(comments) > 0 && comments[len(comments)-1].Token != "" { comments = append(comments, Comment{}) } case _COMMENT: - comments = append(comments, Comment{Start: sym.pos, Token: sym.text}) + tok := in.lex() + comments = append(comments, Comment{Start: tok.pos, Token: tok.text}) case _EOF: in.Error(fmt.Sprintf("syntax error (unterminated block started at %s:%d:%d)", in.filename, x.Start.Line, x.Start.LineRune)) case ')': + rparen := in.lex() x.RParen.Before = comments - x.RParen.Pos = sym.pos - tok = in.lex(sym) - if tok != '\n' && tok != _EOF && tok != _EOL { + x.RParen.Pos = rparen.pos + if !in.peek().isEOL() { in.Error("syntax error (expected newline after closing paren)") } + in.lex() return x default: - l := in.parseLine(sym) + l := in.parseLine() x.Line = append(x.Line, l) l.Comment().Before = comments comments = nil @@ -837,35 +882,29 @@ func (in *input) parseLineBlock(start Position, token []string, sym *symType) *L } } -func (in *input) parseLine(sym *symType) *Line { - start := sym.pos - end := sym.endPos - token := []string{sym.text} +func (in *input) parseLine() *Line { + tok := in.lex() + if tok.kind.isEOL() { + in.Error("internal parse error: parseLine at end of line") + } + start := tok.pos + end := tok.endPos + tokens := []string{tok.text} for { - tok := in.lex(sym) - switch tok { - case '\n', _EOF, _EOL: + tok := in.lex() + if tok.kind.isEOL() { return &Line{ Start: start, - Token: token, + Token: tokens, End: end, InBlock: true, } - default: - token = append(token, sym.text) - end = sym.endPos } + tokens = append(tokens, tok.text) + end = tok.endPos } } -const ( - _EOF = -(1 + iota) - _EOL - _IDENT - _STRING - _COMMENT -) - var ( slashSlash = []byte("//") moduleStr = []byte("module") diff --git a/libgo/go/golang.org/x/mod/modfile/rule.go b/libgo/go/golang.org/x/mod/modfile/rule.go index 62af06889f6..91ca6828df0 100644 --- a/libgo/go/golang.org/x/mod/modfile/rule.go +++ b/libgo/go/golang.org/x/mod/modfile/rule.go @@ -2,10 +2,24 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// Package modfile implements a parser and formatter for go.mod files. +// +// The go.mod syntax is described in +// https://golang.org/cmd/go/#hdr-The_go_mod_file. +// +// The Parse and ParseLax functions both parse a go.mod file and return an +// abstract syntax tree. ParseLax ignores unknown statements and may be used to +// parse go.mod files that may have been developed with newer versions of Go. +// +// The File struct returned by Parse and ParseLax represent an abstract +// go.mod file. File has several methods like AddNewRequire and DropReplace +// that can be used to programmatically edit a file. +// +// The Format function formats a File back to a byte slice which can be +// written to a file. package modfile import ( - "bytes" "errors" "fmt" "path/filepath" @@ -120,7 +134,7 @@ func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (*File Syntax: fs, } - var errs bytes.Buffer + var errs ErrorList for _, x := range fs.Stmt { switch x := x.(type) { case *Line: @@ -129,14 +143,22 @@ func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (*File case *LineBlock: if len(x.Token) > 1 { if strict { - fmt.Fprintf(&errs, "%s:%d: unknown block type: %s\n", file, x.Start.Line, strings.Join(x.Token, " ")) + errs = append(errs, Error{ + Filename: file, + Pos: x.Start, + Err: fmt.Errorf("unknown block type: %s", strings.Join(x.Token, " ")), + }) } continue } switch x.Token[0] { default: if strict { - fmt.Fprintf(&errs, "%s:%d: unknown block type: %s\n", file, x.Start.Line, strings.Join(x.Token, " ")) + errs = append(errs, Error{ + Filename: file, + Pos: x.Start, + Err: fmt.Errorf("unknown block type: %s", strings.Join(x.Token, " ")), + }) } continue case "module", "require", "exclude", "replace": @@ -147,15 +169,15 @@ func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (*File } } - if errs.Len() > 0 { - return nil, errors.New(strings.TrimRight(errs.String(), "\n")) + if len(errs) > 0 { + return nil, errs } return f, nil } var GoVersionRE = lazyregexp.New(`^([1-9][0-9]*)\.(0|[1-9][0-9]*)$`) -func (f *File) add(errs *bytes.Buffer, line *Line, verb string, args []string, fix VersionFixer, strict bool) { +func (f *File) add(errs *ErrorList, line *Line, verb string, args []string, fix VersionFixer, strict bool) { // If strict is false, this module is a dependency. // We ignore all unknown directives as well as main-module-only // directives like replace and exclude. It will work better for @@ -171,60 +193,83 @@ func (f *File) add(errs *bytes.Buffer, line *Line, verb string, args []string, f } } + wrapModPathError := func(modPath string, err error) { + *errs = append(*errs, Error{ + Filename: f.Syntax.Name, + Pos: line.Start, + ModPath: modPath, + Verb: verb, + Err: err, + }) + } + wrapError := func(err error) { + *errs = append(*errs, Error{ + Filename: f.Syntax.Name, + Pos: line.Start, + Err: err, + }) + } + errorf := func(format string, args ...interface{}) { + wrapError(fmt.Errorf(format, args...)) + } + switch verb { default: - fmt.Fprintf(errs, "%s:%d: unknown directive: %s\n", f.Syntax.Name, line.Start.Line, verb) + errorf("unknown directive: %s", verb) case "go": if f.Go != nil { - fmt.Fprintf(errs, "%s:%d: repeated go statement\n", f.Syntax.Name, line.Start.Line) + errorf("repeated go statement") return } - if len(args) != 1 || !GoVersionRE.MatchString(args[0]) { - fmt.Fprintf(errs, "%s:%d: usage: go 1.23\n", f.Syntax.Name, line.Start.Line) + if len(args) != 1 { + errorf("go directive expects exactly one argument") + return + } else if !GoVersionRE.MatchString(args[0]) { + errorf("invalid go version '%s': must match format 1.23", args[0]) return } + f.Go = &Go{Syntax: line} f.Go.Version = args[0] case "module": if f.Module != nil { - fmt.Fprintf(errs, "%s:%d: repeated module statement\n", f.Syntax.Name, line.Start.Line) + errorf("repeated module statement") return } f.Module = &Module{Syntax: line} if len(args) != 1 { - - fmt.Fprintf(errs, "%s:%d: usage: module module/path\n", f.Syntax.Name, line.Start.Line) + errorf("usage: module module/path") return } s, err := parseString(&args[0]) if err != nil { - fmt.Fprintf(errs, "%s:%d: invalid quoted string: %v\n", f.Syntax.Name, line.Start.Line, err) + errorf("invalid quoted string: %v", err) return } f.Module.Mod = module.Version{Path: s} case "require", "exclude": if len(args) != 2 { - fmt.Fprintf(errs, "%s:%d: usage: %s module/path v1.2.3\n", f.Syntax.Name, line.Start.Line, verb) + errorf("usage: %s module/path v1.2.3", verb) return } s, err := parseString(&args[0]) if err != nil { - fmt.Fprintf(errs, "%s:%d: invalid quoted string: %v\n", f.Syntax.Name, line.Start.Line, err) + errorf("invalid quoted string: %v", err) return } v, err := parseVersion(verb, s, &args[1], fix) if err != nil { - fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, err) + wrapError(err) return } pathMajor, err := modulePathMajor(s) if err != nil { - fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, err) + wrapError(err) return } if err := module.CheckPathMajor(v, pathMajor); err != nil { - fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, &Error{Verb: verb, ModPath: s, Err: err}) + wrapModPathError(s, err) return } if verb == "require" { @@ -245,55 +290,55 @@ func (f *File) add(errs *bytes.Buffer, line *Line, verb string, args []string, f arrow = 1 } if len(args) < arrow+2 || len(args) > arrow+3 || args[arrow] != "=>" { - fmt.Fprintf(errs, "%s:%d: usage: %s module/path [v1.2.3] => other/module v1.4\n\t or %s module/path [v1.2.3] => ../local/directory\n", f.Syntax.Name, line.Start.Line, verb, verb) + errorf("usage: %s module/path [v1.2.3] => other/module v1.4\n\t or %s module/path [v1.2.3] => ../local/directory", verb, verb) return } s, err := parseString(&args[0]) if err != nil { - fmt.Fprintf(errs, "%s:%d: invalid quoted string: %v\n", f.Syntax.Name, line.Start.Line, err) + errorf("invalid quoted string: %v", err) return } pathMajor, err := modulePathMajor(s) if err != nil { - fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, err) + wrapModPathError(s, err) return } var v string if arrow == 2 { v, err = parseVersion(verb, s, &args[1], fix) if err != nil { - fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, err) + wrapError(err) return } if err := module.CheckPathMajor(v, pathMajor); err != nil { - fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, &Error{Verb: verb, ModPath: s, Err: err}) + wrapModPathError(s, err) return } } ns, err := parseString(&args[arrow+1]) if err != nil { - fmt.Fprintf(errs, "%s:%d: invalid quoted string: %v\n", f.Syntax.Name, line.Start.Line, err) + errorf("invalid quoted string: %v", err) return } nv := "" if len(args) == arrow+2 { if !IsDirectoryPath(ns) { - fmt.Fprintf(errs, "%s:%d: replacement module without version must be directory path (rooted or starting with ./ or ../)\n", f.Syntax.Name, line.Start.Line) + errorf("replacement module without version must be directory path (rooted or starting with ./ or ../)") return } if filepath.Separator == '/' && strings.Contains(ns, `\`) { - fmt.Fprintf(errs, "%s:%d: replacement directory appears to be Windows path (on a non-windows system)\n", f.Syntax.Name, line.Start.Line) + errorf("replacement directory appears to be Windows path (on a non-windows system)") return } } if len(args) == arrow+3 { nv, err = parseVersion(verb, ns, &args[arrow+2], fix) if err != nil { - fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, err) + wrapError(err) return } if IsDirectoryPath(ns) { - fmt.Fprintf(errs, "%s:%d: replacement module directory path %q cannot have version\n", f.Syntax.Name, line.Start.Line, ns) + errorf("replacement module directory path %q cannot have version", ns) return } } @@ -372,8 +417,19 @@ func IsDirectoryPath(ns string) bool { // a single token in a go.mod line. func MustQuote(s string) bool { for _, r := range s { - if !unicode.IsPrint(r) || r == ' ' || r == '"' || r == '\'' || r == '`' { + switch r { + case ' ', '"', '\'', '`': return true + + case '(', ')', '[', ']', '{', '}', ',': + if len(s) > 1 { + return true + } + + default: + if !unicode.IsPrint(r) { + return true + } } } return s == "" || strings.Contains(s, "//") || strings.Contains(s, "/*") @@ -405,14 +461,42 @@ func parseString(s *string) (string, error) { return t, nil } +type ErrorList []Error + +func (e ErrorList) Error() string { + errStrs := make([]string, len(e)) + for i, err := range e { + errStrs[i] = err.Error() + } + return strings.Join(errStrs, "\n") +} + type Error struct { - Verb string - ModPath string - Err error + Filename string + Pos Position + Verb string + ModPath string + Err error } func (e *Error) Error() string { - return fmt.Sprintf("%s %s: %v", e.Verb, e.ModPath, e.Err) + var pos string + if e.Pos.LineRune > 1 { + // Don't print LineRune if it's 1 (beginning of line). + // It's always 1 except in scanner errors, which are rare. + pos = fmt.Sprintf("%s:%d:%d: ", e.Filename, e.Pos.Line, e.Pos.LineRune) + } else if e.Pos.Line > 0 { + pos = fmt.Sprintf("%s:%d: ", e.Filename, e.Pos.Line) + } else if e.Filename != "" { + pos = fmt.Sprintf("%s: ", e.Filename) + } + + var directive string + if e.ModPath != "" { + directive = fmt.Sprintf("%s %s: ", e.Verb, e.ModPath) + } + + return pos + directive + e.Err.Error() } func (e *Error) Unwrap() error { return e.Err } diff --git a/libgo/go/golang.org/x/mod/zip/zip.go b/libgo/go/golang.org/x/mod/zip/zip.go index 37c764257e4..6865895b3d0 100644 --- a/libgo/go/golang.org/x/mod/zip/zip.go +++ b/libgo/go/golang.org/x/mod/zip/zip.go @@ -247,6 +247,9 @@ func CreateFromDir(w io.Writer, m module.Version, dir string) (err error) { var files []File err = filepath.Walk(dir, func(filePath string, info os.FileInfo, err error) error { + if err != nil { + return err + } relPath, err := filepath.Rel(dir, filePath) if err != nil { return err @@ -313,6 +316,12 @@ func (f dirFile) Path() string { return f.slashPath } func (f dirFile) Lstat() (os.FileInfo, error) { return f.info, nil } func (f dirFile) Open() (io.ReadCloser, error) { return os.Open(f.filePath) } +// isVendoredPackage attempts to report whether the given filename is contained +// in a package whose import path contains (but does not end with) the component +// "vendor". +// +// Unfortunately, isVendoredPackage reports false positives for files in any +// non-top-level package whose import path ends in "vendor". func isVendoredPackage(name string) bool { var i int if strings.HasPrefix(name, "vendor/") { @@ -322,15 +331,8 @@ func isVendoredPackage(name string) bool { // // i = j + len("/vendor/") // - // (See https://golang.org/issue/31562.) - // - // Unfortunately, we can't fix it without invalidating checksums. - // Fortunately, the error appears to be strictly conservative: we'll retain - // vendored packages that we should have pruned, but we won't prune - // non-vendored packages that we should have retained. - // - // Since this defect doesn't seem to break anything, it's not worth fixing - // for now. + // (See https://golang.org/issue/31562 and https://golang.org/issue/37397.) + // Unfortunately, we can't fix it without invalidating module checksums. i += len("/vendor/") } else { return false diff --git a/libgo/go/golang.org/x/net/dns/dnsmessage/message.go b/libgo/go/golang.org/x/net/dns/dnsmessage/message.go index 82bcdcc838c..654f191f8a9 100644 --- a/libgo/go/golang.org/x/net/dns/dnsmessage/message.go +++ b/libgo/go/golang.org/x/net/dns/dnsmessage/message.go @@ -1819,17 +1819,6 @@ func unpackText(msg []byte, off int) (string, int, error) { return string(msg[beginOff:endOff]), endOff, nil } -func skipText(msg []byte, off int) (int, error) { - if off >= len(msg) { - return off, errBaseLen - } - endOff := off + 1 + int(msg[off]) - if endOff > len(msg) { - return off, errCalcLen - } - return endOff, nil -} - // packBytes appends the wire format of field to msg. func packBytes(msg []byte, field []byte) []byte { return append(msg, field...) @@ -1844,14 +1833,6 @@ func unpackBytes(msg []byte, off int, field []byte) (int, error) { return newOff, nil } -func skipBytes(msg []byte, off int, field []byte) (int, error) { - newOff := off + len(field) - if newOff > len(msg) { - return off, errBaseLen - } - return newOff, nil -} - const nameLen = 255 // A Name is a non-encoded domain name. It is used instead of strings to avoid @@ -2159,7 +2140,7 @@ func unpackResourceBody(msg []byte, off int, hdr ResourceHeader) (ResourceBody, return nil, off, &nestedError{name + " record", err} } if r == nil { - return nil, off, errors.New("invalid resource type: " + string(hdr.Type+'0')) + return nil, off, errors.New("invalid resource type: " + hdr.Type.String()) } return r, off + int(hdr.Length), nil } diff --git a/libgo/go/golang.org/x/net/http2/hpack/huffman.go b/libgo/go/golang.org/x/net/http2/hpack/huffman.go index b412a96c504..a1ab2f05679 100644 --- a/libgo/go/golang.org/x/net/http2/hpack/huffman.go +++ b/libgo/go/golang.org/x/net/http2/hpack/huffman.go @@ -105,7 +105,14 @@ func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error { return nil } +// incomparable is a zero-width, non-comparable type. Adding it to a struct +// makes that struct also non-comparable, and generally doesn't add +// any size (as long as it's first). +type incomparable [0]func() + type node struct { + _ incomparable + // children is non-nil for internal nodes children *[256]*node diff --git a/libgo/go/golang.org/x/net/route/address.go b/libgo/go/golang.org/x/net/route/address.go index b71528191f6..e3125a473bc 100644 --- a/libgo/go/golang.org/x/net/route/address.go +++ b/libgo/go/golang.org/x/net/route/address.go @@ -46,12 +46,12 @@ func (a *LinkAddr) marshal(b []byte) (int, error) { data := b[8:] if nlen > 0 { b[5] = byte(nlen) - copy(data[:nlen], a.Addr) + copy(data[:nlen], a.Name) data = data[nlen:] } if alen > 0 { b[6] = byte(alen) - copy(data[:alen], a.Name) + copy(data[:alen], a.Addr) data = data[alen:] } return ll, nil diff --git a/libgo/go/golang.org/x/net/route/route.go b/libgo/go/golang.org/x/net/route/route.go index bba7ed7ef4e..4462cf1b6f6 100644 --- a/libgo/go/golang.org/x/net/route/route.go +++ b/libgo/go/golang.org/x/net/route/route.go @@ -88,7 +88,7 @@ func (m *RouteMessage) Marshal() ([]byte, error) { return m.marshal() } -// A RIBType reprensents a type of routing information base. +// A RIBType represents a type of routing information base. type RIBType int const ( diff --git a/libgo/go/golang.org/x/sys/cpu/byteorder.go b/libgo/go/golang.org/x/sys/cpu/byteorder.go index 74116e97abb..ff3eb5b4481 100644 --- a/libgo/go/golang.org/x/sys/cpu/byteorder.go +++ b/libgo/go/golang.org/x/sys/cpu/byteorder.go @@ -5,13 +5,43 @@ package cpu import ( - "encoding/binary" "runtime" ) +// byteOrder is a subset of encoding/binary.ByteOrder. +type byteOrder interface { + Uint32([]byte) uint32 + Uint64([]byte) uint64 +} + +type littleEndian struct{} +type bigEndian struct{} + +func (littleEndian) Uint32(b []byte) uint32 { + _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808 + return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 +} + +func (littleEndian) Uint64(b []byte) uint64 { + _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808 + return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | + uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 +} + +func (bigEndian) Uint32(b []byte) uint32 { + _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808 + return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 +} + +func (bigEndian) Uint64(b []byte) uint64 { + _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808 + return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | + uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56 +} + // hostByteOrder returns binary.LittleEndian on little-endian machines and // binary.BigEndian on big-endian machines. -func hostByteOrder() binary.ByteOrder { +func hostByteOrder() byteOrder { switch runtime.GOARCH { case "386", "amd64", "amd64p32", "alpha", @@ -21,7 +51,7 @@ func hostByteOrder() binary.ByteOrder { "ppc64le", "riscv", "riscv64", "sh": - return binary.LittleEndian + return littleEndian{} case "armbe", "arm64be", "m68k", "mips", "mips64", "mips64p32", @@ -29,7 +59,7 @@ func hostByteOrder() binary.ByteOrder { "s390", "s390x", "shbe", "sparc", "sparc64": - return binary.BigEndian + return bigEndian{} } panic("unknown architecture") } diff --git a/libgo/go/golang.org/x/sys/cpu/cpu.go b/libgo/go/golang.org/x/sys/cpu/cpu.go index 679e78c2cef..e44deb75746 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu.go @@ -78,6 +78,51 @@ var ARM64 struct { _ CacheLinePad } +// ARM contains the supported CPU features of the current ARM (32-bit) platform. +// All feature flags are false if: +// 1. the current platform is not arm, or +// 2. the current operating system is not Linux. +var ARM struct { + _ CacheLinePad + HasSWP bool // SWP instruction support + HasHALF bool // Half-word load and store support + HasTHUMB bool // ARM Thumb instruction set + Has26BIT bool // Address space limited to 26-bits + HasFASTMUL bool // 32-bit operand, 64-bit result multiplication support + HasFPA bool // Floating point arithmetic support + HasVFP bool // Vector floating point support + HasEDSP bool // DSP Extensions support + HasJAVA bool // Java instruction set + HasIWMMXT bool // Intel Wireless MMX technology support + HasCRUNCH bool // MaverickCrunch context switching and handling + HasTHUMBEE bool // Thumb EE instruction set + HasNEON bool // NEON instruction set + HasVFPv3 bool // Vector floating point version 3 support + HasVFPv3D16 bool // Vector floating point version 3 D8-D15 + HasTLS bool // Thread local storage support + HasVFPv4 bool // Vector floating point version 4 support + HasIDIVA bool // Integer divide instruction support in ARM mode + HasIDIVT bool // Integer divide instruction support in Thumb mode + HasVFPD32 bool // Vector floating point version 3 D15-D31 + HasLPAE bool // Large Physical Address Extensions + HasEVTSTRM bool // Event stream support + HasAES bool // AES hardware implementation + HasPMULL bool // Polynomial multiplication instruction set + HasSHA1 bool // SHA1 hardware implementation + HasSHA2 bool // SHA2 hardware implementation + HasCRC32 bool // CRC32 hardware implementation + _ CacheLinePad +} + +// MIPS64X contains the supported CPU features of the current mips64/mips64le +// platforms. If the current platform is not mips64/mips64le or the current +// operating system is not Linux then all feature flags are false. +var MIPS64X struct { + _ CacheLinePad + HasMSA bool // MIPS SIMD architecture + _ CacheLinePad +} + // PPC64 contains the supported CPU features of the current ppc64/ppc64le platforms. // If the current platform is not ppc64/ppc64le then all feature flags are false. // diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_arm.go b/libgo/go/golang.org/x/sys/cpu/cpu_arm.go new file mode 100644 index 00000000000..bb0b91577cf --- /dev/null +++ b/libgo/go/golang.org/x/sys/cpu/cpu_arm.go @@ -0,0 +1,40 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cpu + +// const cacheLineSize = 32 + +// HWCAP/HWCAP2 bits. +// These are specific to Linux. +const ( + hwcap_SWP = 1 << 0 + hwcap_HALF = 1 << 1 + hwcap_THUMB = 1 << 2 + hwcap_26BIT = 1 << 3 + hwcap_FAST_MULT = 1 << 4 + hwcap_FPA = 1 << 5 + hwcap_VFP = 1 << 6 + hwcap_EDSP = 1 << 7 + hwcap_JAVA = 1 << 8 + hwcap_IWMMXT = 1 << 9 + hwcap_CRUNCH = 1 << 10 + hwcap_THUMBEE = 1 << 11 + hwcap_NEON = 1 << 12 + hwcap_VFPv3 = 1 << 13 + hwcap_VFPv3D16 = 1 << 14 + hwcap_TLS = 1 << 15 + hwcap_VFPv4 = 1 << 16 + hwcap_IDIVA = 1 << 17 + hwcap_IDIVT = 1 << 18 + hwcap_VFPD32 = 1 << 19 + hwcap_LPAE = 1 << 20 + hwcap_EVTSTRM = 1 << 21 + + hwcap2_AES = 1 << 0 + hwcap2_PMULL = 1 << 1 + hwcap2_SHA1 = 1 << 2 + hwcap2_SHA2 = 1 << 3 + hwcap2_CRC32 = 1 << 4 +) diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_arm64.go b/libgo/go/golang.org/x/sys/cpu/cpu_arm64.go new file mode 100644 index 00000000000..74df5c6ff83 --- /dev/null +++ b/libgo/go/golang.org/x/sys/cpu/cpu_arm64.go @@ -0,0 +1,138 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cpu + +import "runtime" + +// const cacheLineSize = 64 + +func init() { + switch runtime.GOOS { + case "android", "darwin": + // Android and iOS don't seem to allow reading these registers. + // Fake the minimal features expected by + // TestARM64minimalFeatures. + ARM64.HasASIMD = true + ARM64.HasFP = true + case "linux": + doinit() + default: + readARM64Registers() + } +} + +func readARM64Registers() { + Initialized = true + + // ID_AA64ISAR0_EL1 + isar0 := getisar0() + + switch extractBits(isar0, 4, 7) { + case 1: + ARM64.HasAES = true + case 2: + ARM64.HasAES = true + ARM64.HasPMULL = true + } + + switch extractBits(isar0, 8, 11) { + case 1: + ARM64.HasSHA1 = true + } + + switch extractBits(isar0, 12, 15) { + case 1: + ARM64.HasSHA2 = true + case 2: + ARM64.HasSHA2 = true + ARM64.HasSHA512 = true + } + + switch extractBits(isar0, 16, 19) { + case 1: + ARM64.HasCRC32 = true + } + + switch extractBits(isar0, 20, 23) { + case 2: + ARM64.HasATOMICS = true + } + + switch extractBits(isar0, 28, 31) { + case 1: + ARM64.HasASIMDRDM = true + } + + switch extractBits(isar0, 32, 35) { + case 1: + ARM64.HasSHA3 = true + } + + switch extractBits(isar0, 36, 39) { + case 1: + ARM64.HasSM3 = true + } + + switch extractBits(isar0, 40, 43) { + case 1: + ARM64.HasSM4 = true + } + + switch extractBits(isar0, 44, 47) { + case 1: + ARM64.HasASIMDDP = true + } + + // ID_AA64ISAR1_EL1 + isar1 := getisar1() + + switch extractBits(isar1, 0, 3) { + case 1: + ARM64.HasDCPOP = true + } + + switch extractBits(isar1, 12, 15) { + case 1: + ARM64.HasJSCVT = true + } + + switch extractBits(isar1, 16, 19) { + case 1: + ARM64.HasFCMA = true + } + + switch extractBits(isar1, 20, 23) { + case 1: + ARM64.HasLRCPC = true + } + + // ID_AA64PFR0_EL1 + pfr0 := getpfr0() + + switch extractBits(pfr0, 16, 19) { + case 0: + ARM64.HasFP = true + case 1: + ARM64.HasFP = true + ARM64.HasFPHP = true + } + + switch extractBits(pfr0, 20, 23) { + case 0: + ARM64.HasASIMD = true + case 1: + ARM64.HasASIMD = true + ARM64.HasASIMDHP = true + } + + switch extractBits(pfr0, 32, 35) { + case 1: + ARM64.HasSVE = true + } +} + +func extractBits(data uint64, start, end uint) uint { + return (uint)(data>>start) & ((1 << (end - start + 1)) - 1) +} diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_gc_arm64.go b/libgo/go/golang.org/x/sys/cpu/cpu_gc_arm64.go new file mode 100644 index 00000000000..7b88e865a42 --- /dev/null +++ b/libgo/go/golang.org/x/sys/cpu/cpu_gc_arm64.go @@ -0,0 +1,11 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !gccgo + +package cpu + +func getisar0() uint64 +func getisar1() uint64 +func getpfr0() uint64 diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_gccgo.c b/libgo/go/golang.org/x/sys/cpu/cpu_gccgo.c deleted file mode 100644 index e363c7d1319..00000000000 --- a/libgo/go/golang.org/x/sys/cpu/cpu_gccgo.c +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build 386 amd64 amd64p32 -// +build gccgo - -#include -#include - -// Need to wrap __get_cpuid_count because it's declared as static. -int -gccgoGetCpuidCount(uint32_t leaf, uint32_t subleaf, - uint32_t *eax, uint32_t *ebx, - uint32_t *ecx, uint32_t *edx) -{ - return __get_cpuid_count(leaf, subleaf, eax, ebx, ecx, edx); -} - -// xgetbv reads the contents of an XCR (Extended Control Register) -// specified in the ECX register into registers EDX:EAX. -// Currently, the only supported value for XCR is 0. -// -// TODO: Replace with a better alternative: -// -// #include -// -// #pragma GCC target("xsave") -// -// void gccgoXgetbv(uint32_t *eax, uint32_t *edx) { -// unsigned long long x = _xgetbv(0); -// *eax = x & 0xffffffff; -// *edx = (x >> 32) & 0xffffffff; -// } -// -// Note that _xgetbv is defined starting with GCC 8. -void -gccgoXgetbv(uint32_t *eax, uint32_t *edx) -{ - __asm(" xorl %%ecx, %%ecx\n" - " xgetbv" - : "=a"(*eax), "=d"(*edx)); -} diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_gccgo.go b/libgo/go/golang.org/x/sys/cpu/cpu_gccgo.go deleted file mode 100644 index ba49b91bd39..00000000000 --- a/libgo/go/golang.org/x/sys/cpu/cpu_gccgo.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build 386 amd64 amd64p32 -// +build gccgo - -package cpu - -//extern gccgoGetCpuidCount -func gccgoGetCpuidCount(eaxArg, ecxArg uint32, eax, ebx, ecx, edx *uint32) - -func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) { - var a, b, c, d uint32 - gccgoGetCpuidCount(eaxArg, ecxArg, &a, &b, &c, &d) - return a, b, c, d -} - -//extern gccgoXgetbv -func gccgoXgetbv(eax, edx *uint32) - -func xgetbv() (eax, edx uint32) { - var a, d uint32 - gccgoXgetbv(&a, &d) - return a, d -} diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_gccgo_arm64.go b/libgo/go/golang.org/x/sys/cpu/cpu_gccgo_arm64.go new file mode 100644 index 00000000000..53ca8d65c37 --- /dev/null +++ b/libgo/go/golang.org/x/sys/cpu/cpu_gccgo_arm64.go @@ -0,0 +1,11 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build gccgo + +package cpu + +func getisar0() uint64 { return 0 } +func getisar1() uint64 { return 0 } +func getpfr0() uint64 { return 0 } diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_gccgo_x86.c b/libgo/go/golang.org/x/sys/cpu/cpu_gccgo_x86.c new file mode 100644 index 00000000000..e363c7d1319 --- /dev/null +++ b/libgo/go/golang.org/x/sys/cpu/cpu_gccgo_x86.c @@ -0,0 +1,43 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build 386 amd64 amd64p32 +// +build gccgo + +#include +#include + +// Need to wrap __get_cpuid_count because it's declared as static. +int +gccgoGetCpuidCount(uint32_t leaf, uint32_t subleaf, + uint32_t *eax, uint32_t *ebx, + uint32_t *ecx, uint32_t *edx) +{ + return __get_cpuid_count(leaf, subleaf, eax, ebx, ecx, edx); +} + +// xgetbv reads the contents of an XCR (Extended Control Register) +// specified in the ECX register into registers EDX:EAX. +// Currently, the only supported value for XCR is 0. +// +// TODO: Replace with a better alternative: +// +// #include +// +// #pragma GCC target("xsave") +// +// void gccgoXgetbv(uint32_t *eax, uint32_t *edx) { +// unsigned long long x = _xgetbv(0); +// *eax = x & 0xffffffff; +// *edx = (x >> 32) & 0xffffffff; +// } +// +// Note that _xgetbv is defined starting with GCC 8. +void +gccgoXgetbv(uint32_t *eax, uint32_t *edx) +{ + __asm(" xorl %%ecx, %%ecx\n" + " xgetbv" + : "=a"(*eax), "=d"(*edx)); +} diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_gccgo_x86.go b/libgo/go/golang.org/x/sys/cpu/cpu_gccgo_x86.go new file mode 100644 index 00000000000..ba49b91bd39 --- /dev/null +++ b/libgo/go/golang.org/x/sys/cpu/cpu_gccgo_x86.go @@ -0,0 +1,26 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build 386 amd64 amd64p32 +// +build gccgo + +package cpu + +//extern gccgoGetCpuidCount +func gccgoGetCpuidCount(eaxArg, ecxArg uint32, eax, ebx, ecx, edx *uint32) + +func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) { + var a, b, c, d uint32 + gccgoGetCpuidCount(eaxArg, ecxArg, &a, &b, &c, &d) + return a, b, c, d +} + +//extern gccgoXgetbv +func gccgoXgetbv(eax, edx *uint32) + +func xgetbv() (eax, edx uint32) { + var a, d uint32 + gccgoXgetbv(&a, &d) + return a, d +} diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_linux.go b/libgo/go/golang.org/x/sys/cpu/cpu_linux.go index 76b5f507faf..fe139182c8d 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu_linux.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu_linux.go @@ -2,58 +2,14 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//+build !amd64,!amd64p32,!386 +// +build !386,!amd64,!amd64p32,!arm64 package cpu -import ( - "io/ioutil" -) - -const ( - _AT_HWCAP = 16 - _AT_HWCAP2 = 26 - - procAuxv = "/proc/self/auxv" - - uintSize = int(32 << (^uint(0) >> 63)) -) - -// For those platforms don't have a 'cpuid' equivalent we use HWCAP/HWCAP2 -// These are initialized in cpu_$GOARCH.go -// and should not be changed after they are initialized. -var hwCap uint -var hwCap2 uint - func init() { - buf, err := ioutil.ReadFile(procAuxv) - if err != nil { - // e.g. on android /proc/self/auxv is not accessible, so silently - // ignore the error and leave Initialized = false + if err := readHWCAP(); err != nil { return } - - bo := hostByteOrder() - for len(buf) >= 2*(uintSize/8) { - var tag, val uint - switch uintSize { - case 32: - tag = uint(bo.Uint32(buf[0:])) - val = uint(bo.Uint32(buf[4:])) - buf = buf[8:] - case 64: - tag = uint(bo.Uint64(buf[0:])) - val = uint(bo.Uint64(buf[8:])) - buf = buf[16:] - } - switch tag { - case _AT_HWCAP: - hwCap = val - case _AT_HWCAP2: - hwCap2 = val - } - } doinit() - Initialized = true } diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_linux_arm.go b/libgo/go/golang.org/x/sys/cpu/cpu_linux_arm.go new file mode 100644 index 00000000000..2057006dce4 --- /dev/null +++ b/libgo/go/golang.org/x/sys/cpu/cpu_linux_arm.go @@ -0,0 +1,39 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cpu + +func doinit() { + ARM.HasSWP = isSet(hwCap, hwcap_SWP) + ARM.HasHALF = isSet(hwCap, hwcap_HALF) + ARM.HasTHUMB = isSet(hwCap, hwcap_THUMB) + ARM.Has26BIT = isSet(hwCap, hwcap_26BIT) + ARM.HasFASTMUL = isSet(hwCap, hwcap_FAST_MULT) + ARM.HasFPA = isSet(hwCap, hwcap_FPA) + ARM.HasVFP = isSet(hwCap, hwcap_VFP) + ARM.HasEDSP = isSet(hwCap, hwcap_EDSP) + ARM.HasJAVA = isSet(hwCap, hwcap_JAVA) + ARM.HasIWMMXT = isSet(hwCap, hwcap_IWMMXT) + ARM.HasCRUNCH = isSet(hwCap, hwcap_CRUNCH) + ARM.HasTHUMBEE = isSet(hwCap, hwcap_THUMBEE) + ARM.HasNEON = isSet(hwCap, hwcap_NEON) + ARM.HasVFPv3 = isSet(hwCap, hwcap_VFPv3) + ARM.HasVFPv3D16 = isSet(hwCap, hwcap_VFPv3D16) + ARM.HasTLS = isSet(hwCap, hwcap_TLS) + ARM.HasVFPv4 = isSet(hwCap, hwcap_VFPv4) + ARM.HasIDIVA = isSet(hwCap, hwcap_IDIVA) + ARM.HasIDIVT = isSet(hwCap, hwcap_IDIVT) + ARM.HasVFPD32 = isSet(hwCap, hwcap_VFPD32) + ARM.HasLPAE = isSet(hwCap, hwcap_LPAE) + ARM.HasEVTSTRM = isSet(hwCap, hwcap_EVTSTRM) + ARM.HasAES = isSet(hwCap2, hwcap2_AES) + ARM.HasPMULL = isSet(hwCap2, hwcap2_PMULL) + ARM.HasSHA1 = isSet(hwCap2, hwcap2_SHA1) + ARM.HasSHA2 = isSet(hwCap2, hwcap2_SHA2) + ARM.HasCRC32 = isSet(hwCap2, hwcap2_CRC32) +} + +func isSet(hwc uint, value uint) bool { + return hwc&value != 0 +} diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_linux_arm64.go b/libgo/go/golang.org/x/sys/cpu/cpu_linux_arm64.go index 15a9b4a7cc7..79a38a0b9bc 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu_linux_arm64.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu_linux_arm64.go @@ -33,6 +33,12 @@ const ( ) func doinit() { + if err := readHWCAP(); err != nil { + // failed to read /proc/self/auxv, try reading registers directly + readARM64Registers() + return + } + // HWCAP feature bits ARM64.HasFP = isSet(hwCap, hwcap_FP) ARM64.HasASIMD = isSet(hwCap, hwcap_ASIMD) diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_linux_mips64x.go b/libgo/go/golang.org/x/sys/cpu/cpu_linux_mips64x.go new file mode 100644 index 00000000000..eb24e5073e7 --- /dev/null +++ b/libgo/go/golang.org/x/sys/cpu/cpu_linux_mips64x.go @@ -0,0 +1,22 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build mips64 mips64le + +package cpu + +// HWCAP bits. These are exposed by the Linux kernel 5.4. +const ( + // CPU features + hwcap_MIPS_MSA = 1 << 1 +) + +func doinit() { + // HWCAP feature bits + MIPS64X.HasMSA = isSet(hwCap, hwcap_MIPS_MSA) +} + +func isSet(hwc uint, value uint) bool { + return hwc&value != 0 +} diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_linux_noinit.go b/libgo/go/golang.org/x/sys/cpu/cpu_linux_noinit.go new file mode 100644 index 00000000000..42b5d33cb69 --- /dev/null +++ b/libgo/go/golang.org/x/sys/cpu/cpu_linux_noinit.go @@ -0,0 +1,9 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build linux,!arm,!arm64,!mips64,!mips64le,!ppc64,!ppc64le,!s390x + +package cpu + +func doinit() {} diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_linux_other.go b/libgo/go/golang.org/x/sys/cpu/cpu_linux_other.go deleted file mode 100644 index 6e8f9fe1920..00000000000 --- a/libgo/go/golang.org/x/sys/cpu/cpu_linux_other.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !amd64,!amd64p32,!386,!arm64,!ppc64,!ppc64le,!s390x - -package cpu - -func doinit() {} diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_linux_ppc64x.go b/libgo/go/golang.org/x/sys/cpu/cpu_linux_ppc64x.go index 99f8a6399ef..6b1b8932f16 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu_linux_ppc64x.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu_linux_ppc64x.go @@ -7,6 +7,8 @@ package cpu +// const cacheLineSize = 128 + // HWCAP/HWCAP2 bits. These are exposed by the kernel. const ( // ISA Level diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_linux_s390x.go b/libgo/go/golang.org/x/sys/cpu/cpu_linux_s390x.go index b88d6b8f662..92f2896ffa0 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu_linux_s390x.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu_linux_s390x.go @@ -4,6 +4,8 @@ package cpu +// const cacheLineSize = 256 + const ( // bit mask values from /usr/include/bits/hwcap.h hwcap_ZARCH = 2 diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_mips64x.go b/libgo/go/golang.org/x/sys/cpu/cpu_mips64x.go new file mode 100644 index 00000000000..35675579033 --- /dev/null +++ b/libgo/go/golang.org/x/sys/cpu/cpu_mips64x.go @@ -0,0 +1,9 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build mips64 mips64le + +package cpu + +// const cacheLineSize = 32 diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_mipsx.go b/libgo/go/golang.org/x/sys/cpu/cpu_mipsx.go new file mode 100644 index 00000000000..2af7fa5b0a4 --- /dev/null +++ b/libgo/go/golang.org/x/sys/cpu/cpu_mipsx.go @@ -0,0 +1,9 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build mips mipsle + +package cpu + +// const cacheLineSize = 32 diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_other_arm64.go b/libgo/go/golang.org/x/sys/cpu/cpu_other_arm64.go new file mode 100644 index 00000000000..3ffc4afa03c --- /dev/null +++ b/libgo/go/golang.org/x/sys/cpu/cpu_other_arm64.go @@ -0,0 +1,9 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !linux,arm64 + +package cpu + +func doinit() {} diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_riscv64.go b/libgo/go/golang.org/x/sys/cpu/cpu_riscv64.go index 18c8a48b9c3..bc41bbb3b3b 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu_riscv64.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu_riscv64.go @@ -5,3 +5,5 @@ // +build riscv64 package cpu + +// const cacheLineSize = 32 diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_wasm.go b/libgo/go/golang.org/x/sys/cpu/cpu_wasm.go new file mode 100644 index 00000000000..c890010e308 --- /dev/null +++ b/libgo/go/golang.org/x/sys/cpu/cpu_wasm.go @@ -0,0 +1,13 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build wasm + +package cpu + +// We're compiling the cpu package for an unknown (software-abstracted) CPU. +// Make CacheLinePad an empty struct and hope that the usual struct alignment +// rules are good enough. + +// const cacheLineSize = 0 diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_x86.go b/libgo/go/golang.org/x/sys/cpu/cpu_x86.go index 6009379c7fa..d6afec9f97a 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu_x86.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu_x86.go @@ -6,6 +6,8 @@ package cpu +// const cacheLineSize = 64 + func init() { Initialized = true diff --git a/libgo/go/golang.org/x/sys/cpu/hwcap_linux.go b/libgo/go/golang.org/x/sys/cpu/hwcap_linux.go new file mode 100644 index 00000000000..f3baa379328 --- /dev/null +++ b/libgo/go/golang.org/x/sys/cpu/hwcap_linux.go @@ -0,0 +1,56 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cpu + +import ( + "io/ioutil" +) + +const ( + _AT_HWCAP = 16 + _AT_HWCAP2 = 26 + + procAuxv = "/proc/self/auxv" + + uintSize = int(32 << (^uint(0) >> 63)) +) + +// For those platforms don't have a 'cpuid' equivalent we use HWCAP/HWCAP2 +// These are initialized in cpu_$GOARCH.go +// and should not be changed after they are initialized. +var hwCap uint +var hwCap2 uint + +func readHWCAP() error { + buf, err := ioutil.ReadFile(procAuxv) + if err != nil { + // e.g. on android /proc/self/auxv is not accessible, so silently + // ignore the error and leave Initialized = false. On some + // architectures (e.g. arm64) doinit() implements a fallback + // readout and will set Initialized = true again. + return err + } + bo := hostByteOrder() + for len(buf) >= 2*(uintSize/8) { + var tag, val uint + switch uintSize { + case 32: + tag = uint(bo.Uint32(buf[0:])) + val = uint(bo.Uint32(buf[4:])) + buf = buf[8:] + case 64: + tag = uint(bo.Uint64(buf[0:])) + val = uint(bo.Uint64(buf[8:])) + buf = buf[16:] + } + switch tag { + case _AT_HWCAP: + hwCap = val + case _AT_HWCAP2: + hwCap2 = val + } + } + return nil +} diff --git a/libgo/go/golang.org/x/text/unicode/bidi/core.go b/libgo/go/golang.org/x/text/unicode/bidi/core.go index 48d144008aa..50deb6600a3 100644 --- a/libgo/go/golang.org/x/text/unicode/bidi/core.go +++ b/libgo/go/golang.org/x/text/unicode/bidi/core.go @@ -480,15 +480,15 @@ func (s *isolatingRunSequence) resolveWeakTypes() { // Rule W1. // Changes all NSMs. - preceedingCharacterType := s.sos + precedingCharacterType := s.sos for i, t := range s.types { if t == NSM { - s.types[i] = preceedingCharacterType + s.types[i] = precedingCharacterType } else { if t.in(LRI, RLI, FSI, PDI) { - preceedingCharacterType = ON + precedingCharacterType = ON } - preceedingCharacterType = t + precedingCharacterType = t } } diff --git a/libgo/go/golang.org/x/tools/go/analysis/analysis.go b/libgo/go/golang.org/x/tools/go/analysis/analysis.go index ea605f4fd46..8c9977355c9 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/analysis.go +++ b/libgo/go/golang.org/x/tools/go/analysis/analysis.go @@ -7,6 +7,8 @@ import ( "go/token" "go/types" "reflect" + + "golang.org/x/tools/internal/analysisinternal" ) // An Analyzer describes an analysis function and its options. @@ -69,6 +71,17 @@ type Analyzer struct { func (a *Analyzer) String() string { return a.Name } +func init() { + // Set the analysisinternal functions to be able to pass type errors + // to the Pass type without modifying the go/analysis API. + analysisinternal.SetTypeErrors = func(p interface{}, errors []types.Error) { + p.(*Pass).typeErrors = errors + } + analysisinternal.GetTypeErrors = func(p interface{}) []types.Error { + return p.(*Pass).typeErrors + } +} + // A Pass provides information to the Run function that // applies a specific analyzer to a single Go package. // @@ -138,6 +151,9 @@ type Pass struct { // WARNING: This is an experimental API and may change in the future. AllObjectFacts func() []ObjectFact + // typeErrors contains types.Errors that are associated with the pkg. + typeErrors []types.Error + /* Further fields may be added in future. */ // For example, suggested or applied refactorings. } diff --git a/libgo/go/golang.org/x/tools/go/analysis/doc.go b/libgo/go/golang.org/x/tools/go/analysis/doc.go index a2353fc88b9..fb17a0e4154 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/doc.go +++ b/libgo/go/golang.org/x/tools/go/analysis/doc.go @@ -1,8 +1,9 @@ /* -The analysis package defines the interface between a modular static +Package analysis defines the interface between a modular static analysis and an analysis driver program. + Background A static analysis is a function that inspects a package of Go code and @@ -41,9 +42,9 @@ the go/analysis/passes/ subdirectory: package unusedresult var Analyzer = &analysis.Analyzer{ - Name: "unusedresult", - Doc: "check for unused results of calls to some functions", - Run: run, + Name: "unusedresult", + Doc: "check for unused results of calls to some functions", + Run: run, ... } @@ -51,7 +52,6 @@ the go/analysis/passes/ subdirectory: ... } - An analysis driver is a program such as vet that runs a set of analyses and prints the diagnostics that they report. The driver program must import the list of Analyzers it needs. @@ -70,51 +70,18 @@ A driver may use the name, flags, and documentation to provide on-line help that describes the analyses it performs. The doc comment contains a brief one-line summary, optionally followed by paragraphs of explanation. -The vet command, shown below, is an example of a driver that runs -multiple analyzers. It is based on the multichecker package -(see the "Standalone commands" section for details). - - $ go build golang.org/x/tools/go/analysis/cmd/vet - $ ./vet help - vet is a tool for static analysis of Go programs. - - Usage: vet [-flag] [package] - - Registered analyzers: - - asmdecl report mismatches between assembly files and Go declarations - assign check for useless assignments - atomic check for common mistakes using the sync/atomic package - ... - unusedresult check for unused results of calls to some functions - - $ ./vet help unusedresult - unusedresult: check for unused results of calls to some functions - - Analyzer flags: - - -unusedresult.funcs value - comma-separated list of functions whose results must be used (default Error,String) - -unusedresult.stringmethods value - comma-separated list of names of methods of type func() string whose results must be used - - Some functions like fmt.Errorf return a result and have no side effects, - so it is always a mistake to discard the result. This analyzer reports - calls to certain functions in which the result of the call is ignored. - - The set of functions may be controlled using flags. The Analyzer type has more fields besides those shown above: type Analyzer struct { - Name string - Doc string - Flags flag.FlagSet - Run func(*Pass) (interface{}, error) - RunDespiteErrors bool - ResultType reflect.Type - Requires []*Analyzer - FactTypes []Fact + Name string + Doc string + Flags flag.FlagSet + Run func(*Pass) (interface{}, error) + RunDespiteErrors bool + ResultType reflect.Type + Requires []*Analyzer + FactTypes []Fact } The Flags field declares a set of named (global) flag variables that @@ -154,13 +121,13 @@ package being analyzed, and provides operations to the Run function for reporting diagnostics and other information back to the driver. type Pass struct { - Fset *token.FileSet - Files []*ast.File - OtherFiles []string - Pkg *types.Package - TypesInfo *types.Info - ResultOf map[*Analyzer]interface{} - Report func(Diagnostic) + Fset *token.FileSet + Files []*ast.File + OtherFiles []string + Pkg *types.Package + TypesInfo *types.Info + ResultOf map[*Analyzer]interface{} + Report func(Diagnostic) ... } @@ -203,6 +170,15 @@ Diagnostic is defined as: The optional Category field is a short identifier that classifies the kind of message when an analysis produces several kinds of diagnostic. +Many analyses want to associate diagnostics with a severity level. +Because Diagnostic does not have a severity level field, an Analyzer's +diagnostics effectively all have the same severity level. To separate which +diagnostics are high severity and which are low severity, expose multiple +Analyzers instead. Analyzers should also be separated when their +diagnostics belong in different groups, or could be tagged differently +before being shown to the end user. Analyzers should document their severity +level to help downstream tools surface diagnostics properly. + Most Analyzers inspect typed Go syntax trees, but a few, such as asmdecl and buildtag, inspect the raw text of Go source files or even non-Go files such as assembly. To report a diagnostic against a line of a @@ -245,7 +221,7 @@ package. An Analyzer that uses facts must declare their types: var Analyzer = &analysis.Analyzer{ - Name: "printf", + Name: "printf", FactTypes: []analysis.Fact{new(isWrapper)}, ... } @@ -330,7 +306,5 @@ entirety as: A tool that provides multiple analyzers can use multichecker in a similar way, giving it the list of Analyzers. - - */ package analysis diff --git a/libgo/go/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go b/libgo/go/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go index 0778f422074..4b7be2d1f5f 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go +++ b/libgo/go/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go @@ -382,7 +382,7 @@ func (tree JSONTree) Add(fset *token.FileSet, id, name string, diags []analysis. func (tree JSONTree) Print() { data, err := json.MarshalIndent(tree, "", "\t") if err != nil { - log.Panicf("internal error: JSON marshalling failed: %v", err) + log.Panicf("internal error: JSON marshaling failed: %v", err) } fmt.Printf("%s\n", data) } diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/cgocall/cgocall.go b/libgo/go/golang.org/x/tools/go/analysis/passes/cgocall/cgocall.go index 7f7ca088b25..132bdf70fa2 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/cgocall/cgocall.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/cgocall/cgocall.go @@ -41,7 +41,7 @@ var Analyzer = &analysis.Analyzer{ } func run(pass *analysis.Pass) (interface{}, error) { - if runtime.Compiler != "gccgo" && imports(pass.Pkg, "runtime/cgo") == nil { + if runtime.Compiler != "gccgo" && !analysisutil.Imports(pass.Pkg, "runtime/cgo") { return nil, nil // doesn't use cgo } @@ -375,15 +375,3 @@ func imported(info *types.Info, spec *ast.ImportSpec) *types.Package { } return obj.(*types.PkgName).Imported() } - -// imports reports whether pkg has path among its direct imports. -// It returns the imported package if so, or nil if not. -// TODO(adonovan): move to analysisutil. -func imports(pkg *types.Package, path string) *types.Package { - for _, imp := range pkg.Imports() { - if imp.Path() == path { - return imp - } - } - return nil -} diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/errorsas/errorsas.go b/libgo/go/golang.org/x/tools/go/analysis/passes/errorsas/errorsas.go index b80271afb95..384f0255704 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/errorsas/errorsas.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/errorsas/errorsas.go @@ -51,7 +51,7 @@ func run(pass *analysis.Pass) (interface{}, error) { return // not enough arguments, e.g. called with return values of another function } if fn.FullName() == "errors.As" && !pointerToInterfaceOrError(pass, call.Args[1]) { - pass.ReportRangef(call, "second argument to errors.As must be a pointer to an interface or a type implementing error") + pass.ReportRangef(call, "second argument to errors.As must be a non-nil pointer to either a type that implements error, or to any interface type") } }) return nil, nil diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/httpresponse/httpresponse.go b/libgo/go/golang.org/x/tools/go/analysis/passes/httpresponse/httpresponse.go index ec335d35061..fd9e2af2b18 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/httpresponse/httpresponse.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/httpresponse/httpresponse.go @@ -12,6 +12,7 @@ import ( "golang.org/x/tools/go/analysis" "golang.org/x/tools/go/analysis/passes/inspect" + "golang.org/x/tools/go/analysis/passes/internal/analysisutil" "golang.org/x/tools/go/ast/inspector" ) @@ -43,7 +44,7 @@ func run(pass *analysis.Pass) (interface{}, error) { // Fast path: if the package doesn't import net/http, // skip the traversal. - if !imports(pass.Pkg, "net/http") { + if !analysisutil.Imports(pass.Pkg, "net/http") { return nil, nil } @@ -166,12 +167,3 @@ func isNamedType(t types.Type, path, name string) bool { obj := n.Obj() return obj.Name() == name && obj.Pkg() != nil && obj.Pkg().Path() == path } - -func imports(pkg *types.Package, path string) bool { - for _, imp := range pkg.Imports() { - if imp.Path() == path { - return true - } - } - return false -} diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/ifaceassert/ifaceassert.go b/libgo/go/golang.org/x/tools/go/analysis/passes/ifaceassert/ifaceassert.go new file mode 100644 index 00000000000..c5a71a7c570 --- /dev/null +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/ifaceassert/ifaceassert.go @@ -0,0 +1,101 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package ifaceassert defines an Analyzer that flags +// impossible interface-interface type assertions. +package ifaceassert + +import ( + "go/ast" + "go/types" + + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/passes/inspect" + "golang.org/x/tools/go/ast/inspector" +) + +const Doc = `detect impossible interface-to-interface type assertions + +This checker flags type assertions v.(T) and corresponding type-switch cases +in which the static type V of v is an interface that cannot possibly implement +the target interface T. This occurs when V and T contain methods with the same +name but different signatures. Example: + + var v interface { + Read() + } + _ = v.(io.Reader) + +The Read method in v has a different signature than the Read method in +io.Reader, so this assertion cannot succeed. +` + +var Analyzer = &analysis.Analyzer{ + Name: "ifaceassert", + Doc: Doc, + Requires: []*analysis.Analyzer{inspect.Analyzer}, + Run: run, +} + +// assertableTo checks whether interface v can be asserted into t. It returns +// nil on success, or the first conflicting method on failure. +func assertableTo(v, t types.Type) *types.Func { + // ensure that v and t are interfaces + V, _ := v.Underlying().(*types.Interface) + T, _ := t.Underlying().(*types.Interface) + if V == nil || T == nil { + return nil + } + if f, wrongType := types.MissingMethod(V, T, false); wrongType { + return f + } + return nil +} + +func run(pass *analysis.Pass) (interface{}, error) { + inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) + nodeFilter := []ast.Node{ + (*ast.TypeAssertExpr)(nil), + (*ast.TypeSwitchStmt)(nil), + } + inspect.Preorder(nodeFilter, func(n ast.Node) { + var ( + assert *ast.TypeAssertExpr // v.(T) expression + targets []ast.Expr // interfaces T in v.(T) + ) + switch n := n.(type) { + case *ast.TypeAssertExpr: + // take care of v.(type) in *ast.TypeSwitchStmt + if n.Type == nil { + return + } + assert = n + targets = append(targets, n.Type) + case *ast.TypeSwitchStmt: + // retrieve type assertion from type switch's 'assign' field + switch t := n.Assign.(type) { + case *ast.ExprStmt: + assert = t.X.(*ast.TypeAssertExpr) + case *ast.AssignStmt: + assert = t.Rhs[0].(*ast.TypeAssertExpr) + } + // gather target types from case clauses + for _, c := range n.Body.List { + targets = append(targets, c.(*ast.CaseClause).List...) + } + } + V := pass.TypesInfo.TypeOf(assert.X) + for _, target := range targets { + T := pass.TypesInfo.TypeOf(target) + if f := assertableTo(V, T); f != nil { + pass.Reportf( + target.Pos(), + "impossible type assertion: no type can implement both %v and %v (conflicting types for %v method)", + V, T, f.Name(), + ) + } + } + }) + return nil, nil +} diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/internal/analysisutil/util.go b/libgo/go/golang.org/x/tools/go/analysis/passes/internal/analysisutil/util.go index 13a458d9d6b..80c9476fcdd 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/internal/analysisutil/util.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/internal/analysisutil/util.go @@ -104,3 +104,13 @@ func LineStart(f *token.File, line int) token.Pos { } } } + +// Imports returns true if path is imported by pkg. +func Imports(pkg *types.Package, path string) bool { + for _, imp := range pkg.Imports() { + if imp.Path() == path { + return true + } + } + return false +} diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/printf/printf.go b/libgo/go/golang.org/x/tools/go/analysis/passes/printf/printf.go index e6177f2ea9b..ddad4c796cb 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/printf/printf.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/printf/printf.go @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// This file contains the printf-checker. - +// Package printf defines an Analyzer that checks consistency +// of Printf format strings and arguments. package printf import ( @@ -508,9 +508,13 @@ func printfNameAndKind(pass *analysis.Pass, call *ast.CallExpr) (fn *types.Func, return fn, KindNone } -// isFormatter reports whether t satisfies fmt.Formatter. +// isFormatter reports whether t could satisfy fmt.Formatter. // The only interface method to look for is "Format(State, rune)". func isFormatter(typ types.Type) bool { + // If the type is an interface, the value it holds might satisfy fmt.Formatter. + if _, ok := typ.Underlying().(*types.Interface); ok { + return true + } obj, _, _ := types.LookupFieldOrMethod(typ, false, nil, "Format") fn, ok := obj.(*types.Func) if !ok { @@ -828,7 +832,7 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, state *formatState) (o } } - // Does current arg implement fmt.Formatter? + // Could current arg implement fmt.Formatter? formatter := false if state.argNum < len(call.Args) { if tv, ok := pass.TypesInfo.Types[call.Args[state.argNum]]; ok { @@ -892,43 +896,51 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, state *formatState) (o pass.ReportRangef(call, "%s format %s has arg %s of wrong type %s", state.name, state.format, analysisutil.Format(pass.Fset, arg), typeString) return false } - if v.typ&argString != 0 && v.verb != 'T' && !bytes.Contains(state.flags, []byte{'#'}) && recursiveStringer(pass, arg) { - pass.ReportRangef(call, "%s format %s with arg %s causes recursive String method call", state.name, state.format, analysisutil.Format(pass.Fset, arg)) - return false + if v.typ&argString != 0 && v.verb != 'T' && !bytes.Contains(state.flags, []byte{'#'}) { + if methodName, ok := recursiveStringer(pass, arg); ok { + pass.ReportRangef(call, "%s format %s with arg %s causes recursive %s method call", state.name, state.format, analysisutil.Format(pass.Fset, arg), methodName) + return false + } } return true } // recursiveStringer reports whether the argument e is a potential -// recursive call to stringer, such as t and &t in these examples: +// recursive call to stringer or is an error, such as t and &t in these examples: // // func (t *T) String() string { printf("%s", t) } -// func (t T) String() string { printf("%s", t) } +// func (t T) Error() string { printf("%s", t) } // func (t T) String() string { printf("%s", &t) } -// -func recursiveStringer(pass *analysis.Pass, e ast.Expr) bool { +func recursiveStringer(pass *analysis.Pass, e ast.Expr) (string, bool) { typ := pass.TypesInfo.Types[e].Type // It's unlikely to be a recursive stringer if it has a Format method. if isFormatter(typ) { - return false + return "", false } - // Does e allow e.String()? - obj, _, _ := types.LookupFieldOrMethod(typ, false, pass.Pkg, "String") - stringMethod, ok := obj.(*types.Func) - if !ok { - return false + // Does e allow e.String() or e.Error()? + strObj, _, _ := types.LookupFieldOrMethod(typ, false, pass.Pkg, "String") + strMethod, strOk := strObj.(*types.Func) + errObj, _, _ := types.LookupFieldOrMethod(typ, false, pass.Pkg, "Error") + errMethod, errOk := errObj.(*types.Func) + if !strOk && !errOk { + return "", false } - // Is the expression e within the body of that String method? - if stringMethod.Pkg() != pass.Pkg || !stringMethod.Scope().Contains(e.Pos()) { - return false + // Is the expression e within the body of that String or Error method? + var method *types.Func + if strOk && strMethod.Pkg() == pass.Pkg && strMethod.Scope().Contains(e.Pos()) { + method = strMethod + } else if errOk && errMethod.Pkg() == pass.Pkg && errMethod.Scope().Contains(e.Pos()) { + method = errMethod + } else { + return "", false } - sig := stringMethod.Type().(*types.Signature) + sig := method.Type().(*types.Signature) if !isStringer(sig) { - return false + return "", false } // Is it the receiver r, or &r? @@ -936,9 +948,11 @@ func recursiveStringer(pass *analysis.Pass, e ast.Expr) bool { e = u.X // strip off & from &r } if id, ok := e.(*ast.Ident); ok { - return pass.TypesInfo.Uses[id] == sig.Recv() + if pass.TypesInfo.Uses[id] == sig.Recv() { + return method.Name(), true + } } - return false + return "", false } // isStringer reports whether the method signature matches the String() definition in fmt.Stringer. @@ -1062,8 +1076,8 @@ func checkPrint(pass *analysis.Pass, call *ast.CallExpr, fn *types.Func) { if isFunctionValue(pass, arg) { pass.ReportRangef(call, "%s arg %s is a func value, not called", fn.Name(), analysisutil.Format(pass.Fset, arg)) } - if recursiveStringer(pass, arg) { - pass.ReportRangef(call, "%s arg %s causes recursive call to String method", fn.Name(), analysisutil.Format(pass.Fset, arg)) + if methodName, ok := recursiveStringer(pass, arg); ok { + pass.ReportRangef(call, "%s arg %s causes recursive call to %s method", fn.Name(), analysisutil.Format(pass.Fset, arg), methodName) } } } diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/stringintconv/string.go b/libgo/go/golang.org/x/tools/go/analysis/passes/stringintconv/string.go new file mode 100644 index 00000000000..7a005901e84 --- /dev/null +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/stringintconv/string.go @@ -0,0 +1,126 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package stringintconv defines an Analyzer that flags type conversions +// from integers to strings. +package stringintconv + +import ( + "fmt" + "go/ast" + "go/types" + + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/passes/inspect" + "golang.org/x/tools/go/ast/inspector" +) + +const Doc = `check for string(int) conversions + +This checker flags conversions of the form string(x) where x is an integer +(but not byte or rune) type. Such conversions are discouraged because they +return the UTF-8 representation of the Unicode code point x, and not a decimal +string representation of x as one might expect. Furthermore, if x denotes an +invalid code point, the conversion cannot be statically rejected. + +For conversions that intend on using the code point, consider replacing them +with string(rune(x)). Otherwise, strconv.Itoa and its equivalents return the +string representation of the value in the desired base. +` + +var Analyzer = &analysis.Analyzer{ + Name: "stringintconv", + Doc: Doc, + Requires: []*analysis.Analyzer{inspect.Analyzer}, + Run: run, +} + +func typeName(typ types.Type) string { + if v, _ := typ.(interface{ Name() string }); v != nil { + return v.Name() + } + if v, _ := typ.(interface{ Obj() *types.TypeName }); v != nil { + return v.Obj().Name() + } + return "" +} + +func run(pass *analysis.Pass) (interface{}, error) { + inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) + nodeFilter := []ast.Node{ + (*ast.CallExpr)(nil), + } + inspect.Preorder(nodeFilter, func(n ast.Node) { + call := n.(*ast.CallExpr) + + // Retrieve target type name. + var tname *types.TypeName + switch fun := call.Fun.(type) { + case *ast.Ident: + tname, _ = pass.TypesInfo.Uses[fun].(*types.TypeName) + case *ast.SelectorExpr: + tname, _ = pass.TypesInfo.Uses[fun.Sel].(*types.TypeName) + } + if tname == nil { + return + } + target := tname.Name() + + // Check that target type T in T(v) has an underlying type of string. + T, _ := tname.Type().Underlying().(*types.Basic) + if T == nil || T.Kind() != types.String { + return + } + if s := T.Name(); target != s { + target += " (" + s + ")" + } + + // Check that type V of v has an underlying integral type that is not byte or rune. + if len(call.Args) != 1 { + return + } + v := call.Args[0] + vtyp := pass.TypesInfo.TypeOf(v) + V, _ := vtyp.Underlying().(*types.Basic) + if V == nil || V.Info()&types.IsInteger == 0 { + return + } + switch V.Kind() { + case types.Byte, types.Rune, types.UntypedRune: + return + } + + // Retrieve source type name. + source := typeName(vtyp) + if source == "" { + return + } + if s := V.Name(); source != s { + source += " (" + s + ")" + } + diag := analysis.Diagnostic{ + Pos: n.Pos(), + Message: fmt.Sprintf("conversion from %s to %s yields a string of one rune, not a string of digits (did you mean fmt.Sprint(x)?)", source, target), + SuggestedFixes: []analysis.SuggestedFix{ + { + Message: "Did you mean to convert a rune to a string?", + TextEdits: []analysis.TextEdit{ + { + Pos: v.Pos(), + End: v.Pos(), + NewText: []byte("rune("), + }, + { + Pos: v.End(), + End: v.End(), + NewText: []byte(")"), + }, + }, + }, + }, + } + pass.Report(diag) + }) + return nil, nil +} diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/unreachable/unreachable.go b/libgo/go/golang.org/x/tools/go/analysis/passes/unreachable/unreachable.go index 089c064838d..90896dd1bb9 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/unreachable/unreachable.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/unreachable/unreachable.go @@ -189,7 +189,18 @@ func (d *deadState) findDead(stmt ast.Stmt) { case *ast.EmptyStmt: // do not warn about unreachable empty statements default: - d.pass.ReportRangef(stmt, "unreachable code") + d.pass.Report(analysis.Diagnostic{ + Pos: stmt.Pos(), + End: stmt.End(), + Message: "unreachable code", + SuggestedFixes: []analysis.SuggestedFix{{ + Message: "Remove", + TextEdits: []analysis.TextEdit{{ + Pos: stmt.Pos(), + End: stmt.End(), + }}, + }}, + }) d.reachable = true // silence error about next statement } } diff --git a/libgo/go/golang.org/x/tools/go/ast/astutil/imports.go b/libgo/go/golang.org/x/tools/go/ast/astutil/imports.go index 3e4b195368b..2087ceec9cf 100644 --- a/libgo/go/golang.org/x/tools/go/ast/astutil/imports.go +++ b/libgo/go/golang.org/x/tools/go/ast/astutil/imports.go @@ -275,9 +275,10 @@ func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (del // We deleted an entry but now there may be // a blank line-sized hole where the import was. - if line-lastLine > 1 { + if line-lastLine > 1 || !gen.Rparen.IsValid() { // There was a blank line immediately preceding the deleted import, - // so there's no need to close the hole. + // so there's no need to close the hole. The right parenthesis is + // invalid after AddImport to an import statement without parenthesis. // Do nothing. } else if line != fset.File(gen.Rparen).LineCount() { // There was no blank line. Close the hole. diff --git a/libgo/go/golang.org/x/tools/go/ast/inspector/inspector.go b/libgo/go/golang.org/x/tools/go/ast/inspector/inspector.go index ddbdd3f08fc..af5e17feeea 100644 --- a/libgo/go/golang.org/x/tools/go/ast/inspector/inspector.go +++ b/libgo/go/golang.org/x/tools/go/ast/inspector/inspector.go @@ -90,7 +90,7 @@ func (in *Inspector) Preorder(types []ast.Node, f func(ast.Node)) { // The types argument, if non-empty, enables type-based filtering of // events. The function f if is called only for nodes whose type // matches an element of the types slice. -func (in *Inspector) Nodes(types []ast.Node, f func(n ast.Node, push bool) (prune bool)) { +func (in *Inspector) Nodes(types []ast.Node, f func(n ast.Node, push bool) (proceed bool)) { mask := maskOf(types) for i := 0; i < len(in.events); { ev := in.events[i] @@ -114,7 +114,7 @@ func (in *Inspector) Nodes(types []ast.Node, f func(n ast.Node, push bool) (prun // supplies each call to f an additional argument, the current // traversal stack. The stack's first element is the outermost node, // an *ast.File; its last is the innermost, n. -func (in *Inspector) WithStack(types []ast.Node, f func(n ast.Node, push bool, stack []ast.Node) (prune bool)) { +func (in *Inspector) WithStack(types []ast.Node, f func(n ast.Node, push bool, stack []ast.Node) (proceed bool)) { mask := maskOf(types) var stack []ast.Node for i := 0; i < len(in.events); { @@ -150,7 +150,11 @@ func traverse(files []*ast.File) []event { extent += int(f.End() - f.Pos()) } // This estimate is based on the net/http package. - events := make([]event, 0, extent*33/100) + capacity := extent * 33 / 100 + if capacity > 1e6 { + capacity = 1e6 // impose some reasonable maximum + } + events := make([]event, 0, capacity) var stack []event for _, f := range files { diff --git a/libgo/go/golang.org/x/tools/go/cfg/cfg.go b/libgo/go/golang.org/x/tools/go/cfg/cfg.go index b075034bb45..3ebc65f60e5 100644 --- a/libgo/go/golang.org/x/tools/go/cfg/cfg.go +++ b/libgo/go/golang.org/x/tools/go/cfg/cfg.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// This package constructs a simple control-flow graph (CFG) of the +// Package cfg constructs a simple control-flow graph (CFG) of the // statements and expressions within a single function. // // Use cfg.New to construct the CFG for a function body. diff --git a/libgo/go/golang.org/x/tools/go/types/objectpath/objectpath.go b/libgo/go/golang.org/x/tools/go/types/objectpath/objectpath.go index 882e3b3d8a9..cffd7acbee7 100644 --- a/libgo/go/golang.org/x/tools/go/types/objectpath/objectpath.go +++ b/libgo/go/golang.org/x/tools/go/types/objectpath/objectpath.go @@ -226,7 +226,8 @@ func For(obj types.Object) (Path, error) { // the best paths because non-types may // refer to types, but not the reverse. empty := make([]byte, 0, 48) // initial space - for _, name := range scope.Names() { + names := scope.Names() + for _, name := range names { o := scope.Lookup(name) tname, ok := o.(*types.TypeName) if !ok { @@ -253,7 +254,7 @@ func For(obj types.Object) (Path, error) { // Then inspect everything else: // non-types, and declared methods of defined types. - for _, name := range scope.Names() { + for _, name := range names { o := scope.Lookup(name) path := append(empty, name...) if _, ok := o.(*types.TypeName); !ok { diff --git a/libgo/go/golang.org/x/tools/internal/analysisinternal/analysis.go b/libgo/go/golang.org/x/tools/internal/analysisinternal/analysis.go new file mode 100644 index 00000000000..26586810c7f --- /dev/null +++ b/libgo/go/golang.org/x/tools/internal/analysisinternal/analysis.go @@ -0,0 +1,118 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package analysisinternal exposes internal-only fields from go/analysis. +package analysisinternal + +import ( + "bytes" + "fmt" + "go/ast" + "go/token" + "go/types" + "strings" + + "golang.org/x/tools/go/ast/astutil" +) + +func TypeErrorEndPos(fset *token.FileSet, src []byte, start token.Pos) token.Pos { + // Get the end position for the type error. + offset, end := fset.PositionFor(start, false).Offset, start + if offset >= len(src) { + return end + } + if width := bytes.IndexAny(src[offset:], " \n,():;[]+-*"); width > 0 { + end = start + token.Pos(width) + } + return end +} + +func ZeroValue(fset *token.FileSet, f *ast.File, pkg *types.Package, typ types.Type) ast.Expr { + under := typ + if n, ok := typ.(*types.Named); ok { + under = n.Underlying() + } + switch u := under.(type) { + case *types.Basic: + switch { + case u.Info()&types.IsNumeric != 0: + return &ast.BasicLit{Kind: token.INT, Value: "0"} + case u.Info()&types.IsBoolean != 0: + return &ast.Ident{Name: "false"} + case u.Info()&types.IsString != 0: + return &ast.BasicLit{Kind: token.STRING, Value: `""`} + default: + panic("unknown basic type") + } + case *types.Chan, *types.Interface, *types.Map, *types.Pointer, *types.Signature, *types.Slice: + return ast.NewIdent("nil") + case *types.Struct: + texpr := typeExpr(fset, f, pkg, typ) // typ because we want the name here. + if texpr == nil { + return nil + } + return &ast.CompositeLit{ + Type: texpr, + } + case *types.Array: + texpr := typeExpr(fset, f, pkg, u.Elem()) + if texpr == nil { + return nil + } + return &ast.CompositeLit{ + Type: &ast.ArrayType{ + Elt: texpr, + Len: &ast.BasicLit{Kind: token.INT, Value: fmt.Sprintf("%v", u.Len())}, + }, + } + } + return nil +} + +func typeExpr(fset *token.FileSet, f *ast.File, pkg *types.Package, typ types.Type) ast.Expr { + switch t := typ.(type) { + case *types.Basic: + switch t.Kind() { + case types.UnsafePointer: + return &ast.SelectorExpr{X: ast.NewIdent("unsafe"), Sel: ast.NewIdent("Pointer")} + default: + return ast.NewIdent(t.Name()) + } + case *types.Named: + if t.Obj().Pkg() == pkg { + return ast.NewIdent(t.Obj().Name()) + } + pkgName := t.Obj().Pkg().Name() + // If the file already imports the package under another name, use that. + for _, group := range astutil.Imports(fset, f) { + for _, cand := range group { + if strings.Trim(cand.Path.Value, `"`) == t.Obj().Pkg().Path() { + if cand.Name != nil && cand.Name.Name != "" { + pkgName = cand.Name.Name + } + } + } + } + if pkgName == "." { + return ast.NewIdent(t.Obj().Name()) + } + return &ast.SelectorExpr{ + X: ast.NewIdent(pkgName), + Sel: ast.NewIdent(t.Obj().Name()), + } + default: + return nil // TODO: anonymous structs, but who does that + } +} + +var GetTypeErrors = func(p interface{}) []types.Error { return nil } +var SetTypeErrors = func(p interface{}, errors []types.Error) {} + +type TypeErrorPass string + +const ( + NoNewVars TypeErrorPass = "nonewvars" + NoResultValues TypeErrorPass = "noresultvalues" + UndeclaredName TypeErrorPass = "undeclaredname" +) diff --git a/libgo/go/golang.org/x/xerrors/fmt.go b/libgo/go/golang.org/x/xerrors/fmt.go index 74c1c93ec9c..829862ddf6a 100644 --- a/libgo/go/golang.org/x/xerrors/fmt.go +++ b/libgo/go/golang.org/x/xerrors/fmt.go @@ -7,10 +7,14 @@ package xerrors import ( "fmt" "strings" + "unicode" + "unicode/utf8" "golang.org/x/xerrors/internal" ) +const percentBangString = "%!" + // Errorf formats according to a format specifier and returns the string as a // value that satisfies error. // @@ -18,29 +22,71 @@ import ( // formatted with additional detail enabled. If the last argument is an error // the returned error's Format method will return it if the format string ends // with ": %s", ": %v", or ": %w". If the last argument is an error and the -// format string ends with ": %w", the returned error implements Wrapper -// with an Unwrap method returning it. +// format string ends with ": %w", the returned error implements an Unwrap +// method returning it. +// +// If the format specifier includes a %w verb with an error operand in a +// position other than at the end, the returned error will still implement an +// Unwrap method returning the operand, but the error's Format method will not +// return the wrapped error. +// +// It is invalid to include more than one %w verb or to supply it with an +// operand that does not implement the error interface. The %w verb is otherwise +// a synonym for %v. func Errorf(format string, a ...interface{}) error { - err, wrap := lastError(format, a) format = formatPlusW(format) - if err == nil { - return &noWrapError{fmt.Sprintf(format, a...), nil, Caller(1)} + // Support a ": %[wsv]" suffix, which works well with xerrors.Formatter. + wrap := strings.HasSuffix(format, ": %w") + idx, format2, ok := parsePercentW(format) + percentWElsewhere := !wrap && idx >= 0 + if !percentWElsewhere && (wrap || strings.HasSuffix(format, ": %s") || strings.HasSuffix(format, ": %v")) { + err := errorAt(a, len(a)-1) + if err == nil { + return &noWrapError{fmt.Sprintf(format, a...), nil, Caller(1)} + } + // TODO: this is not entirely correct. The error value could be + // printed elsewhere in format if it mixes numbered with unnumbered + // substitutions. With relatively small changes to doPrintf we can + // have it optionally ignore extra arguments and pass the argument + // list in its entirety. + msg := fmt.Sprintf(format[:len(format)-len(": %s")], a[:len(a)-1]...) + frame := Frame{} + if internal.EnableTrace { + frame = Caller(1) + } + if wrap { + return &wrapError{msg, err, frame} + } + return &noWrapError{msg, err, frame} + } + // Support %w anywhere. + // TODO: don't repeat the wrapped error's message when %w occurs in the middle. + msg := fmt.Sprintf(format2, a...) + if idx < 0 { + return &noWrapError{msg, nil, Caller(1)} + } + err := errorAt(a, idx) + if !ok || err == nil { + // Too many %ws or argument of %w is not an error. Approximate the Go + // 1.13 fmt.Errorf message. + return &noWrapError{fmt.Sprintf("%sw(%s)", percentBangString, msg), nil, Caller(1)} } - - // TODO: this is not entirely correct. The error value could be - // printed elsewhere in format if it mixes numbered with unnumbered - // substitutions. With relatively small changes to doPrintf we can - // have it optionally ignore extra arguments and pass the argument - // list in its entirety. - msg := fmt.Sprintf(format[:len(format)-len(": %s")], a[:len(a)-1]...) frame := Frame{} if internal.EnableTrace { frame = Caller(1) } - if wrap { - return &wrapError{msg, err, frame} + return &wrapError{msg, err, frame} +} + +func errorAt(args []interface{}, i int) error { + if i < 0 || i >= len(args) { + return nil } - return &noWrapError{msg, err, frame} + err, ok := args[i].(error) + if !ok { + return nil + } + return err } // formatPlusW is used to avoid the vet check that will barf at %w. @@ -48,24 +94,56 @@ func formatPlusW(s string) string { return s } -func lastError(format string, a []interface{}) (err error, wrap bool) { - wrap = strings.HasSuffix(format, ": %w") - if !wrap && - !strings.HasSuffix(format, ": %s") && - !strings.HasSuffix(format, ": %v") { - return nil, false - } - - if len(a) == 0 { - return nil, false +// Return the index of the only %w in format, or -1 if none. +// Also return a rewritten format string with %w replaced by %v, and +// false if there is more than one %w. +// TODO: handle "%[N]w". +func parsePercentW(format string) (idx int, newFormat string, ok bool) { + // Loosely copied from golang.org/x/tools/go/analysis/passes/printf/printf.go. + idx = -1 + ok = true + n := 0 + sz := 0 + var isW bool + for i := 0; i < len(format); i += sz { + if format[i] != '%' { + sz = 1 + continue + } + // "%%" is not a format directive. + if i+1 < len(format) && format[i+1] == '%' { + sz = 2 + continue + } + sz, isW = parsePrintfVerb(format[i:]) + if isW { + if idx >= 0 { + ok = false + } else { + idx = n + } + // "Replace" the last character, the 'w', with a 'v'. + p := i + sz - 1 + format = format[:p] + "v" + format[p+1:] + } + n++ } + return idx, format, ok +} - err, ok := a[len(a)-1].(error) - if !ok { - return nil, false +// Parse the printf verb starting with a % at s[0]. +// Return how many bytes it occupies and whether the verb is 'w'. +func parsePrintfVerb(s string) (int, bool) { + // Assume only that the directive is a sequence of non-letters followed by a single letter. + sz := 0 + var r rune + for i := 1; i < len(s); i += sz { + r, sz = utf8.DecodeRuneInString(s[i:]) + if unicode.IsLetter(r) { + return i + sz, r == 'w' + } } - - return err, wrap + return len(s), false } type noWrapError struct { diff --git a/libgo/go/hash/crc32/crc32_s390x.go b/libgo/go/hash/crc32/crc32_s390x.go index 8815c70470b..c82ef80cf73 100644 --- a/libgo/go/hash/crc32/crc32_s390x.go +++ b/libgo/go/hash/crc32/crc32_s390x.go @@ -6,16 +6,16 @@ package crc32 +import "internal/cpu" + const ( vxMinLen = 64 vxAlignMask = 15 // align to 16 bytes ) -// hasVectorFacility reports whether the machine has the z/Architecture +// hasVX reports whether the machine has the z/Architecture // vector facility installed and enabled. -func hasVectorFacility() bool - -var hasVX = hasVectorFacility() +var hasVX = cpu.S390X.HasVX // vectorizedCastagnoli implements CRC32 using vector instructions. // It is defined in crc32_s390x.s. diff --git a/libgo/go/hash/maphash/example_test.go b/libgo/go/hash/maphash/example_test.go new file mode 100644 index 00000000000..78690fd65d9 --- /dev/null +++ b/libgo/go/hash/maphash/example_test.go @@ -0,0 +1,37 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package maphash_test + +import ( + "fmt" + "hash/maphash" +) + +func Example() { + // The zero Hash value is valid and ready to use; setting an + // initial seed is not necessary. + var h maphash.Hash + + // Add a string to the hash, and print the current hash value. + h.WriteString("hello, ") + fmt.Printf("%#x\n", h.Sum64()) + + // Append additional data (in the form of a byte array). + h.Write([]byte{'w', 'o', 'r', 'l', 'd'}) + fmt.Printf("%#x\n", h.Sum64()) + + // Reset discards all data previously added to the Hash, without + // changing its seed. + h.Reset() + + // Use SetSeed to create a new Hash h2 which will behave + // identically to h. + var h2 maphash.Hash + h2.SetSeed(h.Seed()) + + h.WriteString("same") + h2.WriteString("same") + fmt.Printf("%#x == %#x\n", h.Sum64(), h2.Sum64()) +} diff --git a/libgo/go/hash/maphash/maphash_test.go b/libgo/go/hash/maphash/maphash_test.go index 0164a9e20ae..caea43a8c83 100644 --- a/libgo/go/hash/maphash/maphash_test.go +++ b/libgo/go/hash/maphash/maphash_test.go @@ -106,6 +106,62 @@ func TestRepeat(t *testing.T) { } } +func TestSeedFromSum64(t *testing.T) { + h1 := new(Hash) + h1.WriteString("foo") + x := h1.Sum64() // seed generated here + h2 := new(Hash) + h2.SetSeed(h1.Seed()) + h2.WriteString("foo") + y := h2.Sum64() + if x != y { + t.Errorf("hashes don't match: want %x, got %x", x, y) + } +} + +func TestSeedFromSeed(t *testing.T) { + h1 := new(Hash) + h1.WriteString("foo") + _ = h1.Seed() // seed generated here + x := h1.Sum64() + h2 := new(Hash) + h2.SetSeed(h1.Seed()) + h2.WriteString("foo") + y := h2.Sum64() + if x != y { + t.Errorf("hashes don't match: want %x, got %x", x, y) + } +} + +func TestSeedFromFlush(t *testing.T) { + b := make([]byte, 65) + h1 := new(Hash) + h1.Write(b) // seed generated here + x := h1.Sum64() + h2 := new(Hash) + h2.SetSeed(h1.Seed()) + h2.Write(b) + y := h2.Sum64() + if x != y { + t.Errorf("hashes don't match: want %x, got %x", x, y) + } +} + +func TestSeedFromReset(t *testing.T) { + h1 := new(Hash) + h1.WriteString("foo") + h1.Reset() // seed generated here + h1.WriteString("foo") + x := h1.Sum64() + h2 := new(Hash) + h2.SetSeed(h1.Seed()) + h2.WriteString("foo") + y := h2.Sum64() + if x != y { + t.Errorf("hashes don't match: want %x, got %x", x, y) + } +} + // Make sure a Hash implements the hash.Hash and hash.Hash64 interfaces. var _ hash.Hash = &Hash{} var _ hash.Hash64 = &Hash{} diff --git a/libgo/go/html/template/clone_test.go b/libgo/go/html/template/clone_test.go index e292321d936..c9c619f0d45 100644 --- a/libgo/go/html/template/clone_test.go +++ b/libgo/go/html/template/clone_test.go @@ -15,7 +15,7 @@ import ( "text/template/parse" ) -func TestAddParseTree(t *testing.T) { +func TestAddParseTreeHTML(t *testing.T) { root := Must(New("root").Parse(`{{define "a"}} {{.}} {{template "b"}} {{.}} ">{{end}}`)) tree, err := parse.Parse("t", `{{define "b"}}World &tc!`), HTMLAttr(` dir="ltr"`), JS(`c && alert("Hello, World!");`), - JSStr(`Hello, World & O'Reilly\x21`), + JSStr(`Hello, World & O'Reilly\u0021`), URL(`greeting=H%69,&addressee=(World)`), Srcset(`greeting=H%69,&addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`), URL(`,foo/,`), @@ -70,7 +70,7 @@ func TestTypedContent(t *testing.T) { `Hello, World &tc!`, ` dir="ltr"`, `c && alert("Hello, World!");`, - `Hello, World & O'Reilly\x21`, + `Hello, World & O'Reilly\u0021`, `greeting=H%69,&addressee=(World)`, `greeting=H%69,&addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`, `,foo/,`, @@ -100,7 +100,7 @@ func TestTypedContent(t *testing.T) { `Hello, World &tc!`, ` dir="ltr"`, `c && alert("Hello, World!");`, - `Hello, World & O'Reilly\x21`, + `Hello, World & O'Reilly\u0021`, `greeting=H%69,&addressee=(World)`, `greeting=H%69,&addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`, `,foo/,`, @@ -115,7 +115,7 @@ func TestTypedContent(t *testing.T) { `Hello, World &tc!`, ` dir="ltr"`, `c && alert("Hello, World!");`, - `Hello, World & O'Reilly\x21`, + `Hello, World & O'Reilly\u0021`, `greeting=H%69,&addressee=(World)`, `greeting=H%69,&addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`, `,foo/,`, @@ -130,7 +130,7 @@ func TestTypedContent(t *testing.T) { `Hello, <b>World</b> &tc!`, ` dir="ltr"`, `c && alert("Hello, World!");`, - `Hello, World & O'Reilly\x21`, + `Hello, World & O'Reilly\u0021`, `greeting=H%69,&addressee=(World)`, `greeting=H%69,&addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`, `,foo/,`, @@ -146,7 +146,7 @@ func TestTypedContent(t *testing.T) { // Not escaped. `c && alert("Hello, World!");`, // Escape sequence not over-escaped. - `"Hello, World & O'Reilly\x21"`, + `"Hello, World & O'Reilly\u0021"`, `"greeting=H%69,\u0026addressee=(World)"`, `"greeting=H%69,\u0026addressee=(World) 2x, https://golang.org/favicon.ico 500.5w"`, `",foo/,"`, @@ -162,7 +162,7 @@ func TestTypedContent(t *testing.T) { // Not JS escaped but HTML escaped. `c && alert("Hello, World!");`, // Escape sequence not over-escaped. - `"Hello, World & O'Reilly\x21"`, + `"Hello, World & O'Reilly\u0021"`, `"greeting=H%69,\u0026addressee=(World)"`, `"greeting=H%69,\u0026addressee=(World) 2x, https://golang.org/favicon.ico 500.5w"`, `",foo/,"`, @@ -171,30 +171,30 @@ func TestTypedContent(t *testing.T) { { ``, []string{ - `\x3cb\x3e \x22foo%\x22 O\x27Reilly \x26bar;`, - `a[href =~ \x22\/\/example.com\x22]#foo`, - `Hello, \x3cb\x3eWorld\x3c\/b\x3e \x26amp;tc!`, - ` dir=\x22ltr\x22`, - `c \x26\x26 alert(\x22Hello, World!\x22);`, + `\u003cb\u003e \u0022foo%\u0022 O\u0027Reilly \u0026bar;`, + `a[href =~ \u0022\/\/example.com\u0022]#foo`, + `Hello, \u003cb\u003eWorld\u003c\/b\u003e \u0026amp;tc!`, + ` dir=\u0022ltr\u0022`, + `c \u0026\u0026 alert(\u0022Hello, World!\u0022);`, // Escape sequence not over-escaped. - `Hello, World \x26 O\x27Reilly\x21`, - `greeting=H%69,\x26addressee=(World)`, - `greeting=H%69,\x26addressee=(World) 2x, https:\/\/golang.org\/favicon.ico 500.5w`, + `Hello, World \u0026 O\u0027Reilly\u0021`, + `greeting=H%69,\u0026addressee=(World)`, + `greeting=H%69,\u0026addressee=(World) 2x, https:\/\/golang.org\/favicon.ico 500.5w`, `,foo\/,`, }, }, { ``, []string{ - `\x3cb\x3e \x22foo%\x22 O\x27Reilly \x26bar;`, - `a[href =~ \x22\/\/example.com\x22]#foo`, - `Hello, \x3cb\x3eWorld\x3c\/b\x3e \x26amp;tc!`, - ` dir=\x22ltr\x22`, - `c \x26\x26 alert(\x22Hello, World!\x22);`, + `\u003cb\u003e \u0022foo%\u0022 O\u0027Reilly \u0026bar;`, + `a[href =~ \u0022\/\/example.com\u0022]#foo`, + `Hello, \u003cb\u003eWorld\u003c\/b\u003e \u0026amp;tc!`, + ` dir=\u0022ltr\u0022`, + `c \u0026\u0026 alert(\u0022Hello, World!\u0022);`, // Escape sequence not over-escaped. - `Hello, World \x26 O\x27Reilly\x21`, - `greeting=H%69,\x26addressee=(World)`, - `greeting=H%69,\x26addressee=(World) 2x, https:\/\/golang.org\/favicon.ico 500.5w`, + `Hello, World \u0026 O\u0027Reilly\u0021`, + `greeting=H%69,\u0026addressee=(World)`, + `greeting=H%69,\u0026addressee=(World) 2x, https:\/\/golang.org\/favicon.ico 500.5w`, `,foo\/,`, }, }, @@ -208,7 +208,7 @@ func TestTypedContent(t *testing.T) { // Not escaped. `c && alert("Hello, World!");`, // Escape sequence not over-escaped. - `"Hello, World & O'Reilly\x21"`, + `"Hello, World & O'Reilly\u0021"`, `"greeting=H%69,\u0026addressee=(World)"`, `"greeting=H%69,\u0026addressee=(World) 2x, https://golang.org/favicon.ico 500.5w"`, `",foo/,"`, @@ -224,7 +224,7 @@ func TestTypedContent(t *testing.T) { `Hello, World &tc!`, ` dir="ltr"`, `c && alert("Hello, World!");`, - `Hello, World & O'Reilly\x21`, + `Hello, World & O'Reilly\u0021`, `greeting=H%69,&addressee=(World)`, `greeting=H%69,&addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`, `,foo/,`, @@ -233,15 +233,15 @@ func TestTypedContent(t *testing.T) { { ``, "helper": `{{11}} of {{"<100>"}}`, }, - ``, + ``, }, // A non-recursive template that ends in a different context. // helper starts in jsCtxRegexp and ends in jsCtxDivOp. @@ -1821,7 +1821,7 @@ func TestIndirectPrint(t *testing.T) { } // This is a test for issue 3272. -func TestEmptyTemplate(t *testing.T) { +func TestEmptyTemplateHTML(t *testing.T) { page := Must(New("page").ParseFiles(os.DevNull)) if err := page.ExecuteTemplate(os.Stdout, "page", "nothing"); err == nil { t.Fatal("expected error") diff --git a/libgo/go/html/template/example_test.go b/libgo/go/html/template/example_test.go index 9d965f1943c..6cf936f2709 100644 --- a/libgo/go/html/template/example_test.go +++ b/libgo/go/html/template/example_test.go @@ -116,9 +116,9 @@ func Example_escape() { // "Fran & Freddie's Diner" <tasty@example.com> // "Fran & Freddie's Diner" <tasty@example.com> // "Fran & Freddie's Diner"32<tasty@example.com> - // \"Fran \x26 Freddie\'s Diner\" \x3Ctasty@example.com\x3E - // \"Fran \x26 Freddie\'s Diner\" \x3Ctasty@example.com\x3E - // \"Fran \x26 Freddie\'s Diner\"32\x3Ctasty@example.com\x3E + // \"Fran \u0026 Freddie\'s Diner\" \u003Ctasty@example.com\u003E + // \"Fran \u0026 Freddie\'s Diner\" \u003Ctasty@example.com\u003E + // \"Fran \u0026 Freddie\'s Diner\"32\u003Ctasty@example.com\u003E // %22Fran+%26+Freddie%27s+Diner%2232%3Ctasty%40example.com%3E } diff --git a/libgo/go/html/template/exec_test.go b/libgo/go/html/template/exec_test.go new file mode 100644 index 00000000000..ec2bfcccab5 --- /dev/null +++ b/libgo/go/html/template/exec_test.go @@ -0,0 +1,1708 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Tests for template execution, copied from text/template. + +package template + +import ( + "bytes" + "errors" + "flag" + "fmt" + "io/ioutil" + "reflect" + "strings" + "testing" + "text/template" +) + +var debug = flag.Bool("debug", false, "show the errors produced by the tests") + +// T has lots of interesting pieces to use to test execution. +type T struct { + // Basics + True bool + I int + U16 uint16 + X, S string + FloatZero float64 + ComplexZero complex128 + // Nested structs. + U *U + // Struct with String method. + V0 V + V1, V2 *V + // Struct with Error method. + W0 W + W1, W2 *W + // Slices + SI []int + SICap []int + SIEmpty []int + SB []bool + // Arrays + AI [3]int + // Maps + MSI map[string]int + MSIone map[string]int // one element, for deterministic output + MSIEmpty map[string]int + MXI map[interface{}]int + MII map[int]int + MI32S map[int32]string + MI64S map[int64]string + MUI32S map[uint32]string + MUI64S map[uint64]string + MI8S map[int8]string + MUI8S map[uint8]string + SMSI []map[string]int + // Empty interfaces; used to see if we can dig inside one. + Empty0 interface{} // nil + Empty1 interface{} + Empty2 interface{} + Empty3 interface{} + Empty4 interface{} + // Non-empty interfaces. + NonEmptyInterface I + NonEmptyInterfacePtS *I + NonEmptyInterfaceNil I + NonEmptyInterfaceTypedNil I + // Stringer. + Str fmt.Stringer + Err error + // Pointers + PI *int + PS *string + PSI *[]int + NIL *int + // Function (not method) + BinaryFunc func(string, string) string + VariadicFunc func(...string) string + VariadicFuncInt func(int, ...string) string + NilOKFunc func(*int) bool + ErrFunc func() (string, error) + PanicFunc func() string + // Template to test evaluation of templates. + Tmpl *Template + // Unexported field; cannot be accessed by template. + unexported int +} + +type S []string + +func (S) Method0() string { + return "M0" +} + +type U struct { + V string +} + +type V struct { + j int +} + +func (v *V) String() string { + if v == nil { + return "nilV" + } + return fmt.Sprintf("<%d>", v.j) +} + +type W struct { + k int +} + +func (w *W) Error() string { + if w == nil { + return "nilW" + } + return fmt.Sprintf("[%d]", w.k) +} + +var siVal = I(S{"a", "b"}) + +var tVal = &T{ + True: true, + I: 17, + U16: 16, + X: "x", + S: "xyz", + U: &U{"v"}, + V0: V{6666}, + V1: &V{7777}, // leave V2 as nil + W0: W{888}, + W1: &W{999}, // leave W2 as nil + SI: []int{3, 4, 5}, + SICap: make([]int, 5, 10), + AI: [3]int{3, 4, 5}, + SB: []bool{true, false}, + MSI: map[string]int{"one": 1, "two": 2, "three": 3}, + MSIone: map[string]int{"one": 1}, + MXI: map[interface{}]int{"one": 1}, + MII: map[int]int{1: 1}, + MI32S: map[int32]string{1: "one", 2: "two"}, + MI64S: map[int64]string{2: "i642", 3: "i643"}, + MUI32S: map[uint32]string{2: "u322", 3: "u323"}, + MUI64S: map[uint64]string{2: "ui642", 3: "ui643"}, + MI8S: map[int8]string{2: "i82", 3: "i83"}, + MUI8S: map[uint8]string{2: "u82", 3: "u83"}, + SMSI: []map[string]int{ + {"one": 1, "two": 2}, + {"eleven": 11, "twelve": 12}, + }, + Empty1: 3, + Empty2: "empty2", + Empty3: []int{7, 8}, + Empty4: &U{"UinEmpty"}, + NonEmptyInterface: &T{X: "x"}, + NonEmptyInterfacePtS: &siVal, + NonEmptyInterfaceTypedNil: (*T)(nil), + Str: bytes.NewBuffer([]byte("foozle")), + Err: errors.New("erroozle"), + PI: newInt(23), + PS: newString("a string"), + PSI: newIntSlice(21, 22, 23), + BinaryFunc: func(a, b string) string { return fmt.Sprintf("[%s=%s]", a, b) }, + VariadicFunc: func(s ...string) string { return fmt.Sprint("<", strings.Join(s, "+"), ">") }, + VariadicFuncInt: func(a int, s ...string) string { return fmt.Sprint(a, "=<", strings.Join(s, "+"), ">") }, + NilOKFunc: func(s *int) bool { return s == nil }, + ErrFunc: func() (string, error) { return "bla", nil }, + PanicFunc: func() string { panic("test panic") }, + Tmpl: Must(New("x").Parse("test template")), // "x" is the value of .X +} + +var tSliceOfNil = []*T{nil} + +// A non-empty interface. +type I interface { + Method0() string +} + +var iVal I = tVal + +// Helpers for creation. +func newInt(n int) *int { + return &n +} + +func newString(s string) *string { + return &s +} + +func newIntSlice(n ...int) *[]int { + p := new([]int) + *p = make([]int, len(n)) + copy(*p, n) + return p +} + +// Simple methods with and without arguments. +func (t *T) Method0() string { + return "M0" +} + +func (t *T) Method1(a int) int { + return a +} + +func (t *T) Method2(a uint16, b string) string { + return fmt.Sprintf("Method2: %d %s", a, b) +} + +func (t *T) Method3(v interface{}) string { + return fmt.Sprintf("Method3: %v", v) +} + +func (t *T) Copy() *T { + n := new(T) + *n = *t + return n +} + +func (t *T) MAdd(a int, b []int) []int { + v := make([]int, len(b)) + for i, x := range b { + v[i] = x + a + } + return v +} + +var myError = errors.New("my error") + +// MyError returns a value and an error according to its argument. +func (t *T) MyError(error bool) (bool, error) { + if error { + return true, myError + } + return false, nil +} + +// A few methods to test chaining. +func (t *T) GetU() *U { + return t.U +} + +func (u *U) TrueFalse(b bool) string { + if b { + return "true" + } + return "" +} + +func typeOf(arg interface{}) string { + return fmt.Sprintf("%T", arg) +} + +type execTest struct { + name string + input string + output string + data interface{} + ok bool +} + +// bigInt and bigUint are hex string representing numbers either side +// of the max int boundary. +// We do it this way so the test doesn't depend on ints being 32 bits. +var ( + bigInt = fmt.Sprintf("0x%x", int(1< in text/template + {"map .one interface", "{{.MXI.one}}", "1", tVal, true}, + {"map .WRONG args", "{{.MSI.one 1}}", "", tVal, false}, + {"map .WRONG type", "{{.MII.one}}", "", tVal, false}, + + // Dots of all kinds to test basic evaluation. + {"dot int", "<{{.}}>", "<13>", 13, true}, + {"dot uint", "<{{.}}>", "<14>", uint(14), true}, + {"dot float", "<{{.}}>", "<15.1>", 15.1, true}, + {"dot bool", "<{{.}}>", "<true>", true, true}, + {"dot complex", "<{{.}}>", "<(16.2-17i)>", 16.2 - 17i, true}, + {"dot string", "<{{.}}>", "<hello>", "hello", true}, + {"dot slice", "<{{.}}>", "<[-1 -2 -3]>", []int{-1, -2, -3}, true}, + {"dot map", "<{{.}}>", "<map[two:22]>", map[string]int{"two": 22}, true}, + {"dot struct", "<{{.}}>", "<{7 seven}>", struct { + a int + b string + }{7, "seven"}, true}, + + // Variables. + {"$ int", "{{$}}", "123", 123, true}, + {"$.I", "{{$.I}}", "17", tVal, true}, + {"$.U.V", "{{$.U.V}}", "v", tVal, true}, + {"declare in action", "{{$x := $.U.V}}{{$x}}", "v", tVal, true}, + {"simple assignment", "{{$x := 2}}{{$x = 3}}{{$x}}", "3", tVal, true}, + {"nested assignment", + "{{$x := 2}}{{if true}}{{$x = 3}}{{end}}{{$x}}", + "3", tVal, true}, + {"nested assignment changes the last declaration", + "{{$x := 1}}{{if true}}{{$x := 2}}{{if true}}{{$x = 3}}{{end}}{{end}}{{$x}}", + "1", tVal, true}, + + // Type with String method. + {"V{6666}.String()", "-{{.V0}}-", "-{6666}-", tVal, true}, // NOTE: -<6666>- in text/template + {"&V{7777}.String()", "-{{.V1}}-", "-<7777>-", tVal, true}, + {"(*V)(nil).String()", "-{{.V2}}-", "-nilV-", tVal, true}, + + // Type with Error method. + {"W{888}.Error()", "-{{.W0}}-", "-{888}-", tVal, true}, // NOTE: -[888] in text/template + {"&W{999}.Error()", "-{{.W1}}-", "-[999]-", tVal, true}, + {"(*W)(nil).Error()", "-{{.W2}}-", "-nilW-", tVal, true}, + + // Pointers. + {"*int", "{{.PI}}", "23", tVal, true}, + {"*string", "{{.PS}}", "a string", tVal, true}, + {"*[]int", "{{.PSI}}", "[21 22 23]", tVal, true}, + {"*[]int[1]", "{{index .PSI 1}}", "22", tVal, true}, + {"NIL", "{{.NIL}}", "<nil>", tVal, true}, + + // Empty interfaces holding values. + {"empty nil", "{{.Empty0}}", "", tVal, true}, // NOTE: in text/template + {"empty with int", "{{.Empty1}}", "3", tVal, true}, + {"empty with string", "{{.Empty2}}", "empty2", tVal, true}, + {"empty with slice", "{{.Empty3}}", "[7 8]", tVal, true}, + {"empty with struct", "{{.Empty4}}", "{UinEmpty}", tVal, true}, + {"empty with struct, field", "{{.Empty4.V}}", "UinEmpty", tVal, true}, + + // Edge cases with with an interface value + {"field on interface", "{{.foo}}", "", nil, true}, // NOTE: in text/template + {"field on parenthesized interface", "{{(.).foo}}", "", nil, true}, // NOTE: in text/template + + // Issue 31810: Parenthesized first element of pipeline with arguments. + // See also TestIssue31810. + {"unparenthesized non-function", "{{1 2}}", "", nil, false}, + {"parenthesized non-function", "{{(1) 2}}", "", nil, false}, + {"parenthesized non-function with no args", "{{(1)}}", "1", nil, true}, // This is fine. + + // Method calls. + {".Method0", "-{{.Method0}}-", "-M0-", tVal, true}, + {".Method1(1234)", "-{{.Method1 1234}}-", "-1234-", tVal, true}, + {".Method1(.I)", "-{{.Method1 .I}}-", "-17-", tVal, true}, + {".Method2(3, .X)", "-{{.Method2 3 .X}}-", "-Method2: 3 x-", tVal, true}, + {".Method2(.U16, `str`)", "-{{.Method2 .U16 `str`}}-", "-Method2: 16 str-", tVal, true}, + {".Method2(.U16, $x)", "{{if $x := .X}}-{{.Method2 .U16 $x}}{{end}}-", "-Method2: 16 x-", tVal, true}, + {".Method3(nil constant)", "-{{.Method3 nil}}-", "-Method3: <nil>-", tVal, true}, + {".Method3(nil value)", "-{{.Method3 .MXI.unset}}-", "-Method3: <nil>-", tVal, true}, + {"method on var", "{{if $x := .}}-{{$x.Method2 .U16 $x.X}}{{end}}-", "-Method2: 16 x-", tVal, true}, + {"method on chained var", + "{{range .MSIone}}{{if $.U.TrueFalse $.True}}{{$.U.TrueFalse $.True}}{{else}}WRONG{{end}}{{end}}", + "true", tVal, true}, + {"chained method", + "{{range .MSIone}}{{if $.GetU.TrueFalse $.True}}{{$.U.TrueFalse $.True}}{{else}}WRONG{{end}}{{end}}", + "true", tVal, true}, + {"chained method on variable", + "{{with $x := .}}{{with .SI}}{{$.GetU.TrueFalse $.True}}{{end}}{{end}}", + "true", tVal, true}, + {".NilOKFunc not nil", "{{call .NilOKFunc .PI}}", "false", tVal, true}, + {".NilOKFunc nil", "{{call .NilOKFunc nil}}", "true", tVal, true}, + {"method on nil value from slice", "-{{range .}}{{.Method1 1234}}{{end}}-", "-1234-", tSliceOfNil, true}, + {"method on typed nil interface value", "{{.NonEmptyInterfaceTypedNil.Method0}}", "M0", tVal, true}, + + // Function call builtin. + {".BinaryFunc", "{{call .BinaryFunc `1` `2`}}", "[1=2]", tVal, true}, + {".VariadicFunc0", "{{call .VariadicFunc}}", "<>", tVal, true}, + {".VariadicFunc2", "{{call .VariadicFunc `he` `llo`}}", "<he+llo>", tVal, true}, + {".VariadicFuncInt", "{{call .VariadicFuncInt 33 `he` `llo`}}", "33=<he+llo>", tVal, true}, + {"if .BinaryFunc call", "{{ if .BinaryFunc}}{{call .BinaryFunc `1` `2`}}{{end}}", "[1=2]", tVal, true}, + {"if not .BinaryFunc call", "{{ if not .BinaryFunc}}{{call .BinaryFunc `1` `2`}}{{else}}No{{end}}", "No", tVal, true}, + {"Interface Call", `{{stringer .S}}`, "foozle", map[string]interface{}{"S": bytes.NewBufferString("foozle")}, true}, + {".ErrFunc", "{{call .ErrFunc}}", "bla", tVal, true}, + {"call nil", "{{call nil}}", "", tVal, false}, + + // Erroneous function calls (check args). + {".BinaryFuncTooFew", "{{call .BinaryFunc `1`}}", "", tVal, false}, + {".BinaryFuncTooMany", "{{call .BinaryFunc `1` `2` `3`}}", "", tVal, false}, + {".BinaryFuncBad0", "{{call .BinaryFunc 1 3}}", "", tVal, false}, + {".BinaryFuncBad1", "{{call .BinaryFunc `1` 3}}", "", tVal, false}, + {".VariadicFuncBad0", "{{call .VariadicFunc 3}}", "", tVal, false}, + {".VariadicFuncIntBad0", "{{call .VariadicFuncInt}}", "", tVal, false}, + {".VariadicFuncIntBad`", "{{call .VariadicFuncInt `x`}}", "", tVal, false}, + {".VariadicFuncNilBad", "{{call .VariadicFunc nil}}", "", tVal, false}, + + // Pipelines. + {"pipeline", "-{{.Method0 | .Method2 .U16}}-", "-Method2: 16 M0-", tVal, true}, + {"pipeline func", "-{{call .VariadicFunc `llo` | call .VariadicFunc `he` }}-", "-<he+<llo>>-", tVal, true}, + + // Nil values aren't missing arguments. + {"nil pipeline", "{{ .Empty0 | call .NilOKFunc }}", "true", tVal, true}, + {"nil call arg", "{{ call .NilOKFunc .Empty0 }}", "true", tVal, true}, + {"bad nil pipeline", "{{ .Empty0 | .VariadicFunc }}", "", tVal, false}, + + // Parenthesized expressions + {"parens in pipeline", "{{printf `%d %d %d` (1) (2 | add 3) (add 4 (add 5 6))}}", "1 5 15", tVal, true}, + + // Parenthesized expressions with field accesses + {"parens: $ in paren", "{{($).X}}", "x", tVal, true}, + {"parens: $.GetU in paren", "{{($.GetU).V}}", "v", tVal, true}, + {"parens: $ in paren in pipe", "{{($ | echo).X}}", "x", tVal, true}, + {"parens: spaces and args", `{{(makemap "up" "down" "left" "right").left}}`, "right", tVal, true}, + + // If. + {"if true", "{{if true}}TRUE{{end}}", "TRUE", tVal, true}, + {"if false", "{{if false}}TRUE{{else}}FALSE{{end}}", "FALSE", tVal, true}, + {"if nil", "{{if nil}}TRUE{{end}}", "", tVal, false}, + {"if on typed nil interface value", "{{if .NonEmptyInterfaceTypedNil}}TRUE{{ end }}", "", tVal, true}, + {"if 1", "{{if 1}}NON-ZERO{{else}}ZERO{{end}}", "NON-ZERO", tVal, true}, + {"if 0", "{{if 0}}NON-ZERO{{else}}ZERO{{end}}", "ZERO", tVal, true}, + {"if 1.5", "{{if 1.5}}NON-ZERO{{else}}ZERO{{end}}", "NON-ZERO", tVal, true}, + {"if 0.0", "{{if .FloatZero}}NON-ZERO{{else}}ZERO{{end}}", "ZERO", tVal, true}, + {"if 1.5i", "{{if 1.5i}}NON-ZERO{{else}}ZERO{{end}}", "NON-ZERO", tVal, true}, + {"if 0.0i", "{{if .ComplexZero}}NON-ZERO{{else}}ZERO{{end}}", "ZERO", tVal, true}, + {"if emptystring", "{{if ``}}NON-EMPTY{{else}}EMPTY{{end}}", "EMPTY", tVal, true}, + {"if string", "{{if `notempty`}}NON-EMPTY{{else}}EMPTY{{end}}", "NON-EMPTY", tVal, true}, + {"if emptyslice", "{{if .SIEmpty}}NON-EMPTY{{else}}EMPTY{{end}}", "EMPTY", tVal, true}, + {"if slice", "{{if .SI}}NON-EMPTY{{else}}EMPTY{{end}}", "NON-EMPTY", tVal, true}, + {"if emptymap", "{{if .MSIEmpty}}NON-EMPTY{{else}}EMPTY{{end}}", "EMPTY", tVal, true}, + {"if map", "{{if .MSI}}NON-EMPTY{{else}}EMPTY{{end}}", "NON-EMPTY", tVal, true}, + {"if map unset", "{{if .MXI.none}}NON-ZERO{{else}}ZERO{{end}}", "ZERO", tVal, true}, + {"if map not unset", "{{if not .MXI.none}}ZERO{{else}}NON-ZERO{{end}}", "ZERO", tVal, true}, + {"if $x with $y int", "{{if $x := true}}{{with $y := .I}}{{$x}},{{$y}}{{end}}{{end}}", "true,17", tVal, true}, + {"if $x with $x int", "{{if $x := true}}{{with $x := .I}}{{$x}},{{end}}{{$x}}{{end}}", "17,true", tVal, true}, + {"if else if", "{{if false}}FALSE{{else if true}}TRUE{{end}}", "TRUE", tVal, true}, + {"if else chain", "{{if eq 1 3}}1{{else if eq 2 3}}2{{else if eq 3 3}}3{{end}}", "3", tVal, true}, + + // Print etc. + {"print", `{{print "hello, print"}}`, "hello, print", tVal, true}, + {"print 123", `{{print 1 2 3}}`, "1 2 3", tVal, true}, + {"print nil", `{{print nil}}`, "<nil>", tVal, true}, + {"println", `{{println 1 2 3}}`, "1 2 3\n", tVal, true}, + {"printf int", `{{printf "%04x" 127}}`, "007f", tVal, true}, + {"printf float", `{{printf "%g" 3.5}}`, "3.5", tVal, true}, + {"printf complex", `{{printf "%g" 1+7i}}`, "(1+7i)", tVal, true}, + {"printf string", `{{printf "%s" "hello"}}`, "hello", tVal, true}, + {"printf function", `{{printf "%#q" zeroArgs}}`, "`zeroArgs`", tVal, true}, + {"printf field", `{{printf "%s" .U.V}}`, "v", tVal, true}, + {"printf method", `{{printf "%s" .Method0}}`, "M0", tVal, true}, + {"printf dot", `{{with .I}}{{printf "%d" .}}{{end}}`, "17", tVal, true}, + {"printf var", `{{with $x := .I}}{{printf "%d" $x}}{{end}}`, "17", tVal, true}, + {"printf lots", `{{printf "%d %s %g %s" 127 "hello" 7-3i .Method0}}`, "127 hello (7-3i) M0", tVal, true}, + + // HTML. + {"html", `{{html ""}}`, + "<script>alert("XSS");</script>", nil, true}, + {"html pipeline", `{{printf "" | html}}`, + "<script>alert("XSS");</script>", nil, true}, + {"html", `{{html .PS}}`, "a string", tVal, true}, + {"html typed nil", `{{html .NIL}}`, "<nil>", tVal, true}, + {"html untyped nil", `{{html .Empty0}}`, "<nil>", tVal, true}, // NOTE: "<no value>" in text/template + + // JavaScript. + {"js", `{{js .}}`, `It\'d be nice.`, `It'd be nice.`, true}, + + // URL query. + {"urlquery", `{{"http://www.example.org/"|urlquery}}`, "http%3A%2F%2Fwww.example.org%2F", nil, true}, + + // Booleans + {"not", "{{not true}} {{not false}}", "false true", nil, true}, + {"and", "{{and false 0}} {{and 1 0}} {{and 0 true}} {{and 1 1}}", "false 0 0 1", nil, true}, + {"or", "{{or 0 0}} {{or 1 0}} {{or 0 true}} {{or 1 1}}", "0 1 true 1", nil, true}, + {"boolean if", "{{if and true 1 `hi`}}TRUE{{else}}FALSE{{end}}", "TRUE", tVal, true}, + {"boolean if not", "{{if and true 1 `hi` | not}}TRUE{{else}}FALSE{{end}}", "FALSE", nil, true}, + + // Indexing. + {"slice[0]", "{{index .SI 0}}", "3", tVal, true}, + {"slice[1]", "{{index .SI 1}}", "4", tVal, true}, + {"slice[HUGE]", "{{index .SI 10}}", "", tVal, false}, + {"slice[WRONG]", "{{index .SI `hello`}}", "", tVal, false}, + {"slice[nil]", "{{index .SI nil}}", "", tVal, false}, + {"map[one]", "{{index .MSI `one`}}", "1", tVal, true}, + {"map[two]", "{{index .MSI `two`}}", "2", tVal, true}, + {"map[NO]", "{{index .MSI `XXX`}}", "0", tVal, true}, + {"map[nil]", "{{index .MSI nil}}", "", tVal, false}, + {"map[``]", "{{index .MSI ``}}", "0", tVal, true}, + {"map[WRONG]", "{{index .MSI 10}}", "", tVal, false}, + {"double index", "{{index .SMSI 1 `eleven`}}", "11", tVal, true}, + {"nil[1]", "{{index nil 1}}", "", tVal, false}, + {"map MI64S", "{{index .MI64S 2}}", "i642", tVal, true}, + {"map MI32S", "{{index .MI32S 2}}", "two", tVal, true}, + {"map MUI64S", "{{index .MUI64S 3}}", "ui643", tVal, true}, + {"map MI8S", "{{index .MI8S 3}}", "i83", tVal, true}, + {"map MUI8S", "{{index .MUI8S 2}}", "u82", tVal, true}, + {"index of an interface field", "{{index .Empty3 0}}", "7", tVal, true}, + + // Slicing. + {"slice[:]", "{{slice .SI}}", "[3 4 5]", tVal, true}, + {"slice[1:]", "{{slice .SI 1}}", "[4 5]", tVal, true}, + {"slice[1:2]", "{{slice .SI 1 2}}", "[4]", tVal, true}, + {"slice[-1:]", "{{slice .SI -1}}", "", tVal, false}, + {"slice[1:-2]", "{{slice .SI 1 -2}}", "", tVal, false}, + {"slice[1:2:-1]", "{{slice .SI 1 2 -1}}", "", tVal, false}, + {"slice[2:1]", "{{slice .SI 2 1}}", "", tVal, false}, + {"slice[2:2:1]", "{{slice .SI 2 2 1}}", "", tVal, false}, + {"out of range", "{{slice .SI 4 5}}", "", tVal, false}, + {"out of range", "{{slice .SI 2 2 5}}", "", tVal, false}, + {"len(s) < indexes < cap(s)", "{{slice .SICap 6 10}}", "[0 0 0 0]", tVal, true}, + {"len(s) < indexes < cap(s)", "{{slice .SICap 6 10 10}}", "[0 0 0 0]", tVal, true}, + {"indexes > cap(s)", "{{slice .SICap 10 11}}", "", tVal, false}, + {"indexes > cap(s)", "{{slice .SICap 6 10 11}}", "", tVal, false}, + {"array[:]", "{{slice .AI}}", "[3 4 5]", tVal, true}, + {"array[1:]", "{{slice .AI 1}}", "[4 5]", tVal, true}, + {"array[1:2]", "{{slice .AI 1 2}}", "[4]", tVal, true}, + {"string[:]", "{{slice .S}}", "xyz", tVal, true}, + {"string[0:1]", "{{slice .S 0 1}}", "x", tVal, true}, + {"string[1:]", "{{slice .S 1}}", "yz", tVal, true}, + {"string[1:2]", "{{slice .S 1 2}}", "y", tVal, true}, + {"out of range", "{{slice .S 1 5}}", "", tVal, false}, + {"3-index slice of string", "{{slice .S 1 2 2}}", "", tVal, false}, + {"slice of an interface field", "{{slice .Empty3 0 1}}", "[7]", tVal, true}, + + // Len. + {"slice", "{{len .SI}}", "3", tVal, true}, + {"map", "{{len .MSI }}", "3", tVal, true}, + {"len of int", "{{len 3}}", "", tVal, false}, + {"len of nothing", "{{len .Empty0}}", "", tVal, false}, + {"len of an interface field", "{{len .Empty3}}", "2", tVal, true}, + + // With. + {"with true", "{{with true}}{{.}}{{end}}", "true", tVal, true}, + {"with false", "{{with false}}{{.}}{{else}}FALSE{{end}}", "FALSE", tVal, true}, + {"with 1", "{{with 1}}{{.}}{{else}}ZERO{{end}}", "1", tVal, true}, + {"with 0", "{{with 0}}{{.}}{{else}}ZERO{{end}}", "ZERO", tVal, true}, + {"with 1.5", "{{with 1.5}}{{.}}{{else}}ZERO{{end}}", "1.5", tVal, true}, + {"with 0.0", "{{with .FloatZero}}{{.}}{{else}}ZERO{{end}}", "ZERO", tVal, true}, + {"with 1.5i", "{{with 1.5i}}{{.}}{{else}}ZERO{{end}}", "(0+1.5i)", tVal, true}, + {"with 0.0i", "{{with .ComplexZero}}{{.}}{{else}}ZERO{{end}}", "ZERO", tVal, true}, + {"with emptystring", "{{with ``}}{{.}}{{else}}EMPTY{{end}}", "EMPTY", tVal, true}, + {"with string", "{{with `notempty`}}{{.}}{{else}}EMPTY{{end}}", "notempty", tVal, true}, + {"with emptyslice", "{{with .SIEmpty}}{{.}}{{else}}EMPTY{{end}}", "EMPTY", tVal, true}, + {"with slice", "{{with .SI}}{{.}}{{else}}EMPTY{{end}}", "[3 4 5]", tVal, true}, + {"with emptymap", "{{with .MSIEmpty}}{{.}}{{else}}EMPTY{{end}}", "EMPTY", tVal, true}, + {"with map", "{{with .MSIone}}{{.}}{{else}}EMPTY{{end}}", "map[one:1]", tVal, true}, + {"with empty interface, struct field", "{{with .Empty4}}{{.V}}{{end}}", "UinEmpty", tVal, true}, + {"with $x int", "{{with $x := .I}}{{$x}}{{end}}", "17", tVal, true}, + {"with $x struct.U.V", "{{with $x := $}}{{$x.U.V}}{{end}}", "v", tVal, true}, + {"with variable and action", "{{with $x := $}}{{$y := $.U.V}}{{$y}}{{end}}", "v", tVal, true}, + {"with on typed nil interface value", "{{with .NonEmptyInterfaceTypedNil}}TRUE{{ end }}", "", tVal, true}, + + // Range. + {"range []int", "{{range .SI}}-{{.}}-{{end}}", "-3--4--5-", tVal, true}, + {"range empty no else", "{{range .SIEmpty}}-{{.}}-{{end}}", "", tVal, true}, + {"range []int else", "{{range .SI}}-{{.}}-{{else}}EMPTY{{end}}", "-3--4--5-", tVal, true}, + {"range empty else", "{{range .SIEmpty}}-{{.}}-{{else}}EMPTY{{end}}", "EMPTY", tVal, true}, + {"range []bool", "{{range .SB}}-{{.}}-{{end}}", "-true--false-", tVal, true}, + {"range []int method", "{{range .SI | .MAdd .I}}-{{.}}-{{end}}", "-20--21--22-", tVal, true}, + {"range map", "{{range .MSI}}-{{.}}-{{end}}", "-1--3--2-", tVal, true}, + {"range empty map no else", "{{range .MSIEmpty}}-{{.}}-{{end}}", "", tVal, true}, + {"range map else", "{{range .MSI}}-{{.}}-{{else}}EMPTY{{end}}", "-1--3--2-", tVal, true}, + {"range empty map else", "{{range .MSIEmpty}}-{{.}}-{{else}}EMPTY{{end}}", "EMPTY", tVal, true}, + {"range empty interface", "{{range .Empty3}}-{{.}}-{{else}}EMPTY{{end}}", "-7--8-", tVal, true}, + {"range empty nil", "{{range .Empty0}}-{{.}}-{{end}}", "", tVal, true}, + {"range $x SI", "{{range $x := .SI}}<{{$x}}>{{end}}", "<3><4><5>", tVal, true}, + {"range $x $y SI", "{{range $x, $y := .SI}}<{{$x}}={{$y}}>{{end}}", "<0=3><1=4><2=5>", tVal, true}, + {"range $x MSIone", "{{range $x := .MSIone}}<{{$x}}>{{end}}", "<1>", tVal, true}, + {"range $x $y MSIone", "{{range $x, $y := .MSIone}}<{{$x}}={{$y}}>{{end}}", "<one=1>", tVal, true}, + {"range $x PSI", "{{range $x := .PSI}}<{{$x}}>{{end}}", "<21><22><23>", tVal, true}, + {"declare in range", "{{range $x := .PSI}}<{{$foo:=$x}}{{$x}}>{{end}}", "<21><22><23>", tVal, true}, + {"range count", `{{range $i, $x := count 5}}[{{$i}}]{{$x}}{{end}}`, "[0]a[1]b[2]c[3]d[4]e", tVal, true}, + {"range nil count", `{{range $i, $x := count 0}}{{else}}empty{{end}}`, "empty", tVal, true}, + + // Cute examples. + {"or as if true", `{{or .SI "slice is empty"}}`, "[3 4 5]", tVal, true}, + {"or as if false", `{{or .SIEmpty "slice is empty"}}`, "slice is empty", tVal, true}, + + // Error handling. + {"error method, error", "{{.MyError true}}", "", tVal, false}, + {"error method, no error", "{{.MyError false}}", "false", tVal, true}, + + // Numbers + {"decimal", "{{print 1234}}", "1234", tVal, true}, + {"decimal _", "{{print 12_34}}", "1234", tVal, true}, + {"binary", "{{print 0b101}}", "5", tVal, true}, + {"binary _", "{{print 0b_1_0_1}}", "5", tVal, true}, + {"BINARY", "{{print 0B101}}", "5", tVal, true}, + {"octal0", "{{print 0377}}", "255", tVal, true}, + {"octal", "{{print 0o377}}", "255", tVal, true}, + {"octal _", "{{print 0o_3_7_7}}", "255", tVal, true}, + {"OCTAL", "{{print 0O377}}", "255", tVal, true}, + {"hex", "{{print 0x123}}", "291", tVal, true}, + {"hex _", "{{print 0x1_23}}", "291", tVal, true}, + {"HEX", "{{print 0X123ABC}}", "1194684", tVal, true}, + {"float", "{{print 123.4}}", "123.4", tVal, true}, + {"float _", "{{print 0_0_1_2_3.4}}", "123.4", tVal, true}, + {"hex float", "{{print +0x1.ep+2}}", "7.5", tVal, true}, + {"hex float _", "{{print +0x_1.e_0p+0_2}}", "7.5", tVal, true}, + {"HEX float", "{{print +0X1.EP+2}}", "7.5", tVal, true}, + {"print multi", "{{print 1_2_3_4 7.5_00_00_00}}", "1234 7.5", tVal, true}, + {"print multi2", "{{print 1234 0x0_1.e_0p+02}}", "1234 7.5", tVal, true}, + + // Fixed bugs. + // Must separate dot and receiver; otherwise args are evaluated with dot set to variable. + {"bug0", "{{range .MSIone}}{{if $.Method1 .}}X{{end}}{{end}}", "X", tVal, true}, + // Do not loop endlessly in indirect for non-empty interfaces. + // The bug appears with *interface only; looped forever. + {"bug1", "{{.Method0}}", "M0", &iVal, true}, + // Was taking address of interface field, so method set was empty. + {"bug2", "{{$.NonEmptyInterface.Method0}}", "M0", tVal, true}, + // Struct values were not legal in with - mere oversight. + {"bug3", "{{with $}}{{.Method0}}{{end}}", "M0", tVal, true}, + // Nil interface values in if. + {"bug4", "{{if .Empty0}}non-nil{{else}}nil{{end}}", "nil", tVal, true}, + // Stringer. + {"bug5", "{{.Str}}", "foozle", tVal, true}, + {"bug5a", "{{.Err}}", "erroozle", tVal, true}, + // Args need to be indirected and dereferenced sometimes. + {"bug6a", "{{vfunc .V0 .V1}}", "vfunc", tVal, true}, + {"bug6b", "{{vfunc .V0 .V0}}", "vfunc", tVal, true}, + {"bug6c", "{{vfunc .V1 .V0}}", "vfunc", tVal, true}, + {"bug6d", "{{vfunc .V1 .V1}}", "vfunc", tVal, true}, + // Legal parse but illegal execution: non-function should have no arguments. + {"bug7a", "{{3 2}}", "", tVal, false}, + {"bug7b", "{{$x := 1}}{{$x 2}}", "", tVal, false}, + {"bug7c", "{{$x := 1}}{{3 | $x}}", "", tVal, false}, + // Pipelined arg was not being type-checked. + {"bug8a", "{{3|oneArg}}", "", tVal, false}, + {"bug8b", "{{4|dddArg 3}}", "", tVal, false}, + // A bug was introduced that broke map lookups for lower-case names. + {"bug9", "{{.cause}}", "neglect", map[string]string{"cause": "neglect"}, true}, + // Field chain starting with function did not work. + {"bug10", "{{mapOfThree.three}}-{{(mapOfThree).three}}", "3-3", 0, true}, + // Dereferencing nil pointer while evaluating function arguments should not panic. Issue 7333. + {"bug11", "{{valueString .PS}}", "", T{}, false}, + // 0xef gave constant type float64. Issue 8622. + {"bug12xe", "{{printf `%T` 0xef}}", "int", T{}, true}, + {"bug12xE", "{{printf `%T` 0xEE}}", "int", T{}, true}, + {"bug12Xe", "{{printf `%T` 0Xef}}", "int", T{}, true}, + {"bug12XE", "{{printf `%T` 0XEE}}", "int", T{}, true}, + // Chained nodes did not work as arguments. Issue 8473. + {"bug13", "{{print (.Copy).I}}", "17", tVal, true}, + // Didn't protect against nil or literal values in field chains. + {"bug14a", "{{(nil).True}}", "", tVal, false}, + {"bug14b", "{{$x := nil}}{{$x.anything}}", "", tVal, false}, + {"bug14c", `{{$x := (1.0)}}{{$y := ("hello")}}{{$x.anything}}{{$y.true}}`, "", tVal, false}, + // Didn't call validateType on function results. Issue 10800. + {"bug15", "{{valueString returnInt}}", "", tVal, false}, + // Variadic function corner cases. Issue 10946. + {"bug16a", "{{true|printf}}", "", tVal, false}, + {"bug16b", "{{1|printf}}", "", tVal, false}, + {"bug16c", "{{1.1|printf}}", "", tVal, false}, + {"bug16d", "{{'x'|printf}}", "", tVal, false}, + {"bug16e", "{{0i|printf}}", "", tVal, false}, + {"bug16f", "{{true|twoArgs \"xxx\"}}", "", tVal, false}, + {"bug16g", "{{\"aaa\" |twoArgs \"bbb\"}}", "twoArgs=bbbaaa", tVal, true}, + {"bug16h", "{{1|oneArg}}", "", tVal, false}, + {"bug16i", "{{\"aaa\"|oneArg}}", "oneArg=aaa", tVal, true}, + {"bug16j", "{{1+2i|printf \"%v\"}}", "(1+2i)", tVal, true}, + {"bug16k", "{{\"aaa\"|printf }}", "aaa", tVal, true}, + {"bug17a", "{{.NonEmptyInterface.X}}", "x", tVal, true}, + {"bug17b", "-{{.NonEmptyInterface.Method1 1234}}-", "-1234-", tVal, true}, + {"bug17c", "{{len .NonEmptyInterfacePtS}}", "2", tVal, true}, + {"bug17d", "{{index .NonEmptyInterfacePtS 0}}", "a", tVal, true}, + {"bug17e", "{{range .NonEmptyInterfacePtS}}-{{.}}-{{end}}", "-a--b-", tVal, true}, + + // More variadic function corner cases. Some runes would get evaluated + // as constant floats instead of ints. Issue 34483. + {"bug18a", "{{eq . '.'}}", "true", '.', true}, + {"bug18b", "{{eq . 'e'}}", "true", 'e', true}, + {"bug18c", "{{eq . 'P'}}", "true", 'P', true}, +} + +func zeroArgs() string { + return "zeroArgs" +} + +func oneArg(a string) string { + return "oneArg=" + a +} + +func twoArgs(a, b string) string { + return "twoArgs=" + a + b +} + +func dddArg(a int, b ...string) string { + return fmt.Sprintln(a, b) +} + +// count returns a channel that will deliver n sequential 1-letter strings starting at "a" +func count(n int) chan string { + if n == 0 { + return nil + } + c := make(chan string) + go func() { + for i := 0; i < n; i++ { + c <- "abcdefghijklmnop"[i : i+1] + } + close(c) + }() + return c +} + +// vfunc takes a *V and a V +func vfunc(V, *V) string { + return "vfunc" +} + +// valueString takes a string, not a pointer. +func valueString(v string) string { + return "value is ignored" +} + +// returnInt returns an int +func returnInt() int { + return 7 +} + +func add(args ...int) int { + sum := 0 + for _, x := range args { + sum += x + } + return sum +} + +func echo(arg interface{}) interface{} { + return arg +} + +func makemap(arg ...string) map[string]string { + if len(arg)%2 != 0 { + panic("bad makemap") + } + m := make(map[string]string) + for i := 0; i < len(arg); i += 2 { + m[arg[i]] = arg[i+1] + } + return m +} + +func stringer(s fmt.Stringer) string { + return s.String() +} + +func mapOfThree() interface{} { + return map[string]int{"three": 3} +} + +func testExecute(execTests []execTest, template *Template, t *testing.T) { + b := new(bytes.Buffer) + funcs := FuncMap{ + "add": add, + "count": count, + "dddArg": dddArg, + "echo": echo, + "makemap": makemap, + "mapOfThree": mapOfThree, + "oneArg": oneArg, + "returnInt": returnInt, + "stringer": stringer, + "twoArgs": twoArgs, + "typeOf": typeOf, + "valueString": valueString, + "vfunc": vfunc, + "zeroArgs": zeroArgs, + } + for _, test := range execTests { + var tmpl *Template + var err error + if template == nil { + tmpl, err = New(test.name).Funcs(funcs).Parse(test.input) + } else { + tmpl, err = template.Clone() + if err != nil { + t.Errorf("%s: clone error: %s", test.name, err) + continue + } + tmpl, err = tmpl.New(test.name).Funcs(funcs).Parse(test.input) + } + if err != nil { + t.Errorf("%s: parse error: %s", test.name, err) + continue + } + b.Reset() + err = tmpl.Execute(b, test.data) + switch { + case !test.ok && err == nil: + t.Errorf("%s: expected error; got none", test.name) + continue + case test.ok && err != nil: + t.Errorf("%s: unexpected execute error: %s", test.name, err) + continue + case !test.ok && err != nil: + // expected error, got one + if *debug { + fmt.Printf("%s: %s\n\t%s\n", test.name, test.input, err) + } + } + result := b.String() + if result != test.output { + t.Errorf("%s: expected\n\t%q\ngot\n\t%q", test.name, test.output, result) + } + } +} + +func TestExecute(t *testing.T) { + testExecute(execTests, nil, t) +} + +var delimPairs = []string{ + "", "", // default + "{{", "}}", // same as default + "|", "|", // same + "(日)", "(本)", // peculiar +} + +func TestDelims(t *testing.T) { + const hello = "Hello, world" + var value = struct{ Str string }{hello} + for i := 0; i < len(delimPairs); i += 2 { + text := ".Str" + left := delimPairs[i+0] + trueLeft := left + right := delimPairs[i+1] + trueRight := right + if left == "" { // default case + trueLeft = "{{" + } + if right == "" { // default case + trueRight = "}}" + } + text = trueLeft + text + trueRight + // Now add a comment + text += trueLeft + "/*comment*/" + trueRight + // Now add an action containing a string. + text += trueLeft + `"` + trueLeft + `"` + trueRight + // At this point text looks like `{{.Str}}{{/*comment*/}}{{"{{"}}`. + tmpl, err := New("delims").Delims(left, right).Parse(text) + if err != nil { + t.Fatalf("delim %q text %q parse err %s", left, text, err) + } + var b = new(bytes.Buffer) + err = tmpl.Execute(b, value) + if err != nil { + t.Fatalf("delim %q exec err %s", left, err) + } + if b.String() != hello+trueLeft { + t.Errorf("expected %q got %q", hello+trueLeft, b.String()) + } + } +} + +// Check that an error from a method flows back to the top. +func TestExecuteError(t *testing.T) { + b := new(bytes.Buffer) + tmpl := New("error") + _, err := tmpl.Parse("{{.MyError true}}") + if err != nil { + t.Fatalf("parse error: %s", err) + } + err = tmpl.Execute(b, tVal) + if err == nil { + t.Errorf("expected error; got none") + } else if !strings.Contains(err.Error(), myError.Error()) { + if *debug { + fmt.Printf("test execute error: %s\n", err) + } + t.Errorf("expected myError; got %s", err) + } +} + +const execErrorText = `line 1 +line 2 +line 3 +{{template "one" .}} +{{define "one"}}{{template "two" .}}{{end}} +{{define "two"}}{{template "three" .}}{{end}} +{{define "three"}}{{index "hi" $}}{{end}}` + +// Check that an error from a nested template contains all the relevant information. +func TestExecError(t *testing.T) { + tmpl, err := New("top").Parse(execErrorText) + if err != nil { + t.Fatal("parse error:", err) + } + var b bytes.Buffer + err = tmpl.Execute(&b, 5) // 5 is out of range indexing "hi" + if err == nil { + t.Fatal("expected error") + } + const want = `template: top:7:20: executing "three" at : error calling index: index out of range: 5` + got := err.Error() + if got != want { + t.Errorf("expected\n%q\ngot\n%q", want, got) + } +} + +func TestJSEscaping(t *testing.T) { + testCases := []struct { + in, exp string + }{ + {`a`, `a`}, + {`'foo`, `\'foo`}, + {`Go "jump" \`, `Go \"jump\" \\`}, + {`Yukihiro says "今日は世界"`, `Yukihiro says \"今日は世界\"`}, + {"unprintable \uFDFF", `unprintable \uFDFF`}, + {``, `\u003Chtml\u003E`}, + {`no = in attributes`, `no \u003D in attributes`}, + {`' does not become HTML entity`, `\u0026#x27; does not become HTML entity`}, + } + for _, tc := range testCases { + s := JSEscapeString(tc.in) + if s != tc.exp { + t.Errorf("JS escaping [%s] got [%s] want [%s]", tc.in, s, tc.exp) + } + } +} + +// A nice example: walk a binary tree. + +type Tree struct { + Val int + Left, Right *Tree +} + +// Use different delimiters to test Set.Delims. +// Also test the trimming of leading and trailing spaces. +const treeTemplate = ` + (- define "tree" -) + [ + (- .Val -) + (- with .Left -) + (template "tree" . -) + (- end -) + (- with .Right -) + (- template "tree" . -) + (- end -) + ] + (- end -) +` + +func TestTree(t *testing.T) { + var tree = &Tree{ + 1, + &Tree{ + 2, &Tree{ + 3, + &Tree{ + 4, nil, nil, + }, + nil, + }, + &Tree{ + 5, + &Tree{ + 6, nil, nil, + }, + nil, + }, + }, + &Tree{ + 7, + &Tree{ + 8, + &Tree{ + 9, nil, nil, + }, + nil, + }, + &Tree{ + 10, + &Tree{ + 11, nil, nil, + }, + nil, + }, + }, + } + tmpl, err := New("root").Delims("(", ")").Parse(treeTemplate) + if err != nil { + t.Fatal("parse error:", err) + } + var b bytes.Buffer + const expect = "[1[2[3[4]][5[6]]][7[8[9]][10[11]]]]" + // First by looking up the template. + err = tmpl.Lookup("tree").Execute(&b, tree) + if err != nil { + t.Fatal("exec error:", err) + } + result := b.String() + if result != expect { + t.Errorf("expected %q got %q", expect, result) + } + // Then direct to execution. + b.Reset() + err = tmpl.ExecuteTemplate(&b, "tree", tree) + if err != nil { + t.Fatal("exec error:", err) + } + result = b.String() + if result != expect { + t.Errorf("expected %q got %q", expect, result) + } +} + +func TestExecuteOnNewTemplate(t *testing.T) { + // This is issue 3872. + New("Name").Templates() + // This is issue 11379. + // new(Template).Templates() // TODO: crashes + // new(Template).Parse("") // TODO: crashes + // new(Template).New("abc").Parse("") // TODO: crashes + // new(Template).Execute(nil, nil) // TODO: crashes; returns an error (but does not crash) + // new(Template).ExecuteTemplate(nil, "XXX", nil) // TODO: crashes; returns an error (but does not crash) +} + +const testTemplates = `{{define "one"}}one{{end}}{{define "two"}}two{{end}}` + +func TestMessageForExecuteEmpty(t *testing.T) { + // Test a truly empty template. + tmpl := New("empty") + var b bytes.Buffer + err := tmpl.Execute(&b, 0) + if err == nil { + t.Fatal("expected initial error") + } + got := err.Error() + want := `template: "empty" is an incomplete or empty template` // NOTE: text/template has extra "empty: " in message + if got != want { + t.Errorf("expected error %s got %s", want, got) + } + + // Add a non-empty template to check that the error is helpful. + tmpl = New("empty") + tests, err := New("").Parse(testTemplates) + if err != nil { + t.Fatal(err) + } + tmpl.AddParseTree("secondary", tests.Tree) + err = tmpl.Execute(&b, 0) + if err == nil { + t.Fatal("expected second error") + } + got = err.Error() + if got != want { + t.Errorf("expected error %s got %s", want, got) + } + // Make sure we can execute the secondary. + err = tmpl.ExecuteTemplate(&b, "secondary", 0) + if err != nil { + t.Fatal(err) + } +} + +func TestFinalForPrintf(t *testing.T) { + tmpl, err := New("").Parse(`{{"x" | printf}}`) + if err != nil { + t.Fatal(err) + } + var b bytes.Buffer + err = tmpl.Execute(&b, 0) + if err != nil { + t.Fatal(err) + } +} + +type cmpTest struct { + expr string + truth string + ok bool +} + +var cmpTests = []cmpTest{ + {"eq true true", "true", true}, + {"eq true false", "false", true}, + {"eq 1+2i 1+2i", "true", true}, + {"eq 1+2i 1+3i", "false", true}, + {"eq 1.5 1.5", "true", true}, + {"eq 1.5 2.5", "false", true}, + {"eq 1 1", "true", true}, + {"eq 1 2", "false", true}, + {"eq `xy` `xy`", "true", true}, + {"eq `xy` `xyz`", "false", true}, + {"eq .Uthree .Uthree", "true", true}, + {"eq .Uthree .Ufour", "false", true}, + {"eq 3 4 5 6 3", "true", true}, + {"eq 3 4 5 6 7", "false", true}, + {"ne true true", "false", true}, + {"ne true false", "true", true}, + {"ne 1+2i 1+2i", "false", true}, + {"ne 1+2i 1+3i", "true", true}, + {"ne 1.5 1.5", "false", true}, + {"ne 1.5 2.5", "true", true}, + {"ne 1 1", "false", true}, + {"ne 1 2", "true", true}, + {"ne `xy` `xy`", "false", true}, + {"ne `xy` `xyz`", "true", true}, + {"ne .Uthree .Uthree", "false", true}, + {"ne .Uthree .Ufour", "true", true}, + {"lt 1.5 1.5", "false", true}, + {"lt 1.5 2.5", "true", true}, + {"lt 1 1", "false", true}, + {"lt 1 2", "true", true}, + {"lt `xy` `xy`", "false", true}, + {"lt `xy` `xyz`", "true", true}, + {"lt .Uthree .Uthree", "false", true}, + {"lt .Uthree .Ufour", "true", true}, + {"le 1.5 1.5", "true", true}, + {"le 1.5 2.5", "true", true}, + {"le 2.5 1.5", "false", true}, + {"le 1 1", "true", true}, + {"le 1 2", "true", true}, + {"le 2 1", "false", true}, + {"le `xy` `xy`", "true", true}, + {"le `xy` `xyz`", "true", true}, + {"le `xyz` `xy`", "false", true}, + {"le .Uthree .Uthree", "true", true}, + {"le .Uthree .Ufour", "true", true}, + {"le .Ufour .Uthree", "false", true}, + {"gt 1.5 1.5", "false", true}, + {"gt 1.5 2.5", "false", true}, + {"gt 1 1", "false", true}, + {"gt 2 1", "true", true}, + {"gt 1 2", "false", true}, + {"gt `xy` `xy`", "false", true}, + {"gt `xy` `xyz`", "false", true}, + {"gt .Uthree .Uthree", "false", true}, + {"gt .Uthree .Ufour", "false", true}, + {"gt .Ufour .Uthree", "true", true}, + {"ge 1.5 1.5", "true", true}, + {"ge 1.5 2.5", "false", true}, + {"ge 2.5 1.5", "true", true}, + {"ge 1 1", "true", true}, + {"ge 1 2", "false", true}, + {"ge 2 1", "true", true}, + {"ge `xy` `xy`", "true", true}, + {"ge `xy` `xyz`", "false", true}, + {"ge `xyz` `xy`", "true", true}, + {"ge .Uthree .Uthree", "true", true}, + {"ge .Uthree .Ufour", "false", true}, + {"ge .Ufour .Uthree", "true", true}, + // Mixing signed and unsigned integers. + {"eq .Uthree .Three", "true", true}, + {"eq .Three .Uthree", "true", true}, + {"le .Uthree .Three", "true", true}, + {"le .Three .Uthree", "true", true}, + {"ge .Uthree .Three", "true", true}, + {"ge .Three .Uthree", "true", true}, + {"lt .Uthree .Three", "false", true}, + {"lt .Three .Uthree", "false", true}, + {"gt .Uthree .Three", "false", true}, + {"gt .Three .Uthree", "false", true}, + {"eq .Ufour .Three", "false", true}, + {"lt .Ufour .Three", "false", true}, + {"gt .Ufour .Three", "true", true}, + {"eq .NegOne .Uthree", "false", true}, + {"eq .Uthree .NegOne", "false", true}, + {"ne .NegOne .Uthree", "true", true}, + {"ne .Uthree .NegOne", "true", true}, + {"lt .NegOne .Uthree", "true", true}, + {"lt .Uthree .NegOne", "false", true}, + {"le .NegOne .Uthree", "true", true}, + {"le .Uthree .NegOne", "false", true}, + {"gt .NegOne .Uthree", "false", true}, + {"gt .Uthree .NegOne", "true", true}, + {"ge .NegOne .Uthree", "false", true}, + {"ge .Uthree .NegOne", "true", true}, + {"eq (index `x` 0) 'x'", "true", true}, // The example that triggered this rule. + {"eq (index `x` 0) 'y'", "false", true}, + {"eq .V1 .V2", "true", true}, + {"eq .Ptr .Ptr", "true", true}, + {"eq .Ptr .NilPtr", "false", true}, + {"eq .NilPtr .NilPtr", "true", true}, + {"eq .Iface1 .Iface1", "true", true}, + {"eq .Iface1 .Iface2", "false", true}, + {"eq .Iface2 .Iface2", "true", true}, + // Errors + {"eq `xy` 1", "", false}, // Different types. + {"eq 2 2.0", "", false}, // Different types. + {"lt true true", "", false}, // Unordered types. + {"lt 1+0i 1+0i", "", false}, // Unordered types. + {"eq .Ptr 1", "", false}, // Incompatible types. + {"eq .Ptr .NegOne", "", false}, // Incompatible types. + {"eq .Map .Map", "", false}, // Uncomparable types. + {"eq .Map .V1", "", false}, // Uncomparable types. +} + +func TestComparison(t *testing.T) { + b := new(bytes.Buffer) + var cmpStruct = struct { + Uthree, Ufour uint + NegOne, Three int + Ptr, NilPtr *int + Map map[int]int + V1, V2 V + Iface1, Iface2 fmt.Stringer + }{ + Uthree: 3, + Ufour: 4, + NegOne: -1, + Three: 3, + Ptr: new(int), + Iface1: b, + } + for _, test := range cmpTests { + text := fmt.Sprintf("{{if %s}}true{{else}}false{{end}}", test.expr) + tmpl, err := New("empty").Parse(text) + if err != nil { + t.Fatalf("%q: %s", test.expr, err) + } + b.Reset() + err = tmpl.Execute(b, &cmpStruct) + if test.ok && err != nil { + t.Errorf("%s errored incorrectly: %s", test.expr, err) + continue + } + if !test.ok && err == nil { + t.Errorf("%s did not error", test.expr) + continue + } + if b.String() != test.truth { + t.Errorf("%s: want %s; got %s", test.expr, test.truth, b.String()) + } + } +} + +func TestMissingMapKey(t *testing.T) { + data := map[string]int{ + "x": 99, + } + tmpl, err := New("t1").Parse("{{.x}} {{.y}}") + if err != nil { + t.Fatal(err) + } + var b bytes.Buffer + // By default, just get "" // NOTE: not in html/template, get empty string + err = tmpl.Execute(&b, data) + if err != nil { + t.Fatal(err) + } + want := "99 " + got := b.String() + if got != want { + t.Errorf("got %q; expected %q", got, want) + } + // Same if we set the option explicitly to the default. + tmpl.Option("missingkey=default") + b.Reset() + err = tmpl.Execute(&b, data) + if err != nil { + t.Fatal("default:", err) + } + got = b.String() + if got != want { + t.Errorf("got %q; expected %q", got, want) + } + // Next we ask for a zero value + tmpl.Option("missingkey=zero") + b.Reset() + err = tmpl.Execute(&b, data) + if err != nil { + t.Fatal("zero:", err) + } + want = "99 0" + got = b.String() + if got != want { + t.Errorf("got %q; expected %q", got, want) + } + // Now we ask for an error. + tmpl.Option("missingkey=error") + err = tmpl.Execute(&b, data) + if err == nil { + t.Errorf("expected error; got none") + } + // same Option, but now a nil interface: ask for an error + err = tmpl.Execute(&b, nil) + t.Log(err) + if err == nil { + t.Errorf("expected error for nil-interface; got none") + } +} + +// Test that the error message for multiline unterminated string +// refers to the line number of the opening quote. +func TestUnterminatedStringError(t *testing.T) { + _, err := New("X").Parse("hello\n\n{{`unterminated\n\n\n\n}}\n some more\n\n") + if err == nil { + t.Fatal("expected error") + } + str := err.Error() + if !strings.Contains(str, "X:3: unexpected unterminated raw quoted string") { + t.Fatalf("unexpected error: %s", str) + } +} + +const alwaysErrorText = "always be failing" + +var alwaysError = errors.New(alwaysErrorText) + +type ErrorWriter int + +func (e ErrorWriter) Write(p []byte) (int, error) { + return 0, alwaysError +} + +func TestExecuteGivesExecError(t *testing.T) { + // First, a non-execution error shouldn't be an ExecError. + tmpl, err := New("X").Parse("hello") + if err != nil { + t.Fatal(err) + } + err = tmpl.Execute(ErrorWriter(0), 0) + if err == nil { + t.Fatal("expected error; got none") + } + if err.Error() != alwaysErrorText { + t.Errorf("expected %q error; got %q", alwaysErrorText, err) + } + // This one should be an ExecError. + tmpl, err = New("X").Parse("hello, {{.X.Y}}") + if err != nil { + t.Fatal(err) + } + err = tmpl.Execute(ioutil.Discard, 0) + if err == nil { + t.Fatal("expected error; got none") + } + eerr, ok := err.(template.ExecError) + if !ok { + t.Fatalf("did not expect ExecError %s", eerr) + } + expect := "field X in type int" + if !strings.Contains(err.Error(), expect) { + t.Errorf("expected %q; got %q", expect, err) + } +} + +func funcNameTestFunc() int { + return 0 +} + +func TestGoodFuncNames(t *testing.T) { + names := []string{ + "_", + "a", + "a1", + "a1", + "Ó´", + } + for _, name := range names { + tmpl := New("X").Funcs( + FuncMap{ + name: funcNameTestFunc, + }, + ) + if tmpl == nil { + t.Fatalf("nil result for %q", name) + } + } +} + +func TestBadFuncNames(t *testing.T) { + names := []string{ + "", + "2", + "a-b", + } + for _, name := range names { + testBadFuncName(name, t) + } +} + +func testBadFuncName(name string, t *testing.T) { + t.Helper() + defer func() { + recover() + }() + New("X").Funcs( + FuncMap{ + name: funcNameTestFunc, + }, + ) + // If we get here, the name did not cause a panic, which is how Funcs + // reports an error. + t.Errorf("%q succeeded incorrectly as function name", name) +} + +func TestBlock(t *testing.T) { + const ( + input = `a({{block "inner" .}}bar({{.}})baz{{end}})b` + want = `a(bar(hello)baz)b` + overlay = `{{define "inner"}}foo({{.}})bar{{end}}` + want2 = `a(foo(goodbye)bar)b` + ) + tmpl, err := New("outer").Parse(input) + if err != nil { + t.Fatal(err) + } + tmpl2, err := Must(tmpl.Clone()).Parse(overlay) + if err != nil { + t.Fatal(err) + } + + var buf bytes.Buffer + if err := tmpl.Execute(&buf, "hello"); err != nil { + t.Fatal(err) + } + if got := buf.String(); got != want { + t.Errorf("got %q, want %q", got, want) + } + + buf.Reset() + if err := tmpl2.Execute(&buf, "goodbye"); err != nil { + t.Fatal(err) + } + if got := buf.String(); got != want2 { + t.Errorf("got %q, want %q", got, want2) + } +} + +func TestEvalFieldErrors(t *testing.T) { + tests := []struct { + name, src string + value interface{} + want string + }{ + { + // Check that calling an invalid field on nil pointer + // prints a field error instead of a distracting nil + // pointer error. https://golang.org/issue/15125 + "MissingFieldOnNil", + "{{.MissingField}}", + (*T)(nil), + "can't evaluate field MissingField in type *template.T", + }, + { + "MissingFieldOnNonNil", + "{{.MissingField}}", + &T{}, + "can't evaluate field MissingField in type *template.T", + }, + { + "ExistingFieldOnNil", + "{{.X}}", + (*T)(nil), + "nil pointer evaluating *template.T.X", + }, + { + "MissingKeyOnNilMap", + "{{.MissingKey}}", + (*map[string]string)(nil), + "nil pointer evaluating *map[string]string.MissingKey", + }, + { + "MissingKeyOnNilMapPtr", + "{{.MissingKey}}", + (*map[string]string)(nil), + "nil pointer evaluating *map[string]string.MissingKey", + }, + { + "MissingKeyOnMapPtrToNil", + "{{.MissingKey}}", + &map[string]string{}, + "", + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + tmpl := Must(New("tmpl").Parse(tc.src)) + err := tmpl.Execute(ioutil.Discard, tc.value) + got := "" + if err != nil { + got = err.Error() + } + if !strings.HasSuffix(got, tc.want) { + t.Fatalf("got error %q, want %q", got, tc.want) + } + }) + } +} + +func TestMaxExecDepth(t *testing.T) { + if testing.Short() { + t.Skip("skipping in -short mode") + } + tmpl := Must(New("tmpl").Parse(`{{template "tmpl" .}}`)) + err := tmpl.Execute(ioutil.Discard, nil) + got := "" + if err != nil { + got = err.Error() + } + const want = "exceeded maximum template depth" + if !strings.Contains(got, want) { + t.Errorf("got error %q; want %q", got, want) + } +} + +func TestAddrOfIndex(t *testing.T) { + // golang.org/issue/14916. + // Before index worked on reflect.Values, the .String could not be + // found on the (incorrectly unaddressable) V value, + // in contrast to range, which worked fine. + // Also testing that passing a reflect.Value to tmpl.Execute works. + texts := []string{ + `{{range .}}{{.String}}{{end}}`, + `{{with index . 0}}{{.String}}{{end}}`, + } + for _, text := range texts { + tmpl := Must(New("tmpl").Parse(text)) + var buf bytes.Buffer + err := tmpl.Execute(&buf, reflect.ValueOf([]V{{1}})) + if err != nil { + t.Fatalf("%s: Execute: %v", text, err) + } + if buf.String() != "<1>" { + t.Fatalf("%s: template output = %q, want %q", text, &buf, "<1>") + } + } +} + +func TestInterfaceValues(t *testing.T) { + // golang.org/issue/17714. + // Before index worked on reflect.Values, interface values + // were always implicitly promoted to the underlying value, + // except that nil interfaces were promoted to the zero reflect.Value. + // Eliminating a round trip to interface{} and back to reflect.Value + // eliminated this promotion, breaking these cases. + tests := []struct { + text string + out string + }{ + {`{{index .Nil 1}}`, "ERROR: index of untyped nil"}, + {`{{index .Slice 2}}`, "2"}, + {`{{index .Slice .Two}}`, "2"}, + {`{{call .Nil 1}}`, "ERROR: call of nil"}, + {`{{call .PlusOne 1}}`, "2"}, + {`{{call .PlusOne .One}}`, "2"}, + {`{{and (index .Slice 0) true}}`, "0"}, + {`{{and .Zero true}}`, "0"}, + {`{{and (index .Slice 1) false}}`, "false"}, + {`{{and .One false}}`, "false"}, + {`{{or (index .Slice 0) false}}`, "false"}, + {`{{or .Zero false}}`, "false"}, + {`{{or (index .Slice 1) true}}`, "1"}, + {`{{or .One true}}`, "1"}, + {`{{not (index .Slice 0)}}`, "true"}, + {`{{not .Zero}}`, "true"}, + {`{{not (index .Slice 1)}}`, "false"}, + {`{{not .One}}`, "false"}, + {`{{eq (index .Slice 0) .Zero}}`, "true"}, + {`{{eq (index .Slice 1) .One}}`, "true"}, + {`{{ne (index .Slice 0) .Zero}}`, "false"}, + {`{{ne (index .Slice 1) .One}}`, "false"}, + {`{{ge (index .Slice 0) .One}}`, "false"}, + {`{{ge (index .Slice 1) .Zero}}`, "true"}, + {`{{gt (index .Slice 0) .One}}`, "false"}, + {`{{gt (index .Slice 1) .Zero}}`, "true"}, + {`{{le (index .Slice 0) .One}}`, "true"}, + {`{{le (index .Slice 1) .Zero}}`, "false"}, + {`{{lt (index .Slice 0) .One}}`, "true"}, + {`{{lt (index .Slice 1) .Zero}}`, "false"}, + } + + for _, tt := range tests { + tmpl := Must(New("tmpl").Parse(tt.text)) + var buf bytes.Buffer + err := tmpl.Execute(&buf, map[string]interface{}{ + "PlusOne": func(n int) int { + return n + 1 + }, + "Slice": []int{0, 1, 2, 3}, + "One": 1, + "Two": 2, + "Nil": nil, + "Zero": 0, + }) + if strings.HasPrefix(tt.out, "ERROR:") { + e := strings.TrimSpace(strings.TrimPrefix(tt.out, "ERROR:")) + if err == nil || !strings.Contains(err.Error(), e) { + t.Errorf("%s: Execute: %v, want error %q", tt.text, err, e) + } + continue + } + if err != nil { + t.Errorf("%s: Execute: %v", tt.text, err) + continue + } + if buf.String() != tt.out { + t.Errorf("%s: template output = %q, want %q", tt.text, &buf, tt.out) + } + } +} + +// Check that panics during calls are recovered and returned as errors. +func TestExecutePanicDuringCall(t *testing.T) { + funcs := map[string]interface{}{ + "doPanic": func() string { + panic("custom panic string") + }, + } + tests := []struct { + name string + input string + data interface{} + wantErr string + }{ + { + "direct func call panics", + "{{doPanic}}", (*T)(nil), + `template: t:1:2: executing "t" at : error calling doPanic: custom panic string`, + }, + { + "indirect func call panics", + "{{call doPanic}}", (*T)(nil), + `template: t:1:7: executing "t" at : error calling doPanic: custom panic string`, + }, + { + "direct method call panics", + "{{.GetU}}", (*T)(nil), + `template: t:1:2: executing "t" at <.GetU>: error calling GetU: runtime error: invalid memory address or nil pointer dereference`, + }, + { + "indirect method call panics", + "{{call .GetU}}", (*T)(nil), + `template: t:1:7: executing "t" at <.GetU>: error calling GetU: runtime error: invalid memory address or nil pointer dereference`, + }, + { + "func field call panics", + "{{call .PanicFunc}}", tVal, + `template: t:1:2: executing "t" at : error calling call: test panic`, + }, + { + "method call on nil interface", + "{{.NonEmptyInterfaceNil.Method0}}", tVal, + `template: t:1:23: executing "t" at <.NonEmptyInterfaceNil.Method0>: nil pointer evaluating template.I.Method0`, + }, + } + for _, tc := range tests { + b := new(bytes.Buffer) + tmpl, err := New("t").Funcs(funcs).Parse(tc.input) + if err != nil { + t.Fatalf("parse error: %s", err) + } + err = tmpl.Execute(b, tc.data) + if err == nil { + t.Errorf("%s: expected error; got none", tc.name) + } else if !strings.Contains(err.Error(), tc.wantErr) { + if *debug { + fmt.Printf("%s: test execute error: %s\n", tc.name, err) + } + t.Errorf("%s: expected error:\n%s\ngot:\n%s", tc.name, tc.wantErr, err) + } + } +} + +// Issue 31810. Check that a parenthesized first argument behaves properly. +func TestIssue31810(t *testing.T) { + t.Skip("broken in html/template") + + // A simple value with no arguments is fine. + var b bytes.Buffer + const text = "{{ (.) }}" + tmpl, err := New("").Parse(text) + if err != nil { + t.Error(err) + } + err = tmpl.Execute(&b, "result") + if err != nil { + t.Error(err) + } + if b.String() != "result" { + t.Errorf("%s got %q, expected %q", text, b.String(), "result") + } + + // Even a plain function fails - need to use call. + f := func() string { return "result" } + b.Reset() + err = tmpl.Execute(&b, f) + if err == nil { + t.Error("expected error with no call, got none") + } + + // Works if the function is explicitly called. + const textCall = "{{ (call .) }}" + tmpl, err = New("").Parse(textCall) + b.Reset() + err = tmpl.Execute(&b, f) + if err != nil { + t.Error(err) + } + if b.String() != "result" { + t.Errorf("%s got %q, expected %q", textCall, b.String(), "result") + } +} diff --git a/libgo/go/html/template/html.go b/libgo/go/html/template/html.go index 13a0cd04360..356b8298ae3 100644 --- a/libgo/go/html/template/html.go +++ b/libgo/go/html/template/html.go @@ -240,8 +240,7 @@ func htmlNameFilter(args ...interface{}) string { } s = strings.ToLower(s) if t := attrType(s); t != contentTypePlain { - // TODO: Split attr and element name part filters so we can whitelist - // attributes. + // TODO: Split attr and element name part filters so we can recognize known attributes. return filterFailsafe } for _, r := range s { diff --git a/libgo/go/html/template/js.go b/libgo/go/html/template/js.go index 0e91458d19c..ea9c18346ba 100644 --- a/libgo/go/html/template/js.go +++ b/libgo/go/html/template/js.go @@ -163,7 +163,6 @@ func jsValEscaper(args ...interface{}) string { } // TODO: detect cycles before calling Marshal which loops infinitely on // cyclic data. This may be an unacceptable DoS risk. - b, err := json.Marshal(a) if err != nil { // Put a space before comment so that if it is flush against @@ -178,8 +177,8 @@ func jsValEscaper(args ...interface{}) string { // TODO: maybe post-process output to prevent it from containing // "", "", or "': `\x3e`, + '<': `\u003c`, + '>': `\u003e`, '\\': `\\`, } // jsStrNormReplacementTable is like jsStrReplacementTable but does not // overencode existing escapes since this table has no entry for `\`. var jsStrNormReplacementTable = []string{ - 0: `\0`, + 0: `\u0000`, '\t': `\t`, '\n': `\n`, - '\v': `\x0b`, // "\v" == "v" on IE 6. + '\v': `\u000b`, // "\v" == "v" on IE 6. '\f': `\f`, '\r': `\r`, // Encode HTML specials as hex so the output can be embedded // in HTML attributes without further encoding. - '"': `\x22`, - '&': `\x26`, - '\'': `\x27`, - '+': `\x2b`, + '"': `\u0022`, + '&': `\u0026`, + '\'': `\u0027`, + '+': `\u002b`, '/': `\/`, - '<': `\x3c`, - '>': `\x3e`, + '<': `\u003c`, + '>': `\u003e`, } - var jsRegexpReplacementTable = []string{ - 0: `\0`, + 0: `\u0000`, '\t': `\t`, '\n': `\n`, - '\v': `\x0b`, // "\v" == "v" on IE 6. + '\v': `\u000b`, // "\v" == "v" on IE 6. '\f': `\f`, '\r': `\r`, // Encode HTML specials as hex so the output can be embedded // in HTML attributes without further encoding. - '"': `\x22`, + '"': `\u0022`, '$': `\$`, - '&': `\x26`, - '\'': `\x27`, + '&': `\u0026`, + '\'': `\u0027`, '(': `\(`, ')': `\)`, '*': `\*`, - '+': `\x2b`, + '+': `\u002b`, '-': `\-`, '.': `\.`, '/': `\/`, - '<': `\x3c`, - '>': `\x3e`, + '<': `\u003c`, + '>': `\u003e`, '?': `\?`, '[': `\[`, '\\': `\\`, diff --git a/libgo/go/html/template/js_test.go b/libgo/go/html/template/js_test.go index 075adaafd37..d7ee47b87d4 100644 --- a/libgo/go/html/template/js_test.go +++ b/libgo/go/html/template/js_test.go @@ -137,7 +137,7 @@ func TestJSValEscaper(t *testing.T) { {"foo", `"foo"`}, // Newlines. {"\r\n\u2028\u2029", `"\r\n\u2028\u2029"`}, - // "\v" == "v" on IE 6 so use "\x0b" instead. + // "\v" == "v" on IE 6 so use "\u000b" instead. {"\t\x0b", `"\t\u000b"`}, {struct{ X, Y int }{1, 2}, `{"X":1,"Y":2}`}, {[]interface{}{}, "[]"}, @@ -173,7 +173,7 @@ func TestJSStrEscaper(t *testing.T) { }{ {"", ``}, {"foo", `foo`}, - {"\u0000", `\0`}, + {"\u0000", `\u0000`}, {"\t", `\t`}, {"\n", `\n`}, {"\r", `\r`}, @@ -183,14 +183,14 @@ func TestJSStrEscaper(t *testing.T) { {"\\n", `\\n`}, {"foo\r\nbar", `foo\r\nbar`}, // Preserve attribute boundaries. - {`"`, `\x22`}, - {`'`, `\x27`}, + {`"`, `\u0022`}, + {`'`, `\u0027`}, // Allow embedding in HTML without further escaping. - {`&`, `\x26amp;`}, + {`&`, `\u0026amp;`}, // Prevent breaking out of text node and element boundaries. - {"", `\x3c\/script\x3e`}, - {"", `]]\x3e`}, + {"", `\u003c\/script\u003e`}, + {"", `]]\u003e`}, // https://dev.w3.org/html5/markup/aria/syntax.html#escaping-text-span // "The text in style, script, title, and textarea elements // must not have an escaping text span start that is not @@ -201,11 +201,11 @@ func TestJSStrEscaper(t *testing.T) { // allow regular text content to be interpreted as script // allowing script execution via a combination of a JS string // injection followed by an HTML text injection. - {"", `--\x3e`}, + {"", `--\u003e`}, // From https://code.google.com/p/doctype/wiki/ArticleUtf7 {"+ADw-script+AD4-alert(1)+ADw-/script+AD4-", - `\x2bADw-script\x2bAD4-alert(1)\x2bADw-\/script\x2bAD4-`, + `\u002bADw-script\u002bAD4-alert(1)\u002bADw-\/script\u002bAD4-`, }, // Invalid UTF-8 sequence {"foo\xA0bar", "foo\xA0bar"}, @@ -228,7 +228,7 @@ func TestJSRegexpEscaper(t *testing.T) { }{ {"", `(?:)`}, {"foo", `foo`}, - {"\u0000", `\0`}, + {"\u0000", `\u0000`}, {"\t", `\t`}, {"\n", `\n`}, {"\r", `\r`}, @@ -238,19 +238,19 @@ func TestJSRegexpEscaper(t *testing.T) { {"\\n", `\\n`}, {"foo\r\nbar", `foo\r\nbar`}, // Preserve attribute boundaries. - {`"`, `\x22`}, - {`'`, `\x27`}, + {`"`, `\u0022`}, + {`'`, `\u0027`}, // Allow embedding in HTML without further escaping. - {`&`, `\x26amp;`}, + {`&`, `\u0026amp;`}, // Prevent breaking out of text node and element boundaries. - {"", `\x3c\/script\x3e`}, - {"", `\]\]\x3e`}, + {"", `\u003c\/script\u003e`}, + {"", `\]\]\u003e`}, // Escaping text spans. - {"", `\-\-\x3e`}, + {"", `\-\-\u003e`}, {"*", `\*`}, - {"+", `\x2b`}, + {"+", `\u002b`}, {"?", `\?`}, {"[](){}", `\[\]\(\)\{\}`}, {"$foo|x.y", `\$foo\|x\.y`}, @@ -284,27 +284,27 @@ func TestEscapersOnLower7AndSelectHighCodepoints(t *testing.T) { { "jsStrEscaper", jsStrEscaper, - "\\0\x01\x02\x03\x04\x05\x06\x07" + - "\x08\\t\\n\\x0b\\f\\r\x0E\x0F" + - "\x10\x11\x12\x13\x14\x15\x16\x17" + - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" + - ` !\x22#$%\x26\x27()*\x2b,-.\/` + - `0123456789:;\x3c=\x3e?` + + `\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007` + + `\u0008\t\n\u000b\f\r\u000e\u000f` + + `\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017` + + `\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f` + + ` !\u0022#$%\u0026\u0027()*\u002b,-.\/` + + `0123456789:;\u003c=\u003e?` + `@ABCDEFGHIJKLMNO` + `PQRSTUVWXYZ[\\]^_` + "`abcdefghijklmno" + - "pqrstuvwxyz{|}~\x7f" + + "pqrstuvwxyz{|}~\u007f" + "\u00A0\u0100\\u2028\\u2029\ufeff\U0001D11E", }, { "jsRegexpEscaper", jsRegexpEscaper, - "\\0\x01\x02\x03\x04\x05\x06\x07" + - "\x08\\t\\n\\x0b\\f\\r\x0E\x0F" + - "\x10\x11\x12\x13\x14\x15\x16\x17" + - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" + - ` !\x22#\$%\x26\x27\(\)\*\x2b,\-\.\/` + - `0123456789:;\x3c=\x3e\?` + + `\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007` + + `\u0008\t\n\u000b\f\r\u000e\u000f` + + `\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017` + + `\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f` + + ` !\u0022#\$%\u0026\u0027\(\)\*\u002b,\-\.\/` + + `0123456789:;\u003c=\u003e\?` + `@ABCDEFGHIJKLMNO` + `PQRSTUVWXYZ\[\\\]\^_` + "`abcdefghijklmno" + diff --git a/libgo/go/html/template/multi_test.go b/libgo/go/html/template/multi_test.go new file mode 100644 index 00000000000..50526c5b65f --- /dev/null +++ b/libgo/go/html/template/multi_test.go @@ -0,0 +1,246 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Tests for multiple-template execution, copied from text/template. + +package template + +import ( + "bytes" + "testing" + "text/template/parse" +) + +var multiExecTests = []execTest{ + {"empty", "", "", nil, true}, + {"text", "some text", "some text", nil, true}, + {"invoke x", `{{template "x" .SI}}`, "TEXT", tVal, true}, + {"invoke x no args", `{{template "x"}}`, "TEXT", tVal, true}, + {"invoke dot int", `{{template "dot" .I}}`, "17", tVal, true}, + {"invoke dot []int", `{{template "dot" .SI}}`, "[3 4 5]", tVal, true}, + {"invoke dotV", `{{template "dotV" .U}}`, "v", tVal, true}, + {"invoke nested int", `{{template "nested" .I}}`, "17", tVal, true}, + {"variable declared by template", `{{template "nested" $x:=.SI}},{{index $x 1}}`, "[3 4 5],4", tVal, true}, + + // User-defined function: test argument evaluator. + {"testFunc literal", `{{oneArg "joe"}}`, "oneArg=joe", tVal, true}, + {"testFunc .", `{{oneArg .}}`, "oneArg=joe", "joe", true}, +} + +// These strings are also in testdata/*. +const multiText1 = ` + {{define "x"}}TEXT{{end}} + {{define "dotV"}}{{.V}}{{end}} +` + +const multiText2 = ` + {{define "dot"}}{{.}}{{end}} + {{define "nested"}}{{template "dot" .}}{{end}} +` + +func TestMultiExecute(t *testing.T) { + // Declare a couple of templates first. + template, err := New("root").Parse(multiText1) + if err != nil { + t.Fatalf("parse error for 1: %s", err) + } + _, err = template.Parse(multiText2) + if err != nil { + t.Fatalf("parse error for 2: %s", err) + } + testExecute(multiExecTests, template, t) +} + +func TestParseFiles(t *testing.T) { + _, err := ParseFiles("DOES NOT EXIST") + if err == nil { + t.Error("expected error for non-existent file; got none") + } + template := New("root") + _, err = template.ParseFiles("testdata/file1.tmpl", "testdata/file2.tmpl") + if err != nil { + t.Fatalf("error parsing files: %v", err) + } + testExecute(multiExecTests, template, t) +} + +func TestParseGlob(t *testing.T) { + _, err := ParseGlob("DOES NOT EXIST") + if err == nil { + t.Error("expected error for non-existent file; got none") + } + _, err = New("error").ParseGlob("[x") + if err == nil { + t.Error("expected error for bad pattern; got none") + } + template := New("root") + _, err = template.ParseGlob("testdata/file*.tmpl") + if err != nil { + t.Fatalf("error parsing files: %v", err) + } + testExecute(multiExecTests, template, t) +} + +// In these tests, actual content (not just template definitions) comes from the parsed files. + +var templateFileExecTests = []execTest{ + {"test", `{{template "tmpl1.tmpl"}}{{template "tmpl2.tmpl"}}`, "template1\n\ny\ntemplate2\n\nx\n", 0, true}, +} + +func TestParseFilesWithData(t *testing.T) { + template, err := New("root").ParseFiles("testdata/tmpl1.tmpl", "testdata/tmpl2.tmpl") + if err != nil { + t.Fatalf("error parsing files: %v", err) + } + testExecute(templateFileExecTests, template, t) +} + +func TestParseGlobWithData(t *testing.T) { + template, err := New("root").ParseGlob("testdata/tmpl*.tmpl") + if err != nil { + t.Fatalf("error parsing files: %v", err) + } + testExecute(templateFileExecTests, template, t) +} + +const ( + cloneText1 = `{{define "a"}}{{template "b"}}{{template "c"}}{{end}}` + cloneText2 = `{{define "b"}}b{{end}}` + cloneText3 = `{{define "c"}}root{{end}}` + cloneText4 = `{{define "c"}}clone{{end}}` +) + +// Issue 7032 +func TestAddParseTreeToUnparsedTemplate(t *testing.T) { + master := "{{define \"master\"}}{{end}}" + tmpl := New("master") + tree, err := parse.Parse("master", master, "", "", nil) + if err != nil { + t.Fatalf("unexpected parse err: %v", err) + } + masterTree := tree["master"] + tmpl.AddParseTree("master", masterTree) // used to panic +} + +func TestRedefinition(t *testing.T) { + var tmpl *Template + var err error + if tmpl, err = New("tmpl1").Parse(`{{define "test"}}foo{{end}}`); err != nil { + t.Fatalf("parse 1: %v", err) + } + if _, err = tmpl.Parse(`{{define "test"}}bar{{end}}`); err != nil { + t.Fatalf("got error %v, expected nil", err) + } + if _, err = tmpl.New("tmpl2").Parse(`{{define "test"}}bar{{end}}`); err != nil { + t.Fatalf("got error %v, expected nil", err) + } +} + +// Issue 10879 +func TestEmptyTemplateCloneCrash(t *testing.T) { + t1 := New("base") + t1.Clone() // used to panic +} + +// Issue 10910, 10926 +func TestTemplateLookUp(t *testing.T) { + t.Skip("broken on html/template") // TODO + t1 := New("foo") + if t1.Lookup("foo") != nil { + t.Error("Lookup returned non-nil value for undefined template foo") + } + t1.New("bar") + if t1.Lookup("bar") != nil { + t.Error("Lookup returned non-nil value for undefined template bar") + } + t1.Parse(`{{define "foo"}}test{{end}}`) + if t1.Lookup("foo") == nil { + t.Error("Lookup returned nil value for defined template") + } +} + +func TestParse(t *testing.T) { + // In multiple calls to Parse with the same receiver template, only one call + // can contain text other than space, comments, and template definitions + t1 := New("test") + if _, err := t1.Parse(`{{define "test"}}{{end}}`); err != nil { + t.Fatalf("parsing test: %s", err) + } + if _, err := t1.Parse(`{{define "test"}}{{/* this is a comment */}}{{end}}`); err != nil { + t.Fatalf("parsing test: %s", err) + } + if _, err := t1.Parse(`{{define "test"}}foo{{end}}`); err != nil { + t.Fatalf("parsing test: %s", err) + } +} + +func TestEmptyTemplate(t *testing.T) { + cases := []struct { + defn []string + in string + want string + }{ + {[]string{"x", "y"}, "", "y"}, + {[]string{""}, "once", ""}, + {[]string{"", ""}, "twice", ""}, + {[]string{"{{.}}", "{{.}}"}, "twice", "twice"}, + {[]string{"{{/* a comment */}}", "{{/* a comment */}}"}, "comment", ""}, + {[]string{"{{.}}", ""}, "twice", "twice"}, // TODO: should want "" not "twice" + } + + for i, c := range cases { + root := New("root") + + var ( + m *Template + err error + ) + for _, d := range c.defn { + m, err = root.New(c.in).Parse(d) + if err != nil { + t.Fatal(err) + } + } + buf := &bytes.Buffer{} + if err := m.Execute(buf, c.in); err != nil { + t.Error(i, err) + continue + } + if buf.String() != c.want { + t.Errorf("expected string %q: got %q", c.want, buf.String()) + } + } +} + +// Issue 19249 was a regression in 1.8 caused by the handling of empty +// templates added in that release, which got different answers depending +// on the order templates appeared in the internal map. +func TestIssue19294(t *testing.T) { + // The empty block in "xhtml" should be replaced during execution + // by the contents of "stylesheet", but if the internal map associating + // names with templates is built in the wrong order, the empty block + // looks non-empty and this doesn't happen. + var inlined = map[string]string{ + "stylesheet": `{{define "stylesheet"}}stylesheet{{end}}`, + "xhtml": `{{block "stylesheet" .}}{{end}}`, + } + all := []string{"stylesheet", "xhtml"} + for i := 0; i < 100; i++ { + res, err := New("title.xhtml").Parse(`{{template "xhtml" .}}`) + if err != nil { + t.Fatal(err) + } + for _, name := range all { + _, err := res.New(name).Parse(inlined[name]) + if err != nil { + t.Fatal(err) + } + } + var buf bytes.Buffer + res.Execute(&buf, 0) + if buf.String() != "stylesheet" { + t.Fatalf("iteration %d: got %q; expected %q", i, buf.String(), "stylesheet") + } + } +} diff --git a/libgo/go/html/template/template_test.go b/libgo/go/html/template/template_test.go index 13e6ba406e1..86bd4db444d 100644 --- a/libgo/go/html/template/template_test.go +++ b/libgo/go/html/template/template_test.go @@ -6,6 +6,7 @@ package template_test import ( "bytes" + "encoding/json" . "html/template" "strings" "testing" @@ -121,6 +122,44 @@ func TestNumbers(t *testing.T) { c.mustExecute(c.root, nil, "12.34 7.5") } +func TestStringsInScriptsWithJsonContentTypeAreCorrectlyEscaped(t *testing.T) { + // See #33671 and #37634 for more context on this. + tests := []struct{ name, in string }{ + {"empty", ""}, + {"invalid", string(rune(-1))}, + {"null", "\u0000"}, + {"unit separator", "\u001F"}, + {"tab", "\t"}, + {"gt and lt", "<>"}, + {"quotes", `'"`}, + {"ASCII letters", "ASCII letters"}, + {"Unicode", "ʕ⊙ϖ⊙ʔ"}, + {"Pizza", "🍕"}, + } + const ( + prefix = `` + templ = prefix + `"{{.}}"` + suffix + ) + tpl := Must(New("JS string is JSON string").Parse(templ)) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var buf bytes.Buffer + if err := tpl.Execute(&buf, tt.in); err != nil { + t.Fatalf("Cannot render template: %v", err) + } + trimmed := bytes.TrimSuffix(bytes.TrimPrefix(buf.Bytes(), []byte(prefix)), []byte(suffix)) + var got string + if err := json.Unmarshal(trimmed, &got); err != nil { + t.Fatalf("Cannot parse JS string %q as JSON: %v", trimmed[1:len(trimmed)-1], err) + } + if got != tt.in { + t.Errorf("Serialization changed the string value: got %q want %q", got, tt.in) + } + }) + } +} + type testCase struct { t *testing.T root *Template diff --git a/libgo/go/html/template/testdata/file1.tmpl b/libgo/go/html/template/testdata/file1.tmpl new file mode 100644 index 00000000000..febf9d9f89d --- /dev/null +++ b/libgo/go/html/template/testdata/file1.tmpl @@ -0,0 +1,2 @@ +{{define "x"}}TEXT{{end}} +{{define "dotV"}}{{.V}}{{end}} diff --git a/libgo/go/html/template/testdata/file2.tmpl b/libgo/go/html/template/testdata/file2.tmpl new file mode 100644 index 00000000000..39bf6fb9eef --- /dev/null +++ b/libgo/go/html/template/testdata/file2.tmpl @@ -0,0 +1,2 @@ +{{define "dot"}}{{.}}{{end}} +{{define "nested"}}{{template "dot" .}}{{end}} diff --git a/libgo/go/html/template/testdata/tmpl1.tmpl b/libgo/go/html/template/testdata/tmpl1.tmpl new file mode 100644 index 00000000000..b72b3a340c7 --- /dev/null +++ b/libgo/go/html/template/testdata/tmpl1.tmpl @@ -0,0 +1,3 @@ +template1 +{{define "x"}}x{{end}} +{{template "y"}} diff --git a/libgo/go/html/template/testdata/tmpl2.tmpl b/libgo/go/html/template/testdata/tmpl2.tmpl new file mode 100644 index 00000000000..16beba6e7dd --- /dev/null +++ b/libgo/go/html/template/testdata/tmpl2.tmpl @@ -0,0 +1,3 @@ +template2 +{{define "y"}}y{{end}} +{{template "x"}} diff --git a/libgo/go/image/draw/bench_test.go b/libgo/go/image/draw/bench_test.go index a41d7e7dfb7..831fd958ba3 100644 --- a/libgo/go/image/draw/bench_test.go +++ b/libgo/go/image/draw/bench_test.go @@ -236,7 +236,11 @@ func BenchmarkRGBA(b *testing.B) { bench(b, color.RGBAModel, color.RGBA64Model, nil, Src) } -func BenchmarkPaletted(b *testing.B) { +func BenchmarkPalettedFill(b *testing.B) { + bench(b, palette, nil, nil, Src) +} + +func BenchmarkPalettedRGBA(b *testing.B) { bench(b, palette, color.RGBAModel, nil, Src) } diff --git a/libgo/go/image/draw/draw.go b/libgo/go/image/draw/draw.go index 932a5444831..8f96aa2d180 100644 --- a/libgo/go/image/draw/draw.go +++ b/libgo/go/image/draw/draw.go @@ -180,9 +180,25 @@ func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point, mas drawRGBA(dst0, r, src, sp, mask, mp, op) return case *image.Paletted: - if op == Src && mask == nil && !processBackward(dst, r, src, sp) { - drawPaletted(dst0, r, src, sp, false) - return + if op == Src && mask == nil { + if src0, ok := src.(*image.Uniform); ok { + colorIndex := uint8(dst0.Palette.Index(src0.C)) + i0 := dst0.PixOffset(r.Min.X, r.Min.Y) + i1 := i0 + r.Dx() + for i := i0; i < i1; i++ { + dst0.Pix[i] = colorIndex + } + firstRow := dst0.Pix[i0:i1] + for y := r.Min.Y + 1; y < r.Max.Y; y++ { + i0 += dst0.Stride + i1 += dst0.Stride + copy(dst0.Pix[i0:i1], firstRow) + } + return + } else if !processBackward(dst, r, src, sp) { + drawPaletted(dst0, r, src, sp, false) + return + } } } diff --git a/libgo/go/image/draw/draw_test.go b/libgo/go/image/draw/draw_test.go index dea51b6bc50..9c5a118400e 100644 --- a/libgo/go/image/draw/draw_test.go +++ b/libgo/go/image/draw/draw_test.go @@ -434,11 +434,11 @@ func TestPaletted(t *testing.T) { t.Fatalf("open: %v", err) } defer f.Close() - src, err := png.Decode(f) + video001, err := png.Decode(f) if err != nil { t.Fatalf("decode: %v", err) } - b := src.Bounds() + b := video001.Bounds() cgaPalette := color.Palette{ color.RGBA{0x00, 0x00, 0x00, 0xff}, @@ -450,19 +450,25 @@ func TestPaletted(t *testing.T) { "src": Src, "floyd-steinberg": FloydSteinberg, } + sources := map[string]image.Image{ + "uniform": &image.Uniform{color.RGBA{0xff, 0x7f, 0xff, 0xff}}, + "video001": video001, + } -loop: for dName, d := range drawers { - dst0 := image.NewPaletted(b, cgaPalette) - dst1 := image.NewPaletted(b, cgaPalette) - d.Draw(dst0, b, src, image.Point{}) - d.Draw(embeddedPaletted{dst1}, b, src, image.Point{}) - for y := b.Min.Y; y < b.Max.Y; y++ { - for x := b.Min.X; x < b.Max.X; x++ { - if !eq(dst0.At(x, y), dst1.At(x, y)) { - t.Errorf("%s: at (%d, %d), %v versus %v", - dName, x, y, dst0.At(x, y), dst1.At(x, y)) - continue loop + loop: + for sName, src := range sources { + dst0 := image.NewPaletted(b, cgaPalette) + dst1 := image.NewPaletted(b, cgaPalette) + d.Draw(dst0, b, src, image.Point{}) + d.Draw(embeddedPaletted{dst1}, b, src, image.Point{}) + for y := b.Min.Y; y < b.Max.Y; y++ { + for x := b.Min.X; x < b.Max.X; x++ { + if !eq(dst0.At(x, y), dst1.At(x, y)) { + t.Errorf("%s / %s: at (%d, %d), %v versus %v", + dName, sName, x, y, dst0.At(x, y), dst1.At(x, y)) + continue loop + } } } } diff --git a/libgo/go/image/geom.go b/libgo/go/image/geom.go index 8bb249c1e09..78e9e49d4f6 100644 --- a/libgo/go/image/geom.go +++ b/libgo/go/image/geom.go @@ -6,6 +6,7 @@ package image import ( "image/color" + "math/bits" "strconv" ) @@ -272,3 +273,37 @@ func Rect(x0, y0, x1, y1 int) Rectangle { } return Rectangle{Point{x0, y0}, Point{x1, y1}} } + +// mul3NonNeg returns (x * y * z), unless at least one argument is negative or +// if the computation overflows the int type, in which case it returns -1. +func mul3NonNeg(x int, y int, z int) int { + if (x < 0) || (y < 0) || (z < 0) { + return -1 + } + hi, lo := bits.Mul64(uint64(x), uint64(y)) + if hi != 0 { + return -1 + } + hi, lo = bits.Mul64(lo, uint64(z)) + if hi != 0 { + return -1 + } + a := int(lo) + if (a < 0) || (uint64(a) != lo) { + return -1 + } + return a +} + +// add2NonNeg returns (x + y), unless at least one argument is negative or if +// the computation overflows the int type, in which case it returns -1. +func add2NonNeg(x int, y int) int { + if (x < 0) || (y < 0) { + return -1 + } + a := x + y + if a < 0 { + return -1 + } + return a +} diff --git a/libgo/go/image/gif/writer_test.go b/libgo/go/image/gif/writer_test.go index b619961787d..9b15c8d99d4 100644 --- a/libgo/go/image/gif/writer_test.go +++ b/libgo/go/image/gif/writer_test.go @@ -657,7 +657,6 @@ func TestEncodeWrappedImage(t *testing.T) { } func BenchmarkEncode(b *testing.B) { - bo := image.Rect(0, 0, 640, 480) rnd := rand.New(rand.NewSource(123)) // Restrict to a 256-color paletted image to avoid quantization path. @@ -671,10 +670,8 @@ func BenchmarkEncode(b *testing.B) { } } img := image.NewPaletted(image.Rect(0, 0, 640, 480), palette) - for y := bo.Min.Y; y < bo.Max.Y; y++ { - for x := bo.Min.X; x < bo.Max.X; x++ { - img.Set(x, y, palette[rnd.Intn(256)]) - } + for i := range img.Pix { + img.Pix[i] = uint8(rnd.Intn(256)) } b.SetBytes(640 * 480 * 4) diff --git a/libgo/go/image/image.go b/libgo/go/image/image.go index ffd6de73837..8adba96ab6e 100644 --- a/libgo/go/image/image.go +++ b/libgo/go/image/image.go @@ -56,6 +56,21 @@ type PalettedImage interface { Image } +// pixelBufferLength returns the length of the []uint8 typed Pix slice field +// for the NewXxx functions. Conceptually, this is just (bpp * width * height), +// but this function panics if at least one of those is negative or if the +// computation would overflow the int type. +// +// This panics instead of returning an error because of backwards +// compatibility. The NewXxx functions do not return an error. +func pixelBufferLength(bytesPerPixel int, r Rectangle, imageTypeName string) int { + totalLength := mul3NonNeg(bytesPerPixel, r.Dx(), r.Dy()) + if totalLength < 0 { + panic("image: New" + imageTypeName + " Rectangle has huge or negative dimensions") + } + return totalLength +} + // RGBA is an in-memory image whose At method returns color.RGBA values. type RGBA struct { // Pix holds the image's pixels, in R, G, B, A order. The pixel at @@ -153,9 +168,11 @@ func (p *RGBA) Opaque() bool { // NewRGBA returns a new RGBA image with the given bounds. func NewRGBA(r Rectangle) *RGBA { - w, h := r.Dx(), r.Dy() - buf := make([]uint8, 4*w*h) - return &RGBA{buf, 4 * w, r} + return &RGBA{ + Pix: make([]uint8, pixelBufferLength(4, r, "RGBA")), + Stride: 4 * r.Dx(), + Rect: r, + } } // RGBA64 is an in-memory image whose At method returns color.RGBA64 values. @@ -268,9 +285,11 @@ func (p *RGBA64) Opaque() bool { // NewRGBA64 returns a new RGBA64 image with the given bounds. func NewRGBA64(r Rectangle) *RGBA64 { - w, h := r.Dx(), r.Dy() - pix := make([]uint8, 8*w*h) - return &RGBA64{pix, 8 * w, r} + return &RGBA64{ + Pix: make([]uint8, pixelBufferLength(8, r, "RGBA64")), + Stride: 8 * r.Dx(), + Rect: r, + } } // NRGBA is an in-memory image whose At method returns color.NRGBA values. @@ -370,9 +389,11 @@ func (p *NRGBA) Opaque() bool { // NewNRGBA returns a new NRGBA image with the given bounds. func NewNRGBA(r Rectangle) *NRGBA { - w, h := r.Dx(), r.Dy() - pix := make([]uint8, 4*w*h) - return &NRGBA{pix, 4 * w, r} + return &NRGBA{ + Pix: make([]uint8, pixelBufferLength(4, r, "NRGBA")), + Stride: 4 * r.Dx(), + Rect: r, + } } // NRGBA64 is an in-memory image whose At method returns color.NRGBA64 values. @@ -485,9 +506,11 @@ func (p *NRGBA64) Opaque() bool { // NewNRGBA64 returns a new NRGBA64 image with the given bounds. func NewNRGBA64(r Rectangle) *NRGBA64 { - w, h := r.Dx(), r.Dy() - pix := make([]uint8, 8*w*h) - return &NRGBA64{pix, 8 * w, r} + return &NRGBA64{ + Pix: make([]uint8, pixelBufferLength(8, r, "NRGBA64")), + Stride: 8 * r.Dx(), + Rect: r, + } } // Alpha is an in-memory image whose At method returns color.Alpha values. @@ -577,9 +600,11 @@ func (p *Alpha) Opaque() bool { // NewAlpha returns a new Alpha image with the given bounds. func NewAlpha(r Rectangle) *Alpha { - w, h := r.Dx(), r.Dy() - pix := make([]uint8, 1*w*h) - return &Alpha{pix, 1 * w, r} + return &Alpha{ + Pix: make([]uint8, pixelBufferLength(1, r, "Alpha")), + Stride: 1 * r.Dx(), + Rect: r, + } } // Alpha16 is an in-memory image whose At method returns color.Alpha16 values. @@ -672,9 +697,11 @@ func (p *Alpha16) Opaque() bool { // NewAlpha16 returns a new Alpha16 image with the given bounds. func NewAlpha16(r Rectangle) *Alpha16 { - w, h := r.Dx(), r.Dy() - pix := make([]uint8, 2*w*h) - return &Alpha16{pix, 2 * w, r} + return &Alpha16{ + Pix: make([]uint8, pixelBufferLength(2, r, "Alpha16")), + Stride: 2 * r.Dx(), + Rect: r, + } } // Gray is an in-memory image whose At method returns color.Gray values. @@ -751,9 +778,11 @@ func (p *Gray) Opaque() bool { // NewGray returns a new Gray image with the given bounds. func NewGray(r Rectangle) *Gray { - w, h := r.Dx(), r.Dy() - pix := make([]uint8, 1*w*h) - return &Gray{pix, 1 * w, r} + return &Gray{ + Pix: make([]uint8, pixelBufferLength(1, r, "Gray")), + Stride: 1 * r.Dx(), + Rect: r, + } } // Gray16 is an in-memory image whose At method returns color.Gray16 values. @@ -833,9 +862,11 @@ func (p *Gray16) Opaque() bool { // NewGray16 returns a new Gray16 image with the given bounds. func NewGray16(r Rectangle) *Gray16 { - w, h := r.Dx(), r.Dy() - pix := make([]uint8, 2*w*h) - return &Gray16{pix, 2 * w, r} + return &Gray16{ + Pix: make([]uint8, pixelBufferLength(2, r, "Gray16")), + Stride: 2 * r.Dx(), + Rect: r, + } } // CMYK is an in-memory image whose At method returns color.CMYK values. @@ -922,9 +953,11 @@ func (p *CMYK) Opaque() bool { // NewCMYK returns a new CMYK image with the given bounds. func NewCMYK(r Rectangle) *CMYK { - w, h := r.Dx(), r.Dy() - buf := make([]uint8, 4*w*h) - return &CMYK{buf, 4 * w, r} + return &CMYK{ + Pix: make([]uint8, pixelBufferLength(4, r, "CMYK")), + Stride: 4 * r.Dx(), + Rect: r, + } } // Paletted is an in-memory image of uint8 indices into a given palette. @@ -1032,7 +1065,10 @@ func (p *Paletted) Opaque() bool { // NewPaletted returns a new Paletted image with the given width, height and // palette. func NewPaletted(r Rectangle, p color.Palette) *Paletted { - w, h := r.Dx(), r.Dy() - pix := make([]uint8, 1*w*h) - return &Paletted{pix, 1 * w, r, p} + return &Paletted{ + Pix: make([]uint8, pixelBufferLength(1, r, "Paletted")), + Stride: 1 * r.Dx(), + Rect: r, + Palette: p, + } } diff --git a/libgo/go/image/image_test.go b/libgo/go/image/image_test.go index dfd8eb35a80..b9b9bfaa28c 100644 --- a/libgo/go/image/image_test.go +++ b/libgo/go/image/image_test.go @@ -88,6 +88,78 @@ func TestImage(t *testing.T) { } } +func TestNewXxxBadRectangle(t *testing.T) { + // call calls f(r) and reports whether it ran without panicking. + call := func(f func(Rectangle), r Rectangle) (ok bool) { + defer func() { + if recover() != nil { + ok = false + } + }() + f(r) + return true + } + + testCases := []struct { + name string + f func(Rectangle) + }{ + {"RGBA", func(r Rectangle) { NewRGBA(r) }}, + {"RGBA64", func(r Rectangle) { NewRGBA64(r) }}, + {"NRGBA", func(r Rectangle) { NewNRGBA(r) }}, + {"NRGBA64", func(r Rectangle) { NewNRGBA64(r) }}, + {"Alpha", func(r Rectangle) { NewAlpha(r) }}, + {"Alpha16", func(r Rectangle) { NewAlpha16(r) }}, + {"Gray", func(r Rectangle) { NewGray(r) }}, + {"Gray16", func(r Rectangle) { NewGray16(r) }}, + {"CMYK", func(r Rectangle) { NewCMYK(r) }}, + {"Paletted", func(r Rectangle) { NewPaletted(r, color.Palette{color.Black, color.White}) }}, + {"YCbCr", func(r Rectangle) { NewYCbCr(r, YCbCrSubsampleRatio422) }}, + {"NYCbCrA", func(r Rectangle) { NewNYCbCrA(r, YCbCrSubsampleRatio444) }}, + } + + for _, tc := range testCases { + // Calling NewXxx(r) should fail (panic, since NewXxx doesn't return an + // error) unless r's width and height are both non-negative. + for _, negDx := range []bool{false, true} { + for _, negDy := range []bool{false, true} { + r := Rectangle{ + Min: Point{15, 28}, + Max: Point{16, 29}, + } + if negDx { + r.Max.X = 14 + } + if negDy { + r.Max.Y = 27 + } + + got := call(tc.f, r) + want := !negDx && !negDy + if got != want { + t.Errorf("New%s: negDx=%t, negDy=%t: got %t, want %t", + tc.name, negDx, negDy, got, want) + } + } + } + + // Passing a Rectangle whose width and height is MaxInt should also fail + // (panic), due to overflow. + { + zeroAsUint := uint(0) + maxUint := zeroAsUint - 1 + maxInt := int(maxUint / 2) + got := call(tc.f, Rectangle{ + Min: Point{0, 0}, + Max: Point{maxInt, maxInt}, + }) + if got { + t.Errorf("New%s: overflow: got ok, want !ok", tc.name) + } + } + } +} + func Test16BitsPerColorChannel(t *testing.T) { testColorModel := []color.Model{ color.RGBA64Model, diff --git a/libgo/go/image/jpeg/reader_test.go b/libgo/go/image/jpeg/reader_test.go index a62b509234e..1e2798c9457 100644 --- a/libgo/go/image/jpeg/reader_test.go +++ b/libgo/go/image/jpeg/reader_test.go @@ -6,6 +6,7 @@ package jpeg import ( "bytes" + "encoding/base64" "fmt" "image" "image/color" @@ -262,6 +263,175 @@ func TestLargeImageWithShortData(t *testing.T) { } } +func TestPaddedRSTMarker(t *testing.T) { + // This test image comes from golang.org/issue/28717 + const base64EncodedImage = ` +/9j/4AAhQVZJMQABAQEAeAB4AAAAAAAAAAAAAAAAAAAAAAAAAP/bAEMABAIDAwMCBAMDAwQEBAQGCgYG +BQUGDAgJBwoODA8PDgwODxASFxMQERURDQ4UGhQVFxgZGhkPExweHBkeFxkZGP/bAEMBBAQEBgUGCwYG +CxgQDhAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGP/EAaIA +AAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKCxAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1Fh +ByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNk +ZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT +1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6AQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgsRAAIB +AgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBka +JicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZ +mqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/dAAQA +Cv/gAAQAAP/AABEIALABQAMBIQACEQEDEQH/2gAMAwEAAhEDEQA/APnCFTk5BPPGKliAB718W7H2j3Ip +VUuwJxzTfKXacde9VBhYRUBAyO3pTmUAbSMU5WGmybywzHGAMdelPVFC+n1qXZCuyaJADxjj2qzbBMAP +xz1rKaVib6ltLcFvlIx2pLy0dwuAMMBnH1rFON9RNsszAZPFEYHldPzrOy3KewmBk9qUABugxjtTVmiW +xWRcjp+VJtHXgVL3K6AgBDdM9eRTNzAZViOe1VyxaJavuf/Q8aW4mUcSGpo764AyHz+FfnnJBvVH1UsN +CS1Q/wDte4Trip49ecA7g3FSqMW9zlqZandxJ4/EKADcSPqKni8QQMT865qOSUNjiqZdNbFiHWYXz84N +WE1KNsfMKj2zirHHPDSj0JFvo2H36d9pUjg1sqykYOm0KbgY60omXPXmr9pFkco3zBnrQzjGcnrRzp9S +bEbuOvao3fisZSXUpIYWGKGcbetTCSswsxnmACkYrtNSpJ2YNM//0fnK1BD7sDg9KmUHeOe/Svid3qfb +SdmQ3AHmnr1pGBC5z19a0hohNiJkensM1J0yCKmY0yZR82e+BT1BxnpmpepN9SRCR0NSpweOoPWs6isr +ijuWIZGBA/lVwzMVFY8ibuhXEfr+tOz8hIqUymhRnJGTSc5wBVRRDFPXBHJpB3qdmV0EX7vXmoyfl685 +p2dxWR//0vFsHZ9TQv3T618Bqz7PSwwn1phPXpSWrQEUhIx0NVXc7j0rSNwViCS4dWYpJj3BpBqVzGy7 +ZmHSq9kpblSpxkveQ+PX7uMf6wEDtU0fi24TAkX8jTeCjJaaHDUwFN7aFq28aL/GCMGrtr4xtHGGkA+t +YTy+a+E82eAa2LsXiWzI5mXPHercOsW8hwJB+dcUqVSCOKVFxdmiwl7E2MOPzp4nQ9GH51jzNbmUoOIC +TI4okOaUXoybDCevNBPHX8qIO4mf/9P52i4dix5zjp/n1qZFBCmviL6an2kt9CGcYnJznJpOBwegq4vQ +L9xIUytSkfu/bv70p7j6EnQgjHSpFGVqXclkkaHb1+makUHgdazm7IFuSKOasrnjis2+oDm9qnIHlgd/ +es7gxqjkt1NLwH4xTTEhjkhutM3D15oGhkcnBGRTDKu3A7H1rS3cLn//1PEhJ8uM557UvmDaa/P7a3Ps +xpZcZ6mo5WG45pdUC2K8ko5JIzWfcTqu7HPHrW9OLbKWhSluVLNz3wKrS3I3KfcV1Rg9CrpXK8l0F7io +pLnLnJHGOldMYJGMpu5XNwuxjyRTBcAAjd1HWtfZmPORy3WAWWQDOM4PWtHRru6DFlmY88ZqKsVyXaKp +QjOoa7axe28G/cWqhoHjO/n1WeJwSkS9c981wUcFCopPayFj8JC8VFbs6e38VldvmHHFaMHimAoCzDB6 +V5U8FKz5TlrZU4/CXYtdtnXIarEepW7jAcfnXGqEoKx5tfBzh0P/1fnqEAsc/wB6pI9owAD1618Qn3Ps +35EE4UzHrx79aXaMcdaqAMWIADvj271IMeXg59KUmNLQkUDfjb1FSLxzg0pWJRLGAQAeMVIoA+uaxlaw +0SoF/u1KowwwDUcwuo9wMjrUrY2ZPOKy0KY1T1NMdwG/CtBEFzMqnIPNUZ75FBJP5mtIQvYfoU21JFVs +N271AurRE/e611xw73Yj/9b50GsQhOXHWnpq8JX7w4PWvjPq76H2fzHjVYCud9Q3GrRAZDUvq75kNbMz +7vV0zjdjNZ82pqzMcj7tdlPDtIiVWKKct+AxwRxUbXi7VPJAIrZUdEZOsrsga8DFgelQtd98g5P6V0Qp +GE6qIUut2cZ470kd2FjYc4Oce1bSpJ3Rzxq21GNcDZhSeg710ujKRbKzAg5rkxceWnqd+XtOo7bD9cl8 +qxLDPHasXwUvmyXU7Lgl8cegrnw2lGbZ14l3rU0bl3gMQCRgVU1y7WytUZQzMRwBXPRhzWRvVny3ZW8N +6xPdXBikiZc5IOa6GG6nDsd5xnAyfaliqEacrGOHarx5pI//1/nuL754HWngEkYx1r4VWsfaMjk4mP8A +OgnjPH1rRMLKwR4A2jH1FPA+TNRIa0ROvQcY4p4GF/pUskmi6+gqRACvPrWMnpca3JABjFSKCQOnFS2u +o7E3XBOKcR8ucdKzUkDGSHGemKpXchVuP0rSmDMfUrl1J5rn9TvnVCc9OtelhoJtDekW0Yb6pId3zdRw +RVT+0pAPvc57CvbhQVrHlTxD3P8A/9D4tbUpTH1I7cU/7ZdMnyqcdsV5vsErXPbWJbHLdXzYQDBY8c02 +6udQjyGVuD1FHsqfMridepZ6ED3s4IDqeD0I68VEt7J5hy3GO9aKkuhPt2BumeRjnv3pJLlgwBYE8ZqH +T2GqujYLcuWYbhj0zTHm5B/vcGtVBLYzdRtEcUueoGB3FOjmBjcBhx2NNx1IhO+uwtqd93EgA5YcV32n +IqwrnAz2rzMx+FI9nKldy+RmeMpfLs8DGTxTvBUKw6Csjry2WPbrXHB2wzfdnbUu8SvJF4xh1LDAJNU9 +UtVmDs3IiGB6CuenNx1R0yjfRGd4aRTqJdFG1ARXRgANg4/yK0xbvJehnhlaL9T/AP/R+e4x8xx609F+ +YZ718L6n2ju2RzqTKcYpQMjsc1pHTQWlgjUjGVH0qbkr0BqJSKRMi+uBx3p8a5HYVD8yb32JY15FSKpx +nisp6RuNbj1BzUyrnkmo6FEqrz7U/advHOazvcRHIuSazNXDpbSSJjeqErnpmrp6CueeXusahO5zKi8c +7VrPuGklUiSQtkd6+po0YQs0edVrTd1cqeSoJOB0xUCxpnouAecV33e558rbH//S+KdmFHTk1btywUqc +YNcEnfc9SGl7DyAJ1AHIParx+YZ4/Guea2OmC1dhGjQn5kXNQtbQFiWiTlfSoTa2G0nuU5bG2aQ7V2jP +JU+1RSaXC2GjuApyOorX2slYz9lF3sV/7MmViFljaoJLG6SQbkyDXQqiZzyg1Yg8i4jBJjIBpsaPyXXB +Psea1TTMJJqysaeh2u/UUfP3QCBXdQJtTpivFzKV3FH0WURtCT8zmPHcrhkRSOWro7O28rRYIgOwGB3r +mnph4+bOxNvEy8kWFi+ULxwKzNRkMemSPj/WMT+FckNWdLv0KPhCMmGSZl6k1ulC3zY5x2+la4r+IyKH +wH//0/nuIHB9c9KevUAHk18La60PtHuRy/64+lOGBniqXcOlhUIxwB+NSrynSpndFImQc4A7d6lQccdR +WcyUyWMccDnPSpVAwM1nLYaeo5BjrUyjFTugJIwd2Kfgkc59qyTs7Axkigqao3qBkYdiMVpTeugHmF7b +hbhl2/dJB/OofJBTHfp9K+ppTbimeZOK5issYG5W7VWdBnHXB65rrjJs5JLof//U+LYtu7leM+lSpxIR +7VwO90eskrNkqZLo3PXHoausxI4wa557o2p6JitnOCoqvI3zEkdF5qIrUuW2ogO1iWHeibazIQncHA+l +DT0aCyaaZGNm8kA9PSl2qy9SB78Veq1ZCs9BkOGUrj86zdQGbllVMAe1bQdpGE1eBo+FoCbgtxkY966+ +E4hOeo5rycxleR72VwcaRx+t/wCmeJ7WAdDIOPpzXbSpt/dkcRr+tZ4j3aVNLzNKOteo/QjuiY7Jm6Ej +ANYnitvL05YRxwOf8/WuXDK8l6nVUlaLZb8NQeXpijgZB/M1oIpyPzx74pV2nUbHTVoJH//V+fYhgnnv +Txy4GBXwse59m7kMyEzkj8qkQfKatdgewIo7nIqdQAnXms52RSehMoHHPapY1wMAgVnKzFtqSwjjg4qR +VJHXIzWc2rDiPVeeD+FSDqKh2sBKo54p+Pl61jbQG9RrDIPNU7teT6VpCztYDzfxGskWtXESdN5Pp15q +gN2GZpB0r6ig17OL8jz535miCSPdnaxHHpVV48D7xIB7iu2LOOS7H//W+MCoeIDcc5p4VhIMDkDvXnpq ++p6zu0SwZZlVm6HJFWyRg89MdawmkmrG1NtpiMcY5OevFQ7AWOT0FSkkU9UKUPmEh8jt+VMdGLDLYAIz +xUtrQfLo7Mj2SHjePrSspxgEk1rdGSTGJjymLEZArOjAd5GLHk9DW0NGznqa8qOj8IRHBbrnnmugu08u +1ZiSMn868LGz/eH1GAVqKOW8LR/bfG4c8rCCx46HpXZspk88jHzMf04pY7eEfIjDO7nLz/yKmqh/sjwR +EFwAemcVhamkmpTRxKpyCN2RWeFsveZ01FpbubsEaRWyqhAxnH5YpxIx8rf/AFuK5W3Jts2Wisf/1/n5 +SSxHOM+lP7jGa+EVz7R2IpATN1IIpwB55NaJ2FuhYzx3PvU69OQaio7sEiZOvfpU0YwmMVnJ26DRJH2G +DipUyR361jN6FIeq8/0qUdBxWbkCRIg/D6U8j5e9Rza3ExrA8nmqt0Dkmri9BnnfjlSmvuwGQyhulYkr +yL86DANfTYRp0o3PPr3UnYbBOWU4zz7VHIGIJVjkGu1x5Tl5ro//0Pi3fhgMHJPXFWCeQwLe9ec+jPXj +1JIM7gw44qy+WPUjkcVjPdGsNmgdsNkjJFQ7mMhAB5FRHuXJ6WRIw+VwCc9KbtPy5JyCKgdmxhBDNj8s +U1Cyr0J/rWultDOzTuMuSiWjlT97r7HFZ1nkk4bIPXiuiD3uc00rqzOy8Lw+XBuJPQcGrXiGYJYMwJHB +xXz1d89U+sw8eWmkuxi/DGP/AEm+vHycYUE/jXXu6w2vzdcfiaMw1qpLsjnwi/dt+bKCn5nlw2W5Gacw +GD2wB+dcq2O4AnyADoM80QLukUsp9f0qb6XHuf/R+fkOWNSfwjnivhUz7Nq2hFJ/retPA4PWrWuwul2L +FjAA6VMMFeTms5PUpbEw6/hxUyfd4as5PUETRds9KlA+Xk96ym9FcaHJgGpOv1rPUpIkXg8mnNnGaz5r +aCaEPeqtx1OT0rSL2sC1OG+ISquoQuT1UjP4/wD16wGEZUYGPevo8E26UThrpc7G7ICDzg+1ROmF+91O +K7VKVrHNyxWx/9L4uuVAcH371JvKqScFPU1597pHqtWbZNZnc+QxI9atv8p4z9ayqPVI1pr3WyPBLDGf +qKYnExyeQKlFPQXH7zgdetSk8rgEnis29i0lqxijLEjjt1poU7iVHHpVX3uRbsZl+2IvLX+I56U/TUUA +KxGSfSulu0XY5oq80drpcZSzHvjpWd47fy9O2g8kjpXz0ZJ1kvM+skrUnbsSfDm1C+HlfJ/euXIPRq3b +lleQRYBCg5HrSxk+au/IxwkbUokRw0u0cBFyR70wEEbm6sc/gK5YuyZ1PzFVgVG4ZIzmpbTaJMt07+3F +Q9i7n//T+foic55yTipRkYBBxXwaPtXuRyZEg4pWII4qk7C6BFwAf51MhG31+lZ1Frca2LKHn8qlDY6L +UNgl1Jo+2akQ9BWVR9xpDgffrUq+wrO7tdDsSIPUUpPHvUK1xMM8HA61WmwWOB+NXENjiPiMhE1sw9WH +8q5vqRnjivosD/BXzOKv8QkKgZBA6ZpV27MkDOa7ObsYI//U+MdVGxlK9zninqd1sCQM45rzYaxR68vj +YtgT5h6jvV6Q5X0+lZ1n7yLofCxhOenfFMTI3cdRzWV9DWw5ARI3qPSnMSqKCOSRUy6FRurjFLjPp9KA +xx06n1q1qjO70Me6YtcOOcKcH1q9oqF5l75Oea6KtowOagnKol5neWcSJaocdgRzXGfEm53ERKfvEV89 +gvfxCPqcXLlw8/Q6fwkph0aCEg4VB/KrsDbmcnA4PWoxFnVkxUVaml5IgR9sMj4+ZzSTuTjcOB0/CsUt +zo0VrhCQiF2GcAn/AD+dWLRlYZPQ8cVEk7aF+p//1fAIuvfOakxnr+NfBJ2SsfaN6jJRiUA9RSheCMfn +VXEtgjUk/wBTVgfdBwOfSs5stbE6g7unYVLGpwAazYvUmjHHanqDx061lLazKuh6DHBFSID27VEthkin +5cUHOPxqLvqJiEYziq8/FaQ8hHH/ABEVvIhYYyHNcsrSZG5RyOtfQYC3slfzOPEX5tAA+amHIjO31ruu +rHNa7P8A/9b411QMIwSDnNR2xYQNkjnnkV5sLctj15JqRLZjBzweeSKuycHkD8qyq6tF0rqLI2OTnK5p +sGWbBHQd6zWxo3qSdXLYxTpPvLnvjrWdr2LvuNYYUnj6Uxyu4/KMrVx6ky6GOGLSOwXIYmr9n58UQeFg +svbcCRXTVty2ZzYZOVRcpvDW721tv9LsBIpAHmQNn9K4zxPqSX2sK6hljDDO6uHBYWKre0i9PxPTzDFS +VDkmtX9x2mm65YG0REnTccAc1rx3EJgbbIpyvUGuDE0JxleSO+hXhUj7rGK/7uNcj1P6UmSU+fHPJrlS +5bnXe9mA/wBSQDxzkfh/+qp7YbIipbaOufwrN7WLR//X8DTO7I9e9SJnAIHNfBPY+ze4yQEPnGacoHof +amvIELCDnnqanXoBzUSaRSRMo5J744qRBxzUSelwRPEMingdsVk7pFLckA5p44OTUXuh2HqOKRskE4qV +sKQADkYqvcj8aqD0shWOV8fqDYqc4w4rj5D365Fe7lz/AHdjlxC11CNhyRnp0pqkYOc9a9G/c5bLof/Q ++OdUH7sDnOeKrREgEN6V5tN+6exUT5rlm1IC9ec9qssBg5xzjNYzdpJmkNtRhJzgflSRDqD6flU7FkqZ +55+holblfUVk90aLYYxJH3agvGCQPkjJ6DFaw7GMtrmdYpkcg1q6fsEwB6Ct8Q73M8DpKLZruu+3ZM43 +ADNctfeHt120cEjO3U7scmuDCVvZNux7GLw31iNmypLoN5byByrYzzxVfzdTtXcxzSAD3r0oYinW0Z41 +TB1cPrBlyy8S6nF9+QOMba1LbxepwsyFcYztrnrZdCabgb0MzlCyqGrZ+IbK4U7bgDg8E4rXtL+CQBfM +VgTn9BXi1sJOno0e5SxVOqrxZ//R8DiGScip0HOAOa+CfkfaDJV+fpRjBIxT6iHRjnIHFTAYXBIqZ7lK +1rEygZxUsYI68Gsm7gkSQ59PwqZRxx681lK/LYaHpjI7U8ge1ZK3Qdxw5XpijAOelGoNCDPOOaguOf8A +CnFCOa8cJu0uTI6EHH41xLou3gYBr3culaLXmc2JV7DIx8pXHFNAxknGc16b0OM//9L44v8A/V5wMiqy +/dbI6j1rzKb0PYq7li2C4HHHrVmT5Rx9ayqN8yLppKIwEj6+lPhAGfzNQ9rmqexKvcAYxTTjeM88isty +xhI3mqWrNwqADB5ranozCo9GQaeBjByR1q2GIzjj2rasryMaErRVieK/kjwHbIGOBVrSbtZNRmlfAB+U +ZP0/wrinQsnKPY9eljVJqM9zYgMTMAjoRnoRUV3ptrMrl4UY+o4rzIzcHc9Nx5kZc/hu1lUlBszWPqHh +Z1lYxHJHQZr0cPmElpI87E5dCptoZl1o9zADuVhwfaqqz39tIPLeVMDoPpXqUqsKyPHr0KuGfun/0/Bo +Rzlh+lToOBXwGltD7RjJQcjtSqODn9RVLyEEY96nVflzis6l3YpaEigdscCpl5XqeKiaVgJIhn/61Sgc +AdOaylqkyluPXv7U8gZx/Koih9R+ML1ppHynIoRLEAqKYZ6njFVHRXBnP+Lk3aXN0yFz+tcM6j15r2cv +ejOfEdLjMDb94ZHaoyvy9O/Y16mqOQ//1PjfUcBcnjJ9KqggRldo579682krxPWqO0i1AM7c59OlWJMA +/lWVTdGtJaNiLg89afCMkjOOO1ZtGu5IpCs+emf6Uxug6Y45rO3UruiFmKydvrVK8ZZLogAn+ldNOPU5 +pvox1pH+7JzhumKlVfkOckmnNq5MI2SGScE5HTBqWDcBkMvJ6CpuraFWd+w3ULqW3gMsb4fOOO1VNP8A +FGoxsyy7JFA6kYNKGDp1Y+8aSzCrh5e7qjesPE9s8eJh5eRnIrShvbG7AMUqZ+teVVwU6TbWqPaw+OpV +0lezJWgV4yAVYc8GqV5pFpMMyW+O+V+lc1KtKD906q1KMlaR/9XwqPg9e9SqOQQetfnyfc+0Y2UfOKFy +B25q1K+grCx564FTL93rilMaRKvXtz7U9OnfrWbtbQdyaLoOtSr/AFrOSstCl2HLnPNP5z1qNEA9s4FM +7daSVhMAcZzTJlOD1prYDC8VoTpdzjP+rbH5V5w/nDkj9a9rK2mnc5sVeysQxmYMd4wDUkLM3LZFeu0u +hxan/9b44v8AG35cnnNVArKM+tefS+HU9WoveuizCQCBuOT61ZcnGcgmsZrVG1N3TGrk4x3qWBQGPUHF +RJspa7kjAFmwOp6Y9qSXPyDtkVgnsa9yFxhWYrj2rJUtJcFgB75rqpSvc5K0bWSRetV2Rg98c8d6UZCs +M8AZPNTLWTuVFWiiIgjcBnDY5NToCsZAyDnqKUrtJDitWUfETbYI1Ixz7ZNYkXyzMAMevHSuvDfCceK3 +NKGIG0Ppj73pVdi0F2MMQDj7pog7uSYTXKotGxYajeQwA/aHOAeG5zV6HxJLCdk8KuvTK8dvSvNq4OFV +6aM9ajmM6SSlqj//1/DIOpHGaljG4cYH4V+e62PtWEi45pvzcjIwKuLsS9RYwM9s1Jj5Md88molqUnYl +Xlue1SryKlpodiWLGB6GpBWU9FcEPQd6eBgjNRYpCn7opDyM0Ru9RMQdxxzSODVR12F6mTryFrWVcfeU +j9K82ctvxxXrZY7XRjiF7qEjUHgkYFQuuCeB19K9dO5xSSsf/9D44uwSmM556VXkXMJHGenFeZTvoexN +Ilg4bBOTjrip5uQcY4x2qJ3ckVDSLQ6MdCPpT4uGIHGOaze1jRJbkjFgDgYpjEgqxI7dqyWhpuQ3rkQS +HjpWfaR9/wCf1rqp6RZy1Peki8MGMfNx7d6jc7Yyc4ye1JptjvorjBneDw2QMVPEHBIOFwR3qbXF5ox/ +EDl71U4ODiqDrjJABIrsoaRSRx19ZNmrbD/RgScAjsag1CF9pcBTxWMXaTNZRbirDrF3CbSQTg9f5U+Z +QJxwFBA/lRZc1yrvlsf/0fD4fvE1MnYk/nX5/wBD7R7iP1yMdaQLzRF9LCa7hGvOf0qXHy9qUtxkgXnt +UqDk0pK7sCfYkUcYA6VKnIFYzWha7jhT1Hes42TsC1FIyOlNYEU4oT8hB3pGzt68U1tYVzP1IZQ56Yrz +e6UC5lUrwGOB+Nepl3xNGddXiV0Y8jGPw6U1slSCec9a9m6OCx//0vji/wAiMY45qux3Rbh/KvNprRHr +1N2iW3z5gHY81ZnA3AnipqfErF01aDuPhwXAPHSpME7jyOK53pKxt9kT5vmB4IPHFMkwcEnkkVPkPpqU +75zt8sDBJ+tNtVCt8x59q6rWi7HKneSuTxAhCAQOcc0yQEA4br2FRfVqxfK7LUYw4weCu3n1qbdiNmOM +EgY9KV9CXo2YF+VMyNx8zE5qMgsrhccdq7obK5xT3aRdtTi2VmPGMdc+lWJgr5XAGMfrWElq7G8XsmUx +C8ZJjOQQcgdakVXZxv4PbjvijmTJlBr7z//T8RjIGPc1KhXqPXivzzdH2bWoSD5sg4INJwRzz9aEw2BM +dM5qTjb60SdykSA88enepEOOKU31EkTREdqkH54NZT1Ra0Hd/SnHip0Q/IVjwPWmsePehPqiWC9T1pHH +B5oTaFYoaiOOn415tqm4X842jiRh+tenlvxMzrfCV05JLDHTgD3ppYFCB6/Svb1aOHbc/wD/1PjnUv8A +Vct3qq53IMeleZDZM9ipu0SRYDAkkewqxI24+w6VM90EL2aJYCN5AbgY/lU0R+9z+FZS0N076DZSNzc5 +yc0xyoUfh25qG9mU7XZnXLZuTgnaKsW4zjqRnriuiStHQ5Y/GOxgEVFuwpBA9+MVKsytUOjILcZ7daNQ +ZEt3O7k8fjU3ldDbVmc/cPm4QYA/rS8gMD2zz6139EcF7tli2lVIAhVsYPap45lZiFG08DnrWLT1Ztde +6kidMGMZHGD3pkqjcOcZ447cVjF6o0nZxbP/1fElB7HOD1qVQOOtfnSVj7VsRwNx60Ywp4PFOCVwvoIg +HB9e1SAAjGcUpa7AiQDkf0qRRxgZGaUrWuwJYwOByalXGB6A1nOzRS3FAI70/GSOtTtuMVunemHGKUe1 +iRRgk0hwKqPkDZS1DkYFed+JEEWs3Q5GHz9M816GX6VPkZ1V7pQibOck8jrUbgDIA4r3epwJ6an/1vjf +U9vl43YyelUwR5RGTxx0rzaauj1qrSlckiA3D5j071aYjccnHSlJXaHDZsntzkY3Z96lQjnnt9K55I3T +GsRyDnI9ajfKKOemDxio7Iq+7M3JeVieSecYq7AMKF3Fj6V0zVlaxzQfvXGDpy2McdajjydwIO2h2Hd6 +ND41G8nAGMdD1qLV2zAFORl+R1qEtVcTdkzBl5vSCMgNwKlVG3MFJ4967r6I4bO7JY1BjJJ7Y6dDVqyQ +CYkqTjvWEn7rN1unYtYQLntg9+tV2+aQBlbPTHrxWNPzNqux/9fxWMDP41IoUYr87WzPs3uEgBJ9uKAB +tINCSbDoJGAMcdKkAG04/KiSXQpPQkXGcY7VINp56VLBbksYBxUgAx0rOadrDT7C45pxA4wKVkUhX7ZF +NODzRG1iGAA5NIwGeB1FNLuBTvEBI7V5/wCNFP8Awkl1tIABUdP9kV35cl7VehFbWBlxbNuD8x9aY20Y +xjOa96xwWstD/9D451XAhBOOTxVRlURdOa8ymrI9epu2SW23cMgDHb1qw4BcrgY9KJ25kOn8LLFsArYG +McVIu3GdvOOTWLV2axeliOYgM+FzmoL1isAwME4GKVloDvqVoI9zEEAMMGrbIAmFUdcZrSbS0MqcWQBg +0WMg4PalhCFCdpHWiXUFZtaDtqhywBwMY9Ko6sR5oXPTn2p09WianVIyEYebwMEnPNTL5eXBA4Hautp6 +WONSWt0TQMhUgjKj1q5bhQWKMDwBxWE20mbws3ElXy9pUEDqMd6hfaHUgE7B2HtWUO7NKiVrI//R8Vj4 +br37VMuT9TX55HY+ze+gMM5PSkzwR1AoWu4IRRg9akPC8HpSlfRFLXYeCN3TkipV60ulmBJGeR71IvTP +Ws5K6Ghwp3FQkMH6elNJ461didOoq9SaRjxSjqwuVbgZkH1rzrxWwk8QXj9hIR+XFejl1nVt5EV/gM2I +qCTjPTH50x+eRxya961tzzt9j//S+O9WJ+zjgDmqJYGDJYZNedSSaPXqu0tew+L7wPTvmrBO5x7Y5qZf +EnYUPhZdhUZyO3pTgcOxGOR0rnbu7M6fhK9yVEvPy59O9QX75VBjnIoS+ETa95DLbdu6nnp7VYGSMk59 +vxrWemxlTZCvMe4BTg/nSRKHVsjGfpSe90C1VmTsG2H2x3rF1J1eVxgcHr+FVQWtyK7srFGAgOrHqDnp +7VPGNzO/O3kkCut7pnGno0idCCNyt6Crca5ZiDjpgVzXsnc6X71rDyBgcbtucn8KhjBMpOfrz7VlTdtT +Sqm7JH//2Q== +` + + data, err := base64.StdEncoding.DecodeString(base64EncodedImage) + if err != nil { + t.Fatalf("base64 DecodeString: %v", err) + } + if _, err = Decode(bytes.NewReader(data)); err != nil { + t.Fatalf("Decode: %v", err) + } +} + func TestExtraneousData(t *testing.T) { // Encode a 1x1 red image. src := image.NewRGBA(image.Rect(0, 0, 1, 1)) diff --git a/libgo/go/image/jpeg/scan.go b/libgo/go/image/jpeg/scan.go index 712e7e35ff8..94f3d3a326d 100644 --- a/libgo/go/image/jpeg/scan.go +++ b/libgo/go/image/jpeg/scan.go @@ -310,6 +310,25 @@ func (d *decoder) processSOS(n int) error { if err := d.readFull(d.tmp[:2]); err != nil { return err } + + // Section F.1.2.3 says that "Byte alignment of markers is + // achieved by padding incomplete bytes with 1-bits. If padding + // with 1-bits creates a X’FF’ value, a zero byte is stuffed + // before adding the marker." + // + // Seeing "\xff\x00" here is not spec compliant, as we are not + // expecting an *incomplete* byte (that needed padding). Still, + // some real world encoders (see golang.org/issue/28717) insert + // it, so we accept it and re-try the 2 byte read. + // + // libjpeg issues a warning (but not an error) for this: + // https://github.com/LuaDist/libjpeg/blob/6c0fcb8ddee365e7abc4d332662b06900612e923/jdmarker.c#L1041-L1046 + if d.tmp[0] == 0xff && d.tmp[1] == 0x00 { + if err := d.readFull(d.tmp[:2]); err != nil { + return err + } + } + if d.tmp[0] != 0xff || d.tmp[1] != expectedRST { return FormatError("bad RST marker") } diff --git a/libgo/go/image/names.go b/libgo/go/image/names.go index 8985f492140..8595a35014d 100644 --- a/libgo/go/image/names.go +++ b/libgo/go/image/names.go @@ -47,6 +47,7 @@ func (c *Uniform) Opaque() bool { return a == 0xffff } +// NewUniform returns a new Uniform image of the given color. func NewUniform(c color.Color) *Uniform { return &Uniform{c} } diff --git a/libgo/go/image/png/reader.go b/libgo/go/image/png/reader.go index 6771973bda9..910520bd4b3 100644 --- a/libgo/go/image/png/reader.go +++ b/libgo/go/image/png/reader.go @@ -163,8 +163,9 @@ func (d *decoder) parseIHDR(length uint32) error { if w <= 0 || h <= 0 { return FormatError("non-positive dimension") } - nPixels := int64(w) * int64(h) - if nPixels != int64(int(nPixels)) { + nPixels64 := int64(w) * int64(h) + nPixels := int(nPixels64) + if nPixels64 != int64(nPixels) { return UnsupportedError("dimension overflow") } // There can be up to 8 bytes per pixel, for 16 bits per channel RGBA. @@ -498,7 +499,10 @@ func (d *decoder) readImagePass(r io.Reader, pass int, allocateOnly bool) (image bytesPerPixel := (bitsPerPixel + 7) / 8 // The +1 is for the per-row filter type, which is at cr[0]. - rowSize := 1 + (bitsPerPixel*width+7)/8 + rowSize := 1 + (int64(bitsPerPixel)*int64(width)+7)/8 + if rowSize != int64(int(rowSize)) { + return nil, UnsupportedError("dimension overflow") + } // cr and pr are the bytes for the current and previous row. cr := make([]uint8, rowSize) pr := make([]uint8, rowSize) @@ -858,8 +862,7 @@ func (d *decoder) parseIEND(length uint32) error { func (d *decoder) parseChunk() error { // Read the length and chunk type. - n, err := io.ReadFull(d.r, d.tmp[:8]) - if err != nil { + if _, err := io.ReadFull(d.r, d.tmp[:8]); err != nil { return err } length := binary.BigEndian.Uint32(d.tmp[:4]) @@ -916,7 +919,7 @@ func (d *decoder) parseChunk() error { // Ignore this chunk (of a known length). var ignored [4096]byte for length > 0 { - n, err = io.ReadFull(d.r, ignored[:min(len(ignored), int(length))]) + n, err := io.ReadFull(d.r, ignored[:min(len(ignored), int(length))]) if err != nil { return err } diff --git a/libgo/go/image/png/reader_test.go b/libgo/go/image/png/reader_test.go index 3325d2e8a59..22c704e5cba 100644 --- a/libgo/go/image/png/reader_test.go +++ b/libgo/go/image/png/reader_test.go @@ -661,20 +661,126 @@ func TestGray8Transparent(t *testing.T) { } func TestDimensionOverflow(t *testing.T) { - // These bytes come from https://golang.org/issues/22304 - // - // It encodes a 2147483646 × 2147483646 (i.e. 0x7ffffffe × 0x7ffffffe) - // NRGBA image. The (width × height) per se doesn't overflow an int64, but - // (width × height × bytesPerPixel) will. - _, err := Decode(bytes.NewReader([]byte{ - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x7f, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xfe, 0x08, 0x06, 0x00, 0x00, 0x00, 0x30, 0x57, 0xb3, - 0xfd, 0x00, 0x00, 0x00, 0x15, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0x62, 0x62, 0x20, 0x12, 0x8c, - 0x2a, 0xa4, 0xb3, 0x42, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x13, 0x38, 0x00, 0x15, 0x2d, 0xef, - 0x5f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, - })) - if _, ok := err.(UnsupportedError); !ok { - t.Fatalf("Decode: got %v (of type %T), want non-nil error (of type png.UnsupportedError)", err, err) + maxInt32AsInt := int((1 << 31) - 1) + have32BitInts := 0 > (1 + maxInt32AsInt) + + testCases := []struct { + src []byte + unsupportedConfig bool + width int + height int + }{ + // These bytes come from https://golang.org/issues/22304 + // + // It encodes a 2147483646 × 2147483646 (i.e. 0x7ffffffe × 0x7ffffffe) + // NRGBA image. The (width × height) per se doesn't overflow an int64, but + // (width × height × bytesPerPixel) will. + { + src: []byte{ + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x7f, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xfe, 0x08, 0x06, 0x00, 0x00, 0x00, 0x30, 0x57, 0xb3, + 0xfd, 0x00, 0x00, 0x00, 0x15, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0x62, 0x62, 0x20, 0x12, 0x8c, + 0x2a, 0xa4, 0xb3, 0x42, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x13, 0x38, 0x00, 0x15, 0x2d, 0xef, + 0x5f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, + }, + // It's debatable whether DecodeConfig (which does not allocate a + // pixel buffer, unlike Decode) should fail in this case. The Go + // standard library has made its choice, and the standard library + // has compatibility constraints. + unsupportedConfig: true, + width: 0x7ffffffe, + height: 0x7ffffffe, + }, + + // The next three cases come from https://golang.org/issues/38435 + + { + src: []byte{ + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0xb5, 0x04, 0x00, 0x00, 0xb5, 0x04, 0x08, 0x06, 0x00, 0x00, 0x00, 0xf5, 0x60, 0x2c, + 0xb8, 0x00, 0x00, 0x00, 0x15, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0x62, 0x62, 0x20, 0x12, 0x8c, + 0x2a, 0xa4, 0xb3, 0x42, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x13, 0x38, 0x00, 0x15, 0x2d, 0xef, + 0x5f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, + }, + // Here, width * height = 0x7ffea810, just under MaxInt32, but at 4 + // bytes per pixel, the number of pixels overflows an int32. + unsupportedConfig: have32BitInts, + width: 0x0000b504, + height: 0x0000b504, + }, + + { + src: []byte{ + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06, 0x00, 0x00, 0x00, 0x30, 0x6e, 0xc5, + 0x21, 0x00, 0x00, 0x00, 0x15, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0x62, 0x62, 0x20, 0x12, 0x8c, + 0x2a, 0xa4, 0xb3, 0x42, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x13, 0x38, 0x00, 0x15, 0x2d, 0xef, + 0x5f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, + }, + unsupportedConfig: false, + width: 0x04000000, + height: 0x00000001, + }, + + { + src: []byte{ + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06, 0x00, 0x00, 0x00, 0xaa, 0xd4, 0x7c, + 0xda, 0x00, 0x00, 0x00, 0x15, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0x62, 0x66, 0x20, 0x12, 0x30, + 0x8d, 0x2a, 0xa4, 0xaf, 0x42, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x14, 0xd2, 0x00, 0x16, 0x00, + 0x00, 0x00, + }, + unsupportedConfig: false, + width: 0x08000000, + height: 0x00000001, + }, + } + + for i, tc := range testCases { + cfg, err := DecodeConfig(bytes.NewReader(tc.src)) + if tc.unsupportedConfig { + if err == nil { + t.Errorf("i=%d: DecodeConfig: got nil error, want non-nil", i) + } else if _, ok := err.(UnsupportedError); !ok { + t.Fatalf("Decode: got %v (of type %T), want non-nil error (of type png.UnsupportedError)", err, err) + } + continue + } else if err != nil { + t.Errorf("i=%d: DecodeConfig: %v", i, err) + continue + } else if cfg.Width != tc.width { + t.Errorf("i=%d: width: got %d, want %d", i, cfg.Width, tc.width) + continue + } else if cfg.Height != tc.height { + t.Errorf("i=%d: height: got %d, want %d", i, cfg.Height, tc.height) + continue + } + + if nPixels := int64(cfg.Width) * int64(cfg.Height); nPixels > 0x7f000000 { + // In theory, calling Decode would succeed, given several gigabytes + // of memory. In practice, trying to make a []uint8 big enough to + // hold all of the pixels can often result in OOM (out of memory). + // OOM is unrecoverable; we can't write a test that passes when OOM + // happens. Instead we skip the Decode call (and its tests). + continue + } else if testing.Short() { + // Even for smaller image dimensions, calling Decode might allocate + // 1 GiB or more of memory. This is usually feasible, and we want + // to check that calling Decode doesn't panic if there's enough + // memory, but we provide a runtime switch (testing.Short) to skip + // these if it would OOM. See also http://golang.org/issue/5050 + // "decoding... images can cause huge memory allocations". + continue + } + + // Even if we don't panic, these aren't valid PNG images. + if _, err := Decode(bytes.NewReader(tc.src)); err == nil { + t.Errorf("i=%d: Decode: got nil error, want non-nil", i) + } + } + + if testing.Short() { + t.Skip("skipping tests which allocate large pixel buffers") } } diff --git a/libgo/go/image/ycbcr.go b/libgo/go/image/ycbcr.go index 71c0518a818..fbdffe1bd1b 100644 --- a/libgo/go/image/ycbcr.go +++ b/libgo/go/image/ycbcr.go @@ -168,6 +168,16 @@ func yCbCrSize(r Rectangle, subsampleRatio YCbCrSubsampleRatio) (w, h, cw, ch in // ratio. func NewYCbCr(r Rectangle, subsampleRatio YCbCrSubsampleRatio) *YCbCr { w, h, cw, ch := yCbCrSize(r, subsampleRatio) + + // totalLength should be the same as i2, below, for a valid Rectangle r. + totalLength := add2NonNeg( + mul3NonNeg(1, w, h), + mul3NonNeg(2, cw, ch), + ) + if totalLength < 0 { + panic("image: NewYCbCr Rectangle has huge or negative dimensions") + } + i0 := w*h + 0*cw*ch i1 := w*h + 1*cw*ch i2 := w*h + 2*cw*ch @@ -277,6 +287,16 @@ func (p *NYCbCrA) Opaque() bool { // ratio. func NewNYCbCrA(r Rectangle, subsampleRatio YCbCrSubsampleRatio) *NYCbCrA { w, h, cw, ch := yCbCrSize(r, subsampleRatio) + + // totalLength should be the same as i3, below, for a valid Rectangle r. + totalLength := add2NonNeg( + mul3NonNeg(2, w, h), + mul3NonNeg(2, cw, ch), + ) + if totalLength < 0 { + panic("image: NewNYCbCrA Rectangle has huge or negative dimension") + } + i0 := 1*w*h + 0*cw*ch i1 := 1*w*h + 1*cw*ch i2 := 1*w*h + 2*cw*ch diff --git a/libgo/go/internal/bytealg/bytealg.go b/libgo/go/internal/bytealg/bytealg.go index e46ee7c4fba..abdba5fb580 100644 --- a/libgo/go/internal/bytealg/bytealg.go +++ b/libgo/go/internal/bytealg/bytealg.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build ignore_for_gccgo - package bytealg import ( @@ -22,4 +20,130 @@ const ( ) // MaxLen is the maximum length of the string to be searched for (argument b) in Index. +// If MaxLen is not 0, make sure MaxLen >= 4. var MaxLen int = 32 + +// FIXME: the logic of HashStrBytes, HashStrRevBytes, IndexRabinKarpBytes and HashStr, HashStrRev, +// IndexRabinKarp are exactly the same, except that the types are different. Can we eliminate +// three of them without causing allocation? + +// PrimeRK is the prime base used in Rabin-Karp algorithm. +const PrimeRK = 16777619 + +// HashStrBytes returns the hash and the appropriate multiplicative +// factor for use in Rabin-Karp algorithm. +func HashStrBytes(sep []byte) (uint32, uint32) { + hash := uint32(0) + for i := 0; i < len(sep); i++ { + hash = hash*PrimeRK + uint32(sep[i]) + } + var pow, sq uint32 = 1, PrimeRK + for i := len(sep); i > 0; i >>= 1 { + if i&1 != 0 { + pow *= sq + } + sq *= sq + } + return hash, pow +} + +// HashStr returns the hash and the appropriate multiplicative +// factor for use in Rabin-Karp algorithm. +func HashStr(sep string) (uint32, uint32) { + hash := uint32(0) + for i := 0; i < len(sep); i++ { + hash = hash*PrimeRK + uint32(sep[i]) + } + var pow, sq uint32 = 1, PrimeRK + for i := len(sep); i > 0; i >>= 1 { + if i&1 != 0 { + pow *= sq + } + sq *= sq + } + return hash, pow +} + +// HashStrRevBytes returns the hash of the reverse of sep and the +// appropriate multiplicative factor for use in Rabin-Karp algorithm. +func HashStrRevBytes(sep []byte) (uint32, uint32) { + hash := uint32(0) + for i := len(sep) - 1; i >= 0; i-- { + hash = hash*PrimeRK + uint32(sep[i]) + } + var pow, sq uint32 = 1, PrimeRK + for i := len(sep); i > 0; i >>= 1 { + if i&1 != 0 { + pow *= sq + } + sq *= sq + } + return hash, pow +} + +// HashStrRev returns the hash of the reverse of sep and the +// appropriate multiplicative factor for use in Rabin-Karp algorithm. +func HashStrRev(sep string) (uint32, uint32) { + hash := uint32(0) + for i := len(sep) - 1; i >= 0; i-- { + hash = hash*PrimeRK + uint32(sep[i]) + } + var pow, sq uint32 = 1, PrimeRK + for i := len(sep); i > 0; i >>= 1 { + if i&1 != 0 { + pow *= sq + } + sq *= sq + } + return hash, pow +} + +// IndexRabinKarpBytes uses the Rabin-Karp search algorithm to return the index of the +// first occurence of substr in s, or -1 if not present. +func IndexRabinKarpBytes(s, sep []byte) int { + // Rabin-Karp search + hashsep, pow := HashStrBytes(sep) + n := len(sep) + var h uint32 + for i := 0; i < n; i++ { + h = h*PrimeRK + uint32(s[i]) + } + if h == hashsep && Equal(s[:n], sep) { + return 0 + } + for i := n; i < len(s); { + h *= PrimeRK + h += uint32(s[i]) + h -= pow * uint32(s[i-n]) + i++ + if h == hashsep && Equal(s[i-n:i], sep) { + return i - n + } + } + return -1 +} + +// IndexRabinKarp uses the Rabin-Karp search algorithm to return the index of the +// first occurence of substr in s, or -1 if not present. +func IndexRabinKarp(s, substr string) int { + // Rabin-Karp search + hashss, pow := HashStr(substr) + n := len(substr) + var h uint32 + for i := 0; i < n; i++ { + h = h*PrimeRK + uint32(s[i]) + } + if h == hashss && s[:n] == substr { + return 0 + } + for i := n; i < len(s); { + h *= PrimeRK + h += uint32(s[i]) + h -= pow * uint32(s[i-n]) + i++ + if h == hashss && s[i-n:i] == substr { + return i - n + } + } + return -1 +} diff --git a/libgo/go/internal/bytealg/gccgo.go b/libgo/go/internal/bytealg/gccgo.go index 8c78b631dee..05b39e3e2ca 100644 --- a/libgo/go/internal/bytealg/gccgo.go +++ b/libgo/go/internal/bytealg/gccgo.go @@ -6,7 +6,4 @@ package bytealg -// MaxLen is the maximum length of the string to be searched for (argument b) in Index. -var MaxLen int = 32 - const MaxBruteForce = 64 diff --git a/libgo/go/internal/bytealg/index_generic.go b/libgo/go/internal/bytealg/index_generic.go index c595c231cf0..3dc1c6b2232 100644 --- a/libgo/go/internal/bytealg/index_generic.go +++ b/libgo/go/internal/bytealg/index_generic.go @@ -17,8 +17,42 @@ func Index(a, b []byte) int { // IndexString returns the index of the first instance of b in a, or -1 if b is not present in a. // Requires 2 <= len(b) <= MaxLen. -func IndexString(a, b string) int { - panic("unimplemented") +func IndexString(s, substr string) int { + // This is a partial copy of strings.Index, here because bytes.IndexAny and bytes.LastIndexAny + // call bytealg.IndexString. Some platforms have an optimized assembly version of this function. + // This implementation is used for those that do not. Although the pure Go implementation here + // works for the case of len(b) > MaxLen, we do not require that its assembly implementation also + // supports the case of len(b) > MaxLen. And we do not guarantee that this function supports the + // case of len(b) > MaxLen. + n := len(substr) + c0 := substr[0] + c1 := substr[1] + i := 0 + t := len(s) - n + 1 + fails := 0 + for i < t { + if s[i] != c0 { + o := IndexByteString(s[i:t], c0) + if o < 0 { + return -1 + } + i += o + } + if s[i+1] == c1 && s[i:i+n] == substr { + return i + } + i++ + fails++ + if fails >= 4+i>>4 && i < t { + // See comment in src/bytes/bytes.go. + j := IndexRabinKarp(s[i:], substr) + if j < 0 { + return -1 + } + return i + j + } + } + return -1 } // Cutover reports the number of failures of IndexByte we should tolerate diff --git a/libgo/go/internal/cfg/cfg.go b/libgo/go/internal/cfg/cfg.go index 0d227ecd100..bdbe9df3e75 100644 --- a/libgo/go/internal/cfg/cfg.go +++ b/libgo/go/internal/cfg/cfg.go @@ -46,6 +46,7 @@ const KnownEnv = ` GOINSECURE GOMIPS GOMIPS64 + GOMODCACHE GONOPROXY GONOSUMDB GOOS diff --git a/libgo/go/internal/cpu/cpu.go b/libgo/go/internal/cpu/cpu.go index f326b063321..2829945af0b 100644 --- a/libgo/go/internal/cpu/cpu.go +++ b/libgo/go/internal/cpu/cpu.go @@ -19,13 +19,11 @@ type CacheLinePad struct{ _ [CacheLinePadSize]byte } // so we use the constant per GOARCH CacheLinePadSize as an approximation. var CacheLineSize uintptr = CacheLinePadSize -var X86 x86 - -// The booleans in x86 contain the correspondingly named cpuid feature bit. +// The booleans in X86 contain the correspondingly named cpuid feature bit. // HasAVX and HasAVX2 are only set if the OS does support XMM and YMM registers // in addition to the cpuid feature bit being set. // The struct is padded to avoid false sharing. -type x86 struct { +var X86 struct { _ CacheLinePad HasAES bool HasADX bool @@ -46,38 +44,18 @@ type x86 struct { _ CacheLinePad } -var PPC64 ppc64 - -// For ppc64(le), it is safe to check only for ISA level starting on ISA v3.00, -// since there are no optional categories. There are some exceptions that also -// require kernel support to work (darn, scv), so there are feature bits for -// those as well. The minimum processor requirement is POWER8 (ISA 2.07). -// The struct is padded to avoid false sharing. -type ppc64 struct { - _ CacheLinePad - HasDARN bool // Hardware random number generator (requires kernel enablement) - HasSCV bool // Syscall vectored (requires kernel enablement) - IsPOWER8 bool // ISA v2.07 (POWER8) - IsPOWER9 bool // ISA v3.00 (POWER9) - _ CacheLinePad -} - -var ARM arm - -// The booleans in arm contain the correspondingly named cpu feature bit. +// The booleans in ARM contain the correspondingly named cpu feature bit. // The struct is padded to avoid false sharing. -type arm struct { +var ARM struct { _ CacheLinePad HasVFPv4 bool HasIDIVA bool _ CacheLinePad } -var ARM64 arm64 - -// The booleans in arm64 contain the correspondingly named cpu feature bit. +// The booleans in ARM64 contain the correspondingly named cpu feature bit. // The struct is padded to avoid false sharing. -type arm64 struct { +var ARM64 struct { _ CacheLinePad HasFP bool HasASIMD bool @@ -106,9 +84,27 @@ type arm64 struct { _ CacheLinePad } -var S390X s390x +var MIPS64X struct { + _ CacheLinePad + HasMSA bool // MIPS SIMD architecture + _ CacheLinePad +} + +// For ppc64(le), it is safe to check only for ISA level starting on ISA v3.00, +// since there are no optional categories. There are some exceptions that also +// require kernel support to work (darn, scv), so there are feature bits for +// those as well. The minimum processor requirement is POWER8 (ISA 2.07). +// The struct is padded to avoid false sharing. +var PPC64 struct { + _ CacheLinePad + HasDARN bool // Hardware random number generator (requires kernel enablement) + HasSCV bool // Syscall vectored (requires kernel enablement) + IsPOWER8 bool // ISA v2.07 (POWER8) + IsPOWER9 bool // ISA v3.00 (POWER9) + _ CacheLinePad +} -type s390x struct { +var S390X struct { _ CacheLinePad HasZARCH bool // z architecture mode is active [mandatory] HasSTFLE bool // store facility list extended [mandatory] diff --git a/libgo/go/internal/cpu/cpu_arm.go b/libgo/go/internal/cpu/cpu_arm.go index a1d5a7ba255..7324e7b8151 100644 --- a/libgo/go/internal/cpu/cpu_arm.go +++ b/libgo/go/internal/cpu/cpu_arm.go @@ -5,9 +5,8 @@ package cpu // arm doesn't have a 'cpuid' equivalent, so we rely on HWCAP/HWCAP2. -// These are linknamed in runtime/os_(linux|freebsd)_arm.go and are -// initialized by archauxv(). -// These should not be changed after they are initialized. +// These are initialized by archauxv() and should not be changed after they are +// initialized. var HWCap uint var HWCap2 uint diff --git a/libgo/go/internal/cpu/cpu_arm64.go b/libgo/go/internal/cpu/cpu_arm64.go index 99fa9918625..c1f0b01e648 100644 --- a/libgo/go/internal/cpu/cpu_arm64.go +++ b/libgo/go/internal/cpu/cpu_arm64.go @@ -5,8 +5,8 @@ package cpu // arm64 doesn't have a 'cpuid' equivalent, so we rely on HWCAP/HWCAP2. -// These are initialized by archauxv in runtime/os_linux_arm64.go. -// These should not be changed after they are initialized. +// These are initialized by archauxv and should not be changed after they are +// initialized. var HWCap uint var HWCap2 uint diff --git a/libgo/go/internal/cpu/cpu_mips64x.go b/libgo/go/internal/cpu/cpu_mips64x.go new file mode 100644 index 00000000000..0c4794a70ac --- /dev/null +++ b/libgo/go/internal/cpu/cpu_mips64x.go @@ -0,0 +1,32 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build mips64 mips64le + +package cpu + +const CacheLinePadSize = 32 + +// This is initialized by archauxv and should not be changed after it is +// initialized. +var HWCap uint + +// HWCAP bits. These are exposed by the Linux kernel 5.4. +const ( + // CPU features + hwcap_MIPS_MSA = 1 << 1 +) + +func doinit() { + options = []option{ + {Name: "msa", Feature: &MIPS64X.HasMSA}, + } + + // HWCAP feature bits + MIPS64X.HasMSA = isSet(HWCap, hwcap_MIPS_MSA) +} + +func isSet(hwc uint, value uint) bool { + return hwc&value != 0 +} diff --git a/libgo/go/internal/cpu/cpu_no_init.go b/libgo/go/internal/cpu/cpu_no_init.go index d4b2be8cf4f..fb381e1ce2d 100644 --- a/libgo/go/internal/cpu/cpu_no_init.go +++ b/libgo/go/internal/cpu/cpu_no_init.go @@ -9,6 +9,8 @@ // +build !ppc64 // +build !ppc64le // +build !s390x +// +build !mips64 +// +build !mips64le package cpu diff --git a/libgo/go/internal/cpu/cpu_ppc64x.go b/libgo/go/internal/cpu/cpu_ppc64x.go index 02f2c06c60b..b726cc86d52 100644 --- a/libgo/go/internal/cpu/cpu_ppc64x.go +++ b/libgo/go/internal/cpu/cpu_ppc64x.go @@ -7,8 +7,8 @@ package cpu // ppc64x doesn't have a 'cpuid' equivalent, so we rely on HWCAP/HWCAP2. -// These are initialized by archauxv in runtime/os_linux_ppc64x.go. -// These should not be changed after they are initialized. +// These are initialized by archauxv and should not be changed after they are +// initialized. // On aix/ppc64, these values are initialized early in the runtime in runtime/os_aix.go. var HWCap uint var HWCap2 uint diff --git a/libgo/go/internal/goversion/goversion.go b/libgo/go/internal/goversion/goversion.go index c5783337b31..4ffd34c1a28 100644 --- a/libgo/go/internal/goversion/goversion.go +++ b/libgo/go/internal/goversion/goversion.go @@ -10,4 +10,4 @@ package goversion // // When incrementing this, also add to the list at src/go/build/doc.go // (search for "onward"). -const Version = 14 +const Version = 15 diff --git a/libgo/go/internal/poll/copy_file_range_linux.go b/libgo/go/internal/poll/copy_file_range_linux.go new file mode 100644 index 00000000000..604607f774a --- /dev/null +++ b/libgo/go/internal/poll/copy_file_range_linux.go @@ -0,0 +1,99 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package poll + +import ( + "internal/syscall/unix" + "sync/atomic" + "syscall" +) + +var copyFileRangeSupported int32 = 1 // accessed atomically + +const maxCopyFileRangeRound = 1 << 30 + +// CopyFileRange copies at most remain bytes of data from src to dst, using +// the copy_file_range system call. dst and src must refer to regular files. +func CopyFileRange(dst, src *FD, remain int64) (written int64, handled bool, err error) { + if atomic.LoadInt32(©FileRangeSupported) == 0 { + return 0, false, nil + } + for remain > 0 { + max := remain + if max > maxCopyFileRangeRound { + max = maxCopyFileRangeRound + } + n, err := copyFileRange(dst, src, int(max)) + switch err { + case syscall.ENOSYS: + // copy_file_range(2) was introduced in Linux 4.5. + // Go supports Linux >= 2.6.33, so the system call + // may not be present. + // + // If we see ENOSYS, we have certainly not transfered + // any data, so we can tell the caller that we + // couldn't handle the transfer and let them fall + // back to more generic code. + // + // Seeing ENOSYS also means that we will not try to + // use copy_file_range(2) again. + atomic.StoreInt32(©FileRangeSupported, 0) + return 0, false, nil + case syscall.EXDEV, syscall.EINVAL: + // Prior to Linux 5.3, it was not possible to + // copy_file_range across file systems. Similarly to + // the ENOSYS case above, if we see EXDEV, we have + // not transfered any data, and we can let the caller + // fall back to generic code. + // + // As for EINVAL, that is what we see if, for example, + // dst or src refer to a pipe rather than a regular + // file. This is another case where no data has been + // transfered, so we consider it unhandled. + return 0, false, nil + case nil: + if n == 0 { + // src is at EOF, which means we are done. + return written, true, nil + } + remain -= n + written += n + default: + return written, true, err + } + } + return written, true, nil +} + +// copyFileRange performs one round of copy_file_range(2). +func copyFileRange(dst, src *FD, max int) (written int64, err error) { + // The signature of copy_file_range(2) is: + // + // ssize_t copy_file_range(int fd_in, loff_t *off_in, + // int fd_out, loff_t *off_out, + // size_t len, unsigned int flags); + // + // Note that in the call to unix.CopyFileRange below, we use nil + // values for off_in and off_out. For the system call, this means + // "use and update the file offsets". That is why we must acquire + // locks for both file descriptors (and why this whole machinery is + // in the internal/poll package to begin with). + if err := dst.writeLock(); err != nil { + return 0, err + } + defer dst.writeUnlock() + if err := src.readLock(); err != nil { + return 0, err + } + defer src.readUnlock() + var n int + for { + n, err = unix.CopyFileRange(src.Sysfd, nil, dst.Sysfd, nil, max, 0) + if err != syscall.EINTR { + break + } + } + return int64(n), err +} diff --git a/libgo/go/internal/poll/fd.go b/libgo/go/internal/poll/fd.go index c0de50c1b46..b72ea3d55c2 100644 --- a/libgo/go/internal/poll/fd.go +++ b/libgo/go/internal/poll/fd.go @@ -35,16 +35,20 @@ func errClosing(isFile bool) error { return ErrNetClosing } -// ErrTimeout is returned for an expired deadline. -var ErrTimeout error = &TimeoutError{} +// ErrDeadlineExceeded is returned for an expired deadline. +// This is exported by the os package as os.ErrDeadlineExceeded. +var ErrDeadlineExceeded error = &DeadlineExceededError{} -// TimeoutError is returned for an expired deadline. -type TimeoutError struct{} +// DeadlineExceededError is returned for an expired deadline. +type DeadlineExceededError struct{} // Implement the net.Error interface. -func (e *TimeoutError) Error() string { return "i/o timeout" } -func (e *TimeoutError) Timeout() bool { return true } -func (e *TimeoutError) Temporary() bool { return true } +// The string is "i/o timeout" because that is what was returned +// by earlier Go versions. Changing it may break programs that +// match on error strings. +func (e *DeadlineExceededError) Error() string { return "i/o timeout" } +func (e *DeadlineExceededError) Timeout() bool { return true } +func (e *DeadlineExceededError) Temporary() bool { return true } // ErrNotPollable is returned when the file or socket is not suitable // for event notification. diff --git a/libgo/go/internal/poll/fd_mutex_test.go b/libgo/go/internal/poll/fd_mutex_test.go index 2c53c4561fb..3029b9a6811 100644 --- a/libgo/go/internal/poll/fd_mutex_test.go +++ b/libgo/go/internal/poll/fd_mutex_test.go @@ -59,7 +59,7 @@ func TestMutexClose(t *testing.T) { } func TestMutexCloseUnblock(t *testing.T) { - c := make(chan bool) + c := make(chan bool, 4) var mu FDMutex mu.RWLock(true) for i := 0; i < 4; i++ { @@ -151,12 +151,15 @@ func TestMutexStress(t *testing.T) { N = 1e4 } defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(P)) - done := make(chan bool) + done := make(chan bool, P) var mu FDMutex var readState [2]uint64 var writeState [2]uint64 for p := 0; p < P; p++ { go func() { + defer func() { + done <- !t.Failed() + }() r := rand.New(rand.NewSource(rand.Int63())) for i := 0; i < N; i++ { switch r.Intn(3) { @@ -203,11 +206,12 @@ func TestMutexStress(t *testing.T) { } } } - done <- true }() } for p := 0; p < P; p++ { - <-done + if !<-done { + t.FailNow() + } } if !mu.IncrefAndClose() { t.Fatal("broken") diff --git a/libgo/go/internal/poll/fd_plan9.go b/libgo/go/internal/poll/fd_plan9.go index 0fce32915e7..0b5b9375333 100644 --- a/libgo/go/internal/poll/fd_plan9.go +++ b/libgo/go/internal/poll/fd_plan9.go @@ -7,6 +7,7 @@ package poll import ( "errors" "io" + "sync" "sync/atomic" "time" ) @@ -24,6 +25,8 @@ type FD struct { Destroy func() // deadlines + rmu sync.Mutex + wmu sync.Mutex raio *asyncIO waio *asyncIO rtimer *time.Timer @@ -59,9 +62,6 @@ func (fd *FD) Close() error { // Read implements io.Reader. func (fd *FD) Read(fn func([]byte) (int, error), b []byte) (int, error) { - if fd.rtimedout.isSet() { - return 0, ErrTimeout - } if err := fd.readLock(); err != nil { return 0, err } @@ -69,32 +69,41 @@ func (fd *FD) Read(fn func([]byte) (int, error), b []byte) (int, error) { if len(b) == 0 { return 0, nil } + fd.rmu.Lock() + if fd.rtimedout.isSet() { + fd.rmu.Unlock() + return 0, ErrDeadlineExceeded + } fd.raio = newAsyncIO(fn, b) + fd.rmu.Unlock() n, err := fd.raio.Wait() fd.raio = nil if isHangup(err) { err = io.EOF } if isInterrupted(err) { - err = ErrTimeout + err = ErrDeadlineExceeded } return n, err } // Write implements io.Writer. func (fd *FD) Write(fn func([]byte) (int, error), b []byte) (int, error) { - if fd.wtimedout.isSet() { - return 0, ErrTimeout - } if err := fd.writeLock(); err != nil { return 0, err } defer fd.writeUnlock() + fd.wmu.Lock() + if fd.wtimedout.isSet() { + fd.wmu.Unlock() + return 0, ErrDeadlineExceeded + } fd.waio = newAsyncIO(fn, b) + fd.wmu.Unlock() n, err := fd.waio.Wait() fd.waio = nil if isInterrupted(err) { - err = ErrTimeout + err = ErrDeadlineExceeded } return n, err } @@ -117,9 +126,13 @@ func (fd *FD) SetWriteDeadline(t time.Time) error { func setDeadlineImpl(fd *FD, t time.Time, mode int) error { d := t.Sub(time.Now()) if mode == 'r' || mode == 'r'+'w' { + fd.rmu.Lock() + defer fd.rmu.Unlock() fd.rtimedout.setFalse() } if mode == 'w' || mode == 'r'+'w' { + fd.wmu.Lock() + defer fd.wmu.Unlock() fd.wtimedout.setFalse() } if t.IsZero() || d < 0 { @@ -140,18 +153,22 @@ func setDeadlineImpl(fd *FD, t time.Time, mode int) error { // Interrupt I/O operation once timer has expired if mode == 'r' || mode == 'r'+'w' { fd.rtimer = time.AfterFunc(d, func() { + fd.rmu.Lock() fd.rtimedout.setTrue() if fd.raio != nil { fd.raio.Cancel() } + fd.rmu.Unlock() }) } if mode == 'w' || mode == 'r'+'w' { fd.wtimer = time.AfterFunc(d, func() { + fd.wmu.Lock() fd.wtimedout.setTrue() if fd.waio != nil { fd.waio.Cancel() } + fd.wmu.Unlock() }) } } diff --git a/libgo/go/internal/poll/fd_poll_js.go b/libgo/go/internal/poll/fd_poll_js.go index 2bfeb0a0b7a..d6b28e503cd 100644 --- a/libgo/go/internal/poll/fd_poll_js.go +++ b/libgo/go/internal/poll/fd_poll_js.go @@ -45,7 +45,7 @@ func (pd *pollDesc) wait(mode int, isFile bool) error { if isFile { // TODO(neelance): wasm: Use callbacks from JS to block until the read/write finished. return nil } - return ErrTimeout + return ErrDeadlineExceeded } func (pd *pollDesc) waitRead(isFile bool) error { return pd.wait('r', isFile) } diff --git a/libgo/go/internal/poll/fd_poll_runtime.go b/libgo/go/internal/poll/fd_poll_runtime.go index d80ec3f1c9b..55aa304834e 100644 --- a/libgo/go/internal/poll/fd_poll_runtime.go +++ b/libgo/go/internal/poll/fd_poll_runtime.go @@ -107,15 +107,24 @@ func (pd *pollDesc) pollable() bool { return pd.runtimeCtx != 0 } +// Error values returned by runtime_pollReset and runtime_pollWait. +// These must match the values in runtime/netpoll.go. +const ( + pollNoError = 0 + pollErrClosing = 1 + pollErrTimeout = 2 + pollErrNotPollable = 3 +) + func convertErr(res int, isFile bool) error { switch res { - case 0: + case pollNoError: return nil - case 1: + case pollErrClosing: return errClosing(isFile) - case 2: - return ErrTimeout - case 3: + case pollErrTimeout: + return ErrDeadlineExceeded + case pollErrNotPollable: return ErrNotPollable } println("unreachable: ", res) diff --git a/libgo/go/internal/poll/fd_posix.go b/libgo/go/internal/poll/fd_posix.go index 9eaec365462..986cd331854 100644 --- a/libgo/go/internal/poll/fd_posix.go +++ b/libgo/go/internal/poll/fd_posix.go @@ -20,6 +20,15 @@ func (fd *FD) eofError(n int, err error) error { return err } +// Shutdown wraps syscall.Shutdown. +func (fd *FD) Shutdown(how int) error { + if err := fd.incref(); err != nil { + return err + } + defer fd.decref() + return syscall.Shutdown(fd.Sysfd, how) +} + // Fchmod wraps syscall.Fchmod. func (fd *FD) Fchmod(mode uint32) error { if err := fd.incref(); err != nil { @@ -46,3 +55,14 @@ func (fd *FD) Ftruncate(size int64) error { defer fd.decref() return syscall.Ftruncate(fd.Sysfd, size) } + +// RawControl invokes the user-defined function f for a non-IO +// operation. +func (fd *FD) RawControl(f func(uintptr)) error { + if err := fd.incref(); err != nil { + return err + } + defer fd.decref() + f(uintptr(fd.Sysfd)) + return nil +} diff --git a/libgo/go/internal/poll/fd_unix.go b/libgo/go/internal/poll/fd_unix.go index 213e815a307..f177ccf3f6e 100644 --- a/libgo/go/internal/poll/fd_unix.go +++ b/libgo/go/internal/poll/fd_unix.go @@ -8,7 +8,6 @@ package poll import ( "io" - "runtime" "sync/atomic" "syscall" ) @@ -112,15 +111,6 @@ func (fd *FD) Close() error { return err } -// Shutdown wraps the shutdown network call. -func (fd *FD) Shutdown(how int) error { - if err := fd.incref(); err != nil { - return err - } - defer fd.decref() - return syscall.Shutdown(fd.Sysfd, how) -} - // SetBlocking puts the file into blocking mode. func (fd *FD) SetBlocking() error { if err := fd.incref(); err != nil { @@ -162,7 +152,7 @@ func (fd *FD) Read(p []byte) (int, error) { p = p[:maxRW] } for { - n, err := syscall.Read(fd.Sysfd, p) + n, err := ignoringEINTR(syscall.Read, fd.Sysfd, p) if err != nil { n = 0 if err == syscall.EAGAIN && fd.pd.pollable() { @@ -170,12 +160,6 @@ func (fd *FD) Read(p []byte) (int, error) { continue } } - - // On MacOS we can see EINTR here if the user - // pressed ^Z. See issue #22838. - if runtime.GOOS == "darwin" && err == syscall.EINTR { - continue - } } err = fd.eofError(n, err) return n, err @@ -193,7 +177,16 @@ func (fd *FD) Pread(p []byte, off int64) (int, error) { if fd.IsStream && len(p) > maxRW { p = p[:maxRW] } - n, err := syscall.Pread(fd.Sysfd, p, off) + var ( + n int + err error + ) + for { + n, err = syscall.Pread(fd.Sysfd, p, off) + if err != syscall.EINTR { + break + } + } if err != nil { n = 0 } @@ -214,6 +207,9 @@ func (fd *FD) ReadFrom(p []byte) (int, syscall.Sockaddr, error) { for { n, sa, err := syscall.Recvfrom(fd.Sysfd, p, 0) if err != nil { + if err == syscall.EINTR { + continue + } n = 0 if err == syscall.EAGAIN && fd.pd.pollable() { if err = fd.pd.waitRead(fd.isFile); err == nil { @@ -238,6 +234,9 @@ func (fd *FD) ReadMsg(p []byte, oob []byte) (int, int, int, syscall.Sockaddr, er for { n, oobn, flags, sa, err := syscall.Recvmsg(fd.Sysfd, p, oob, 0) if err != nil { + if err == syscall.EINTR { + continue + } // TODO(dfc) should n and oobn be set to 0 if err == syscall.EAGAIN && fd.pd.pollable() { if err = fd.pd.waitRead(fd.isFile); err == nil { @@ -265,7 +264,7 @@ func (fd *FD) Write(p []byte) (int, error) { if fd.IsStream && max-nn > maxRW { max = nn + maxRW } - n, err := syscall.Write(fd.Sysfd, p[nn:max]) + n, err := ignoringEINTR(syscall.Write, fd.Sysfd, p[nn:max]) if n > 0 { nn += n } @@ -302,6 +301,9 @@ func (fd *FD) Pwrite(p []byte, off int64) (int, error) { max = nn + maxRW } n, err := syscall.Pwrite(fd.Sysfd, p[nn:max], off+int64(nn)) + if err == syscall.EINTR { + continue + } if n > 0 { nn += n } @@ -328,6 +330,9 @@ func (fd *FD) WriteTo(p []byte, sa syscall.Sockaddr) (int, error) { } for { err := syscall.Sendto(fd.Sysfd, p, 0, sa) + if err == syscall.EINTR { + continue + } if err == syscall.EAGAIN && fd.pd.pollable() { if err = fd.pd.waitWrite(fd.isFile); err == nil { continue @@ -351,6 +356,9 @@ func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, err } for { n, err := syscall.SendmsgN(fd.Sysfd, p, oob, sa, 0) + if err == syscall.EINTR { + continue + } if err == syscall.EAGAIN && fd.pd.pollable() { if err = fd.pd.waitWrite(fd.isFile); err == nil { continue @@ -379,6 +387,8 @@ func (fd *FD) Accept() (int, syscall.Sockaddr, string, error) { return s, rsa, "", err } switch err { + case syscall.EINTR: + continue case syscall.EAGAIN: if fd.pd.pollable() { if err = fd.pd.waitRead(fd.isFile); err == nil { @@ -413,7 +423,7 @@ func (fd *FD) ReadDirent(buf []byte) (int, error) { } defer fd.decref() for { - n, err := syscall.ReadDirent(fd.Sysfd, buf) + n, err := ignoringEINTR(syscall.ReadDirent, fd.Sysfd, buf) if err != nil { n = 0 if err == syscall.EAGAIN && fd.pd.pollable() { @@ -469,7 +479,7 @@ func DupCloseOnExec(fd int) (int, string, error) { return dupCloseOnExecOld(fd) } -// dupCloseOnExecUnixOld is the traditional way to dup an fd and +// dupCloseOnExecOld is the traditional way to dup an fd and // set its O_CLOEXEC bit, using two system calls. func dupCloseOnExecOld(fd int) (int, string, error) { syscall.ForkLock.RLock() @@ -504,18 +514,7 @@ func (fd *FD) WriteOnce(p []byte) (int, error) { return 0, err } defer fd.writeUnlock() - return syscall.Write(fd.Sysfd, p) -} - -// RawControl invokes the user-defined function f for a non-IO -// operation. -func (fd *FD) RawControl(f func(uintptr)) error { - if err := fd.incref(); err != nil { - return err - } - defer fd.decref() - f(uintptr(fd.Sysfd)) - return nil + return ignoringEINTR(syscall.Write, fd.Sysfd, p) } // RawRead invokes the user-defined function f for a read operation. @@ -555,3 +554,19 @@ func (fd *FD) RawWrite(f func(uintptr) bool) error { } } } + +// ignoringEINTR makes a function call and repeats it if it returns +// an EINTR error. This appears to be required even though we install +// all signal handlers with SA_RESTART: see #22838, #38033, #38836. +// Also #20400 and #36644 are issues in which a signal handler is +// installed without setting SA_RESTART. None of these are the common case, +// but there are enough of them that it seems that we can't avoid +// an EINTR loop. +func ignoringEINTR(fn func(fd int, p []byte) (int, error), fd int, p []byte) (int, error) { + for { + n, err := fn(fd, p) + if err != syscall.EINTR { + return n, err + } + } +} diff --git a/libgo/go/internal/poll/fd_windows.go b/libgo/go/internal/poll/fd_windows.go index f96e441abe1..e1ef6199b37 100644 --- a/libgo/go/internal/poll/fd_windows.go +++ b/libgo/go/internal/poll/fd_windows.go @@ -9,7 +9,6 @@ import ( "internal/race" "internal/syscall/windows" "io" - "runtime" "sync" "syscall" "unicode/utf16" @@ -22,18 +21,6 @@ var ( ioSync uint64 ) -// CancelIo Windows API cancels all outstanding IO for a particular -// socket on current thread. To overcome that limitation, we run -// special goroutine, locked to OS single thread, that both starts -// and cancels IO. It means, there are 2 unavoidable thread switches -// for every IO. -// Some newer versions of Windows has new CancelIoEx API, that does -// not have that limitation and can be used from any thread. This -// package uses CancelIoEx API, if present, otherwise it fallback -// to CancelIo. - -var canCancelIO bool // determines if CancelIoEx API is present - // This package uses the SetFileCompletionNotificationModes Windows // API to skip calling GetQueuedCompletionStatus if an IO operation // completes synchronously. There is a known bug where @@ -72,7 +59,6 @@ func init() { if e != nil { initErr = e } - canCancelIO = syscall.LoadCancelIoEx() == nil checkSetFileCompletionNotificationModes() } @@ -90,7 +76,6 @@ type operation struct { // fields used only by net package fd *FD - errc chan error buf syscall.WSABuf msg windows.WSAMsg sa syscall.Sockaddr @@ -155,46 +140,15 @@ func (o *operation) InitMsg(p []byte, oob []byte) { } } -// ioSrv executes net IO requests. -type ioSrv struct { - req chan ioSrvReq -} - -type ioSrvReq struct { - o *operation - submit func(o *operation) error // if nil, cancel the operation -} - -// ProcessRemoteIO will execute submit IO requests on behalf -// of other goroutines, all on a single os thread, so it can -// cancel them later. Results of all operations will be sent -// back to their requesters via channel supplied in request. -// It is used only when the CancelIoEx API is unavailable. -func (s *ioSrv) ProcessRemoteIO() { - runtime.LockOSThread() - defer runtime.UnlockOSThread() - for r := range s.req { - if r.submit != nil { - r.o.errc <- r.submit(r.o) - } else { - r.o.errc <- syscall.CancelIo(r.o.fd.Sysfd) - } - } -} - -// ExecIO executes a single IO operation o. It submits and cancels +// execIO executes a single IO operation o. It submits and cancels // IO in the current thread for systems where Windows CancelIoEx API // is available. Alternatively, it passes the request onto // runtime netpoll and waits for completion or cancels request. -func (s *ioSrv) ExecIO(o *operation, submit func(o *operation) error) (int, error) { +func execIO(o *operation, submit func(o *operation) error) (int, error) { if o.fd.pd.runtimeCtx == 0 { return 0, errors.New("internal error: polling on unsupported descriptor type") } - if !canCancelIO { - onceStartServer.Do(startServer) - } - fd := o.fd // Notify runtime netpoll about starting IO. err := fd.pd.prepare(int(o.mode), fd.isFile) @@ -202,14 +156,7 @@ func (s *ioSrv) ExecIO(o *operation, submit func(o *operation) error) (int, erro return 0, err } // Start IO. - if canCancelIO { - err = submit(o) - } else { - // Send request to a special dedicated thread, - // so it can stop the IO with CancelIO later. - s.req <- ioSrvReq{o, submit} - err = <-o.errc - } + err = submit(o) switch err { case nil: // IO completed immediately @@ -241,22 +188,17 @@ func (s *ioSrv) ExecIO(o *operation, submit func(o *operation) error) (int, erro // IO is interrupted by "close" or "timeout" netpollErr := err switch netpollErr { - case ErrNetClosing, ErrFileClosing, ErrTimeout: + case ErrNetClosing, ErrFileClosing, ErrDeadlineExceeded: // will deal with those. default: panic("unexpected runtime.netpoll error: " + netpollErr.Error()) } // Cancel our request. - if canCancelIO { - err := syscall.CancelIoEx(fd.Sysfd, &o.o) - // Assuming ERROR_NOT_FOUND is returned, if IO is completed. - if err != nil && err != syscall.ERROR_NOT_FOUND { - // TODO(brainman): maybe do something else, but panic. - panic(err) - } - } else { - s.req <- ioSrvReq{o, nil} - <-o.errc + err = syscall.CancelIoEx(fd.Sysfd, &o.o) + // Assuming ERROR_NOT_FOUND is returned, if IO is completed. + if err != nil && err != syscall.ERROR_NOT_FOUND { + // TODO(brainman): maybe do something else, but panic. + panic(err) } // Wait for cancellation to complete. fd.pd.waitCanceled(int(o.mode)) @@ -273,21 +215,6 @@ func (s *ioSrv) ExecIO(o *operation, submit func(o *operation) error) (int, erro return int(o.qty), nil } -// Start helper goroutines. -var rsrv, wsrv ioSrv -var onceStartServer sync.Once - -func startServer() { - // This is called, once, when only the CancelIo API is available. - // Start two special goroutines, both locked to an OS thread, - // that start and cancel IO requests. - // One will process read requests, while the other will do writes. - rsrv.req = make(chan ioSrvReq) - go rsrv.ProcessRemoteIO() - wsrv.req = make(chan ioSrvReq) - go wsrv.ProcessRemoteIO() -} - // FD is a file descriptor. The net and os packages embed this type in // a larger type representing a network connection or OS file. type FD struct { @@ -385,9 +312,9 @@ func (fd *FD) Init(net string, pollable bool) (string, error) { // if the user is doing their own overlapped I/O. // See issue #21172. // - // In general the code below avoids calling the ExecIO - // method for non-network sockets. If some method does - // somehow call ExecIO, then ExecIO, and therefore the + // In general the code below avoids calling the execIO + // function for non-network sockets. If some method does + // somehow call execIO, then execIO, and therefore the // calling method, will return an error, because // fd.pd.runtimeCtx will be 0. err = fd.pd.init(fd) @@ -402,7 +329,7 @@ func (fd *FD) Init(net string, pollable bool) (string, error) { // We do not use events, so we can skip them always. flags := uint8(syscall.FILE_SKIP_SET_EVENT_ON_HANDLE) // It's not safe to skip completion notifications for UDP: - // https://blogs.technet.com/b/winserverperformance/archive/2008/06/26/designing-applications-for-high-performance-part-iii.aspx + // https://docs.microsoft.com/en-us/archive/blogs/winserverperformance/designing-applications-for-high-performance-part-iii if net == "tcp" { flags |= syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS } @@ -429,10 +356,6 @@ func (fd *FD) Init(net string, pollable bool) (string, error) { fd.wop.fd = fd fd.rop.runtimeCtx = fd.pd.runtimeCtx fd.wop.runtimeCtx = fd.pd.runtimeCtx - if !canCancelIO { - fd.rop.errc = make(chan error) - fd.wop.errc = make(chan error) - } return "", nil } @@ -476,15 +399,6 @@ func (fd *FD) Close() error { return err } -// Shutdown wraps the shutdown network call. -func (fd *FD) Shutdown(how int) error { - if err := fd.incref(); err != nil { - return err - } - defer fd.decref() - return syscall.Shutdown(fd.Sysfd, how) -} - // Windows ReadFile and WSARecv use DWORD (uint32) parameter to pass buffer length. // This prevents us reading blocks larger than 4GB. // See golang.org/issue/26923. @@ -524,7 +438,7 @@ func (fd *FD) Read(buf []byte) (int, error) { } else { o := &fd.rop o.InitBuf(buf) - n, err = rsrv.ExecIO(o, func(o *operation) error { + n, err = execIO(o, func(o *operation) error { return syscall.WSARecv(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil) }) if race.Enabled { @@ -664,7 +578,7 @@ func (fd *FD) ReadFrom(buf []byte) (int, syscall.Sockaddr, error) { defer fd.readUnlock() o := &fd.rop o.InitBuf(buf) - n, err := rsrv.ExecIO(o, func(o *operation) error { + n, err := execIO(o, func(o *operation) error { if o.rsa == nil { o.rsa = new(syscall.RawSockaddrAny) } @@ -720,7 +634,7 @@ func (fd *FD) Write(buf []byte) (int, error) { } o := &fd.wop o.InitBuf(b) - n, err = wsrv.ExecIO(o, func(o *operation) error { + n, err = execIO(o, func(o *operation) error { return syscall.WSASend(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, &o.o, nil) }) } @@ -829,7 +743,7 @@ func (fd *FD) Writev(buf *[][]byte) (int64, error) { } o := &fd.wop o.InitBufs(buf) - n, err := wsrv.ExecIO(o, func(o *operation) error { + n, err := execIO(o, func(o *operation) error { return syscall.WSASend(o.fd.Sysfd, &o.bufs[0], uint32(len(o.bufs)), &o.qty, 0, &o.o, nil) }) o.ClearBufs() @@ -850,7 +764,7 @@ func (fd *FD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) { o := &fd.wop o.InitBuf(buf) o.sa = sa - n, err := wsrv.ExecIO(o, func(o *operation) error { + n, err := execIO(o, func(o *operation) error { return syscall.WSASendto(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil) }) return n, err @@ -865,7 +779,7 @@ func (fd *FD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) { o := &fd.wop o.InitBuf(b) o.sa = sa - n, err := wsrv.ExecIO(o, func(o *operation) error { + n, err := execIO(o, func(o *operation) error { return syscall.WSASendto(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil) }) ntotal += int(n) @@ -883,7 +797,7 @@ func (fd *FD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) { func (fd *FD) ConnectEx(ra syscall.Sockaddr) error { o := &fd.wop o.sa = ra - _, err := wsrv.ExecIO(o, func(o *operation) error { + _, err := execIO(o, func(o *operation) error { return ConnectExFunc(o.fd.Sysfd, o.sa, nil, 0, nil, &o.o) }) return err @@ -893,7 +807,7 @@ func (fd *FD) acceptOne(s syscall.Handle, rawsa []syscall.RawSockaddrAny, o *ope // Submit accept request. o.handle = s o.rsan = int32(unsafe.Sizeof(rawsa[0])) - _, err := rsrv.ExecIO(o, func(o *operation) error { + _, err := execIO(o, func(o *operation) error { return AcceptFunc(o.fd.Sysfd, o.handle, (*byte)(unsafe.Pointer(&rawsa[0])), 0, uint32(o.rsan), uint32(o.rsan), &o.qty, &o.o) }) if err != nil { @@ -999,17 +913,6 @@ func (fd *FD) GetFileInformationByHandle(data *syscall.ByHandleFileInformation) return syscall.GetFileInformationByHandle(fd.Sysfd, data) } -// RawControl invokes the user-defined function f for a non-IO -// operation. -func (fd *FD) RawControl(f func(uintptr)) error { - if err := fd.incref(); err != nil { - return err - } - defer fd.decref() - f(uintptr(fd.Sysfd)) - return nil -} - // RawRead invokes the user-defined function f for a read operation. func (fd *FD) RawRead(f func(uintptr) bool) error { if err := fd.readLock(); err != nil { @@ -1028,7 +931,7 @@ func (fd *FD) RawRead(f func(uintptr) bool) error { if !fd.IsStream { o.flags |= windows.MSG_PEEK } - _, err := rsrv.ExecIO(o, func(o *operation) error { + _, err := execIO(o, func(o *operation) error { return syscall.WSARecv(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil) }) if err == windows.WSAEMSGSIZE { @@ -1096,9 +999,9 @@ func (fd *FD) ReadMsg(p []byte, oob []byte) (int, int, int, syscall.Sockaddr, er o := &fd.rop o.InitMsg(p, oob) o.rsa = new(syscall.RawSockaddrAny) - o.msg.Name = o.rsa + o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa)) o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa)) - n, err := rsrv.ExecIO(o, func(o *operation) error { + n, err := execIO(o, func(o *operation) error { return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil) }) err = fd.eofError(n, err) @@ -1127,10 +1030,10 @@ func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, err if err != nil { return 0, 0, err } - o.msg.Name = (*syscall.RawSockaddrAny)(rsa) + o.msg.Name = (syscall.Pointer)(rsa) o.msg.Namelen = len } - n, err := wsrv.ExecIO(o, func(o *operation) error { + n, err := execIO(o, func(o *operation) error { return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil) }) return n, int(o.msg.Control.Len), err diff --git a/libgo/go/internal/poll/fd_writev_unix.go b/libgo/go/internal/poll/fd_writev_unix.go index 86af795b5a5..daeec96c385 100644 --- a/libgo/go/internal/poll/fd_writev_unix.go +++ b/libgo/go/internal/poll/fd_writev_unix.go @@ -12,9 +12,18 @@ import ( ) func writev(fd int, iovecs []syscall.Iovec) (uintptr, error) { - r, _, e := syscall.Syscall(syscall.SYS_WRITEV, uintptr(fd), uintptr(unsafe.Pointer(&iovecs[0])), uintptr(len(iovecs))) + var ( + r uintptr + e syscall.Errno + ) + for { + r, _, e = syscall.Syscall(syscall.SYS_WRITEV, uintptr(fd), uintptr(unsafe.Pointer(&iovecs[0])), uintptr(len(iovecs))) + if e != syscall.EINTR { + break + } + } if e != 0 { - return r, syscall.Errno(e) + return r, e } return r, nil } diff --git a/libgo/go/internal/poll/sendfile_bsd.go b/libgo/go/internal/poll/sendfile_bsd.go index 40ae3468b07..a24e41dcaa8 100644 --- a/libgo/go/internal/poll/sendfile_bsd.go +++ b/libgo/go/internal/poll/sendfile_bsd.go @@ -35,6 +35,9 @@ func SendFile(dstFD *FD, src int, pos, remain int64) (int64, error) { } else if n == 0 && err1 == nil { break } + if err1 == syscall.EINTR { + continue + } if err1 == syscall.EAGAIN { if err1 = dstFD.pd.waitWrite(dstFD.isFile); err1 == nil { continue diff --git a/libgo/go/internal/poll/sendfile_windows.go b/libgo/go/internal/poll/sendfile_windows.go index 5674af41895..50c3ee86c0f 100644 --- a/libgo/go/internal/poll/sendfile_windows.go +++ b/libgo/go/internal/poll/sendfile_windows.go @@ -57,7 +57,7 @@ func SendFile(fd *FD, src syscall.Handle, n int64) (written int64, err error) { o.o.Offset = uint32(curpos) o.o.OffsetHigh = uint32(curpos >> 32) - nw, err := wsrv.ExecIO(o, func(o *operation) error { + nw, err := execIO(o, func(o *operation) error { return syscall.TransmitFile(o.fd.Sysfd, o.handle, o.qty, 0, &o.o, nil, syscall.TF_WRITE_BEHIND) }) if err != nil { diff --git a/libgo/go/internal/poll/splice_linux.go b/libgo/go/internal/poll/splice_linux.go index 68a57181f4b..ca772e91e59 100644 --- a/libgo/go/internal/poll/splice_linux.go +++ b/libgo/go/internal/poll/splice_linux.go @@ -86,6 +86,9 @@ func spliceDrain(pipefd int, sock *FD, max int) (int, error) { } for { n, err := splice(pipefd, sock.Sysfd, max, spliceNonblock) + if err == syscall.EINTR { + continue + } if err != syscall.EAGAIN { return n, err } diff --git a/libgo/go/internal/poll/writev.go b/libgo/go/internal/poll/writev.go index 6050d1f6423..305e2fd2094 100644 --- a/libgo/go/internal/poll/writev.go +++ b/libgo/go/internal/poll/writev.go @@ -68,7 +68,10 @@ func (fd *FD) Writev(v *[][]byte) (int64, error) { iovecs[i] = syscall.Iovec{} } if err != nil { - if err.(syscall.Errno) == syscall.EAGAIN { + if err == syscall.EINTR { + continue + } + if err == syscall.EAGAIN { if err = fd.pd.waitWrite(fd.isFile); err == nil { continue } diff --git a/libgo/go/internal/profile/encode.go b/libgo/go/internal/profile/encode.go new file mode 100644 index 00000000000..af319330d9a --- /dev/null +++ b/libgo/go/internal/profile/encode.go @@ -0,0 +1,482 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package profile + +import ( + "errors" + "fmt" + "sort" +) + +func (p *Profile) decoder() []decoder { + return profileDecoder +} + +// preEncode populates the unexported fields to be used by encode +// (with suffix X) from the corresponding exported fields. The +// exported fields are cleared up to facilitate testing. +func (p *Profile) preEncode() { + strings := make(map[string]int) + addString(strings, "") + + for _, st := range p.SampleType { + st.typeX = addString(strings, st.Type) + st.unitX = addString(strings, st.Unit) + } + + for _, s := range p.Sample { + s.labelX = nil + var keys []string + for k := range s.Label { + keys = append(keys, k) + } + sort.Strings(keys) + for _, k := range keys { + vs := s.Label[k] + for _, v := range vs { + s.labelX = append(s.labelX, + Label{ + keyX: addString(strings, k), + strX: addString(strings, v), + }, + ) + } + } + var numKeys []string + for k := range s.NumLabel { + numKeys = append(numKeys, k) + } + sort.Strings(numKeys) + for _, k := range numKeys { + vs := s.NumLabel[k] + for _, v := range vs { + s.labelX = append(s.labelX, + Label{ + keyX: addString(strings, k), + numX: v, + }, + ) + } + } + s.locationIDX = nil + for _, l := range s.Location { + s.locationIDX = append(s.locationIDX, l.ID) + } + } + + for _, m := range p.Mapping { + m.fileX = addString(strings, m.File) + m.buildIDX = addString(strings, m.BuildID) + } + + for _, l := range p.Location { + for i, ln := range l.Line { + if ln.Function != nil { + l.Line[i].functionIDX = ln.Function.ID + } else { + l.Line[i].functionIDX = 0 + } + } + if l.Mapping != nil { + l.mappingIDX = l.Mapping.ID + } else { + l.mappingIDX = 0 + } + } + for _, f := range p.Function { + f.nameX = addString(strings, f.Name) + f.systemNameX = addString(strings, f.SystemName) + f.filenameX = addString(strings, f.Filename) + } + + p.dropFramesX = addString(strings, p.DropFrames) + p.keepFramesX = addString(strings, p.KeepFrames) + + if pt := p.PeriodType; pt != nil { + pt.typeX = addString(strings, pt.Type) + pt.unitX = addString(strings, pt.Unit) + } + + p.stringTable = make([]string, len(strings)) + for s, i := range strings { + p.stringTable[i] = s + } +} + +func (p *Profile) encode(b *buffer) { + for _, x := range p.SampleType { + encodeMessage(b, 1, x) + } + for _, x := range p.Sample { + encodeMessage(b, 2, x) + } + for _, x := range p.Mapping { + encodeMessage(b, 3, x) + } + for _, x := range p.Location { + encodeMessage(b, 4, x) + } + for _, x := range p.Function { + encodeMessage(b, 5, x) + } + encodeStrings(b, 6, p.stringTable) + encodeInt64Opt(b, 7, p.dropFramesX) + encodeInt64Opt(b, 8, p.keepFramesX) + encodeInt64Opt(b, 9, p.TimeNanos) + encodeInt64Opt(b, 10, p.DurationNanos) + if pt := p.PeriodType; pt != nil && (pt.typeX != 0 || pt.unitX != 0) { + encodeMessage(b, 11, p.PeriodType) + } + encodeInt64Opt(b, 12, p.Period) +} + +var profileDecoder = []decoder{ + nil, // 0 + // repeated ValueType sample_type = 1 + func(b *buffer, m message) error { + x := new(ValueType) + pp := m.(*Profile) + pp.SampleType = append(pp.SampleType, x) + return decodeMessage(b, x) + }, + // repeated Sample sample = 2 + func(b *buffer, m message) error { + x := new(Sample) + pp := m.(*Profile) + pp.Sample = append(pp.Sample, x) + return decodeMessage(b, x) + }, + // repeated Mapping mapping = 3 + func(b *buffer, m message) error { + x := new(Mapping) + pp := m.(*Profile) + pp.Mapping = append(pp.Mapping, x) + return decodeMessage(b, x) + }, + // repeated Location location = 4 + func(b *buffer, m message) error { + x := new(Location) + pp := m.(*Profile) + pp.Location = append(pp.Location, x) + return decodeMessage(b, x) + }, + // repeated Function function = 5 + func(b *buffer, m message) error { + x := new(Function) + pp := m.(*Profile) + pp.Function = append(pp.Function, x) + return decodeMessage(b, x) + }, + // repeated string string_table = 6 + func(b *buffer, m message) error { + err := decodeStrings(b, &m.(*Profile).stringTable) + if err != nil { + return err + } + if *&m.(*Profile).stringTable[0] != "" { + return errors.New("string_table[0] must be ''") + } + return nil + }, + // repeated int64 drop_frames = 7 + func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).dropFramesX) }, + // repeated int64 keep_frames = 8 + func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).keepFramesX) }, + // repeated int64 time_nanos = 9 + func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).TimeNanos) }, + // repeated int64 duration_nanos = 10 + func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).DurationNanos) }, + // optional string period_type = 11 + func(b *buffer, m message) error { + x := new(ValueType) + pp := m.(*Profile) + pp.PeriodType = x + return decodeMessage(b, x) + }, + // repeated int64 period = 12 + func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).Period) }, + // repeated int64 comment = 13 + func(b *buffer, m message) error { return decodeInt64s(b, &m.(*Profile).commentX) }, + // int64 defaultSampleType = 14 + func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).defaultSampleTypeX) }, +} + +// postDecode takes the unexported fields populated by decode (with +// suffix X) and populates the corresponding exported fields. +// The unexported fields are cleared up to facilitate testing. +func (p *Profile) postDecode() error { + var err error + + mappings := make(map[uint64]*Mapping) + for _, m := range p.Mapping { + m.File, err = getString(p.stringTable, &m.fileX, err) + m.BuildID, err = getString(p.stringTable, &m.buildIDX, err) + mappings[m.ID] = m + } + + functions := make(map[uint64]*Function) + for _, f := range p.Function { + f.Name, err = getString(p.stringTable, &f.nameX, err) + f.SystemName, err = getString(p.stringTable, &f.systemNameX, err) + f.Filename, err = getString(p.stringTable, &f.filenameX, err) + functions[f.ID] = f + } + + locations := make(map[uint64]*Location) + for _, l := range p.Location { + l.Mapping = mappings[l.mappingIDX] + l.mappingIDX = 0 + for i, ln := range l.Line { + if id := ln.functionIDX; id != 0 { + l.Line[i].Function = functions[id] + if l.Line[i].Function == nil { + return fmt.Errorf("Function ID %d not found", id) + } + l.Line[i].functionIDX = 0 + } + } + locations[l.ID] = l + } + + for _, st := range p.SampleType { + st.Type, err = getString(p.stringTable, &st.typeX, err) + st.Unit, err = getString(p.stringTable, &st.unitX, err) + } + + for _, s := range p.Sample { + labels := make(map[string][]string) + numLabels := make(map[string][]int64) + for _, l := range s.labelX { + var key, value string + key, err = getString(p.stringTable, &l.keyX, err) + if l.strX != 0 { + value, err = getString(p.stringTable, &l.strX, err) + labels[key] = append(labels[key], value) + } else { + numLabels[key] = append(numLabels[key], l.numX) + } + } + if len(labels) > 0 { + s.Label = labels + } + if len(numLabels) > 0 { + s.NumLabel = numLabels + } + s.Location = nil + for _, lid := range s.locationIDX { + s.Location = append(s.Location, locations[lid]) + } + s.locationIDX = nil + } + + p.DropFrames, err = getString(p.stringTable, &p.dropFramesX, err) + p.KeepFrames, err = getString(p.stringTable, &p.keepFramesX, err) + + if pt := p.PeriodType; pt == nil { + p.PeriodType = &ValueType{} + } + + if pt := p.PeriodType; pt != nil { + pt.Type, err = getString(p.stringTable, &pt.typeX, err) + pt.Unit, err = getString(p.stringTable, &pt.unitX, err) + } + for _, i := range p.commentX { + var c string + c, err = getString(p.stringTable, &i, err) + p.Comments = append(p.Comments, c) + } + + p.commentX = nil + p.DefaultSampleType, err = getString(p.stringTable, &p.defaultSampleTypeX, err) + p.stringTable = nil + return nil +} + +func (p *ValueType) decoder() []decoder { + return valueTypeDecoder +} + +func (p *ValueType) encode(b *buffer) { + encodeInt64Opt(b, 1, p.typeX) + encodeInt64Opt(b, 2, p.unitX) +} + +var valueTypeDecoder = []decoder{ + nil, // 0 + // optional int64 type = 1 + func(b *buffer, m message) error { return decodeInt64(b, &m.(*ValueType).typeX) }, + // optional int64 unit = 2 + func(b *buffer, m message) error { return decodeInt64(b, &m.(*ValueType).unitX) }, +} + +func (p *Sample) decoder() []decoder { + return sampleDecoder +} + +func (p *Sample) encode(b *buffer) { + encodeUint64s(b, 1, p.locationIDX) + for _, x := range p.Value { + encodeInt64(b, 2, x) + } + for _, x := range p.labelX { + encodeMessage(b, 3, x) + } +} + +var sampleDecoder = []decoder{ + nil, // 0 + // repeated uint64 location = 1 + func(b *buffer, m message) error { return decodeUint64s(b, &m.(*Sample).locationIDX) }, + // repeated int64 value = 2 + func(b *buffer, m message) error { return decodeInt64s(b, &m.(*Sample).Value) }, + // repeated Label label = 3 + func(b *buffer, m message) error { + s := m.(*Sample) + n := len(s.labelX) + s.labelX = append(s.labelX, Label{}) + return decodeMessage(b, &s.labelX[n]) + }, +} + +func (p Label) decoder() []decoder { + return labelDecoder +} + +func (p Label) encode(b *buffer) { + encodeInt64Opt(b, 1, p.keyX) + encodeInt64Opt(b, 2, p.strX) + encodeInt64Opt(b, 3, p.numX) +} + +var labelDecoder = []decoder{ + nil, // 0 + // optional int64 key = 1 + func(b *buffer, m message) error { return decodeInt64(b, &m.(*Label).keyX) }, + // optional int64 str = 2 + func(b *buffer, m message) error { return decodeInt64(b, &m.(*Label).strX) }, + // optional int64 num = 3 + func(b *buffer, m message) error { return decodeInt64(b, &m.(*Label).numX) }, +} + +func (p *Mapping) decoder() []decoder { + return mappingDecoder +} + +func (p *Mapping) encode(b *buffer) { + encodeUint64Opt(b, 1, p.ID) + encodeUint64Opt(b, 2, p.Start) + encodeUint64Opt(b, 3, p.Limit) + encodeUint64Opt(b, 4, p.Offset) + encodeInt64Opt(b, 5, p.fileX) + encodeInt64Opt(b, 6, p.buildIDX) + encodeBoolOpt(b, 7, p.HasFunctions) + encodeBoolOpt(b, 8, p.HasFilenames) + encodeBoolOpt(b, 9, p.HasLineNumbers) + encodeBoolOpt(b, 10, p.HasInlineFrames) +} + +var mappingDecoder = []decoder{ + nil, // 0 + func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).ID) }, // optional uint64 id = 1 + func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Start) }, // optional uint64 memory_offset = 2 + func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Limit) }, // optional uint64 memory_limit = 3 + func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Offset) }, // optional uint64 file_offset = 4 + func(b *buffer, m message) error { return decodeInt64(b, &m.(*Mapping).fileX) }, // optional int64 filename = 5 + func(b *buffer, m message) error { return decodeInt64(b, &m.(*Mapping).buildIDX) }, // optional int64 build_id = 6 + func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasFunctions) }, // optional bool has_functions = 7 + func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasFilenames) }, // optional bool has_filenames = 8 + func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasLineNumbers) }, // optional bool has_line_numbers = 9 + func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasInlineFrames) }, // optional bool has_inline_frames = 10 +} + +func (p *Location) decoder() []decoder { + return locationDecoder +} + +func (p *Location) encode(b *buffer) { + encodeUint64Opt(b, 1, p.ID) + encodeUint64Opt(b, 2, p.mappingIDX) + encodeUint64Opt(b, 3, p.Address) + for i := range p.Line { + encodeMessage(b, 4, &p.Line[i]) + } +} + +var locationDecoder = []decoder{ + nil, // 0 + func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).ID) }, // optional uint64 id = 1; + func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).mappingIDX) }, // optional uint64 mapping_id = 2; + func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).Address) }, // optional uint64 address = 3; + func(b *buffer, m message) error { // repeated Line line = 4 + pp := m.(*Location) + n := len(pp.Line) + pp.Line = append(pp.Line, Line{}) + return decodeMessage(b, &pp.Line[n]) + }, +} + +func (p *Line) decoder() []decoder { + return lineDecoder +} + +func (p *Line) encode(b *buffer) { + encodeUint64Opt(b, 1, p.functionIDX) + encodeInt64Opt(b, 2, p.Line) +} + +var lineDecoder = []decoder{ + nil, // 0 + // optional uint64 function_id = 1 + func(b *buffer, m message) error { return decodeUint64(b, &m.(*Line).functionIDX) }, + // optional int64 line = 2 + func(b *buffer, m message) error { return decodeInt64(b, &m.(*Line).Line) }, +} + +func (p *Function) decoder() []decoder { + return functionDecoder +} + +func (p *Function) encode(b *buffer) { + encodeUint64Opt(b, 1, p.ID) + encodeInt64Opt(b, 2, p.nameX) + encodeInt64Opt(b, 3, p.systemNameX) + encodeInt64Opt(b, 4, p.filenameX) + encodeInt64Opt(b, 5, p.StartLine) +} + +var functionDecoder = []decoder{ + nil, // 0 + // optional uint64 id = 1 + func(b *buffer, m message) error { return decodeUint64(b, &m.(*Function).ID) }, + // optional int64 function_name = 2 + func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).nameX) }, + // optional int64 function_system_name = 3 + func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).systemNameX) }, + // repeated int64 filename = 4 + func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).filenameX) }, + // optional int64 start_line = 5 + func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).StartLine) }, +} + +func addString(strings map[string]int, s string) int64 { + i, ok := strings[s] + if !ok { + i = len(strings) + strings[s] = i + } + return int64(i) +} + +func getString(strings []string, strng *int64, err error) (string, error) { + if err != nil { + return "", err + } + s := int(*strng) + if s < 0 || s >= len(strings) { + return "", errMalformed + } + *strng = 0 + return strings[s], nil +} diff --git a/libgo/go/internal/profile/filter.go b/libgo/go/internal/profile/filter.go new file mode 100644 index 00000000000..9cad866df8c --- /dev/null +++ b/libgo/go/internal/profile/filter.go @@ -0,0 +1,158 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Implements methods to filter samples from profiles. + +package profile + +import "regexp" + +// FilterSamplesByName filters the samples in a profile and only keeps +// samples where at least one frame matches focus but none match ignore. +// Returns true is the corresponding regexp matched at least one sample. +func (p *Profile) FilterSamplesByName(focus, ignore, hide *regexp.Regexp) (fm, im, hm bool) { + focusOrIgnore := make(map[uint64]bool) + hidden := make(map[uint64]bool) + for _, l := range p.Location { + if ignore != nil && l.matchesName(ignore) { + im = true + focusOrIgnore[l.ID] = false + } else if focus == nil || l.matchesName(focus) { + fm = true + focusOrIgnore[l.ID] = true + } + if hide != nil && l.matchesName(hide) { + hm = true + l.Line = l.unmatchedLines(hide) + if len(l.Line) == 0 { + hidden[l.ID] = true + } + } + } + + s := make([]*Sample, 0, len(p.Sample)) + for _, sample := range p.Sample { + if focusedAndNotIgnored(sample.Location, focusOrIgnore) { + if len(hidden) > 0 { + var locs []*Location + for _, loc := range sample.Location { + if !hidden[loc.ID] { + locs = append(locs, loc) + } + } + if len(locs) == 0 { + // Remove sample with no locations (by not adding it to s). + continue + } + sample.Location = locs + } + s = append(s, sample) + } + } + p.Sample = s + + return +} + +// matchesName reports whether the function name or file in the +// location matches the regular expression. +func (loc *Location) matchesName(re *regexp.Regexp) bool { + for _, ln := range loc.Line { + if fn := ln.Function; fn != nil { + if re.MatchString(fn.Name) { + return true + } + if re.MatchString(fn.Filename) { + return true + } + } + } + return false +} + +// unmatchedLines returns the lines in the location that do not match +// the regular expression. +func (loc *Location) unmatchedLines(re *regexp.Regexp) []Line { + var lines []Line + for _, ln := range loc.Line { + if fn := ln.Function; fn != nil { + if re.MatchString(fn.Name) { + continue + } + if re.MatchString(fn.Filename) { + continue + } + } + lines = append(lines, ln) + } + return lines +} + +// focusedAndNotIgnored looks up a slice of ids against a map of +// focused/ignored locations. The map only contains locations that are +// explicitly focused or ignored. Returns whether there is at least +// one focused location but no ignored locations. +func focusedAndNotIgnored(locs []*Location, m map[uint64]bool) bool { + var f bool + for _, loc := range locs { + if focus, focusOrIgnore := m[loc.ID]; focusOrIgnore { + if focus { + // Found focused location. Must keep searching in case there + // is an ignored one as well. + f = true + } else { + // Found ignored location. Can return false right away. + return false + } + } + } + return f +} + +// TagMatch selects tags for filtering +type TagMatch func(key, val string, nval int64) bool + +// FilterSamplesByTag removes all samples from the profile, except +// those that match focus and do not match the ignore regular +// expression. +func (p *Profile) FilterSamplesByTag(focus, ignore TagMatch) (fm, im bool) { + samples := make([]*Sample, 0, len(p.Sample)) + for _, s := range p.Sample { + focused, ignored := focusedSample(s, focus, ignore) + fm = fm || focused + im = im || ignored + if focused && !ignored { + samples = append(samples, s) + } + } + p.Sample = samples + return +} + +// focusedTag checks a sample against focus and ignore regexps. +// Returns whether the focus/ignore regexps match any tags +func focusedSample(s *Sample, focus, ignore TagMatch) (fm, im bool) { + fm = focus == nil + for key, vals := range s.Label { + for _, val := range vals { + if ignore != nil && ignore(key, val, 0) { + im = true + } + if !fm && focus(key, val, 0) { + fm = true + } + } + } + for key, vals := range s.NumLabel { + for _, val := range vals { + if ignore != nil && ignore(key, "", val) { + im = true + } + if !fm && focus(key, "", val) { + fm = true + } + } + } + return fm, im +} diff --git a/libgo/go/internal/profile/legacy_profile.go b/libgo/go/internal/profile/legacy_profile.go new file mode 100644 index 00000000000..d69f8deee7c --- /dev/null +++ b/libgo/go/internal/profile/legacy_profile.go @@ -0,0 +1,1266 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements parsers to convert legacy profiles into the +// profile.proto format. + +package profile + +import ( + "bufio" + "bytes" + "fmt" + "io" + "math" + "regexp" + "strconv" + "strings" +) + +var ( + countStartRE = regexp.MustCompile(`\A(\w+) profile: total \d+\n\z`) + countRE = regexp.MustCompile(`\A(\d+) @(( 0x[0-9a-f]+)+)\n\z`) + + heapHeaderRE = regexp.MustCompile(`heap profile: *(\d+): *(\d+) *\[ *(\d+): *(\d+) *\] *@ *(heap[_a-z0-9]*)/?(\d*)`) + heapSampleRE = regexp.MustCompile(`(-?\d+): *(-?\d+) *\[ *(\d+): *(\d+) *] @([ x0-9a-f]*)`) + + contentionSampleRE = regexp.MustCompile(`(\d+) *(\d+) @([ x0-9a-f]*)`) + + hexNumberRE = regexp.MustCompile(`0x[0-9a-f]+`) + + growthHeaderRE = regexp.MustCompile(`heap profile: *(\d+): *(\d+) *\[ *(\d+): *(\d+) *\] @ growthz`) + + fragmentationHeaderRE = regexp.MustCompile(`heap profile: *(\d+): *(\d+) *\[ *(\d+): *(\d+) *\] @ fragmentationz`) + + threadzStartRE = regexp.MustCompile(`--- threadz \d+ ---`) + threadStartRE = regexp.MustCompile(`--- Thread ([[:xdigit:]]+) \(name: (.*)/(\d+)\) stack: ---`) + + procMapsRE = regexp.MustCompile(`([[:xdigit:]]+)-([[:xdigit:]]+)\s+([-rwxp]+)\s+([[:xdigit:]]+)\s+([[:xdigit:]]+):([[:xdigit:]]+)\s+([[:digit:]]+)\s*(\S+)?`) + + briefMapsRE = regexp.MustCompile(`\s*([[:xdigit:]]+)-([[:xdigit:]]+):\s*(\S+)(\s.*@)?([[:xdigit:]]+)?`) + + // LegacyHeapAllocated instructs the heapz parsers to use the + // allocated memory stats instead of the default in-use memory. Note + // that tcmalloc doesn't provide all allocated memory, only in-use + // stats. + LegacyHeapAllocated bool +) + +func isSpaceOrComment(line string) bool { + trimmed := strings.TrimSpace(line) + return len(trimmed) == 0 || trimmed[0] == '#' +} + +// parseGoCount parses a Go count profile (e.g., threadcreate or +// goroutine) and returns a new Profile. +func parseGoCount(b []byte) (*Profile, error) { + r := bytes.NewBuffer(b) + + var line string + var err error + for { + // Skip past comments and empty lines seeking a real header. + line, err = r.ReadString('\n') + if err != nil { + return nil, err + } + if !isSpaceOrComment(line) { + break + } + } + + m := countStartRE.FindStringSubmatch(line) + if m == nil { + return nil, errUnrecognized + } + profileType := m[1] + p := &Profile{ + PeriodType: &ValueType{Type: profileType, Unit: "count"}, + Period: 1, + SampleType: []*ValueType{{Type: profileType, Unit: "count"}}, + } + locations := make(map[uint64]*Location) + for { + line, err = r.ReadString('\n') + if err != nil { + if err == io.EOF { + break + } + return nil, err + } + if isSpaceOrComment(line) { + continue + } + if strings.HasPrefix(line, "---") { + break + } + m := countRE.FindStringSubmatch(line) + if m == nil { + return nil, errMalformed + } + n, err := strconv.ParseInt(m[1], 0, 64) + if err != nil { + return nil, errMalformed + } + fields := strings.Fields(m[2]) + locs := make([]*Location, 0, len(fields)) + for _, stk := range fields { + addr, err := strconv.ParseUint(stk, 0, 64) + if err != nil { + return nil, errMalformed + } + // Adjust all frames by -1 to land on the call instruction. + addr-- + loc := locations[addr] + if loc == nil { + loc = &Location{ + Address: addr, + } + locations[addr] = loc + p.Location = append(p.Location, loc) + } + locs = append(locs, loc) + } + p.Sample = append(p.Sample, &Sample{ + Location: locs, + Value: []int64{n}, + }) + } + + if err = parseAdditionalSections(strings.TrimSpace(line), r, p); err != nil { + return nil, err + } + return p, nil +} + +// remapLocationIDs ensures there is a location for each address +// referenced by a sample, and remaps the samples to point to the new +// location ids. +func (p *Profile) remapLocationIDs() { + seen := make(map[*Location]bool, len(p.Location)) + var locs []*Location + + for _, s := range p.Sample { + for _, l := range s.Location { + if seen[l] { + continue + } + l.ID = uint64(len(locs) + 1) + locs = append(locs, l) + seen[l] = true + } + } + p.Location = locs +} + +func (p *Profile) remapFunctionIDs() { + seen := make(map[*Function]bool, len(p.Function)) + var fns []*Function + + for _, l := range p.Location { + for _, ln := range l.Line { + fn := ln.Function + if fn == nil || seen[fn] { + continue + } + fn.ID = uint64(len(fns) + 1) + fns = append(fns, fn) + seen[fn] = true + } + } + p.Function = fns +} + +// remapMappingIDs matches location addresses with existing mappings +// and updates them appropriately. This is O(N*M), if this ever shows +// up as a bottleneck, evaluate sorting the mappings and doing a +// binary search, which would make it O(N*log(M)). +func (p *Profile) remapMappingIDs() { + if len(p.Mapping) == 0 { + return + } + + // Some profile handlers will incorrectly set regions for the main + // executable if its section is remapped. Fix them through heuristics. + + // Remove the initial mapping if named '/anon_hugepage' and has a + // consecutive adjacent mapping. + if m := p.Mapping[0]; strings.HasPrefix(m.File, "/anon_hugepage") { + if len(p.Mapping) > 1 && m.Limit == p.Mapping[1].Start { + p.Mapping = p.Mapping[1:] + } + } + + // Subtract the offset from the start of the main mapping if it + // ends up at a recognizable start address. + const expectedStart = 0x400000 + if m := p.Mapping[0]; m.Start-m.Offset == expectedStart { + m.Start = expectedStart + m.Offset = 0 + } + + for _, l := range p.Location { + if a := l.Address; a != 0 { + for _, m := range p.Mapping { + if m.Start <= a && a < m.Limit { + l.Mapping = m + break + } + } + } + } + + // Reset all mapping IDs. + for i, m := range p.Mapping { + m.ID = uint64(i + 1) + } +} + +var cpuInts = []func([]byte) (uint64, []byte){ + get32l, + get32b, + get64l, + get64b, +} + +func get32l(b []byte) (uint64, []byte) { + if len(b) < 4 { + return 0, nil + } + return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24, b[4:] +} + +func get32b(b []byte) (uint64, []byte) { + if len(b) < 4 { + return 0, nil + } + return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24, b[4:] +} + +func get64l(b []byte) (uint64, []byte) { + if len(b) < 8 { + return 0, nil + } + return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56, b[8:] +} + +func get64b(b []byte) (uint64, []byte) { + if len(b) < 8 { + return 0, nil + } + return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56, b[8:] +} + +// ParseTracebacks parses a set of tracebacks and returns a newly +// populated profile. It will accept any text file and generate a +// Profile out of it with any hex addresses it can identify, including +// a process map if it can recognize one. Each sample will include a +// tag "source" with the addresses recognized in string format. +func ParseTracebacks(b []byte) (*Profile, error) { + r := bytes.NewBuffer(b) + + p := &Profile{ + PeriodType: &ValueType{Type: "trace", Unit: "count"}, + Period: 1, + SampleType: []*ValueType{ + {Type: "trace", Unit: "count"}, + }, + } + + var sources []string + var sloc []*Location + + locs := make(map[uint64]*Location) + for { + l, err := r.ReadString('\n') + if err != nil { + if err != io.EOF { + return nil, err + } + if l == "" { + break + } + } + if sectionTrigger(l) == memoryMapSection { + break + } + if s, addrs := extractHexAddresses(l); len(s) > 0 { + for _, addr := range addrs { + // Addresses from stack traces point to the next instruction after + // each call. Adjust by -1 to land somewhere on the actual call. + addr-- + loc := locs[addr] + if locs[addr] == nil { + loc = &Location{ + Address: addr, + } + p.Location = append(p.Location, loc) + locs[addr] = loc + } + sloc = append(sloc, loc) + } + + sources = append(sources, s...) + } else { + if len(sources) > 0 || len(sloc) > 0 { + addTracebackSample(sloc, sources, p) + sloc, sources = nil, nil + } + } + } + + // Add final sample to save any leftover data. + if len(sources) > 0 || len(sloc) > 0 { + addTracebackSample(sloc, sources, p) + } + + if err := p.ParseMemoryMap(r); err != nil { + return nil, err + } + return p, nil +} + +func addTracebackSample(l []*Location, s []string, p *Profile) { + p.Sample = append(p.Sample, + &Sample{ + Value: []int64{1}, + Location: l, + Label: map[string][]string{"source": s}, + }) +} + +// parseCPU parses a profilez legacy profile and returns a newly +// populated Profile. +// +// The general format for profilez samples is a sequence of words in +// binary format. The first words are a header with the following data: +// 1st word -- 0 +// 2nd word -- 3 +// 3rd word -- 0 if a c++ application, 1 if a java application. +// 4th word -- Sampling period (in microseconds). +// 5th word -- Padding. +func parseCPU(b []byte) (*Profile, error) { + var parse func([]byte) (uint64, []byte) + var n1, n2, n3, n4, n5 uint64 + for _, parse = range cpuInts { + var tmp []byte + n1, tmp = parse(b) + n2, tmp = parse(tmp) + n3, tmp = parse(tmp) + n4, tmp = parse(tmp) + n5, tmp = parse(tmp) + + if tmp != nil && n1 == 0 && n2 == 3 && n3 == 0 && n4 > 0 && n5 == 0 { + b = tmp + return cpuProfile(b, int64(n4), parse) + } + } + return nil, errUnrecognized +} + +// cpuProfile returns a new Profile from C++ profilez data. +// b is the profile bytes after the header, period is the profiling +// period, and parse is a function to parse 8-byte chunks from the +// profile in its native endianness. +func cpuProfile(b []byte, period int64, parse func(b []byte) (uint64, []byte)) (*Profile, error) { + p := &Profile{ + Period: period * 1000, + PeriodType: &ValueType{Type: "cpu", Unit: "nanoseconds"}, + SampleType: []*ValueType{ + {Type: "samples", Unit: "count"}, + {Type: "cpu", Unit: "nanoseconds"}, + }, + } + var err error + if b, _, err = parseCPUSamples(b, parse, true, p); err != nil { + return nil, err + } + + // If all samples have the same second-to-the-bottom frame, it + // strongly suggests that it is an uninteresting artifact of + // measurement -- a stack frame pushed by the signal handler. The + // bottom frame is always correct as it is picked up from the signal + // structure, not the stack. Check if this is the case and if so, + // remove. + if len(p.Sample) > 1 && len(p.Sample[0].Location) > 1 { + allSame := true + id1 := p.Sample[0].Location[1].Address + for _, s := range p.Sample { + if len(s.Location) < 2 || id1 != s.Location[1].Address { + allSame = false + break + } + } + if allSame { + for _, s := range p.Sample { + s.Location = append(s.Location[:1], s.Location[2:]...) + } + } + } + + if err := p.ParseMemoryMap(bytes.NewBuffer(b)); err != nil { + return nil, err + } + return p, nil +} + +// parseCPUSamples parses a collection of profilez samples from a +// profile. +// +// profilez samples are a repeated sequence of stack frames of the +// form: +// 1st word -- The number of times this stack was encountered. +// 2nd word -- The size of the stack (StackSize). +// 3rd word -- The first address on the stack. +// ... +// StackSize + 2 -- The last address on the stack +// The last stack trace is of the form: +// 1st word -- 0 +// 2nd word -- 1 +// 3rd word -- 0 +// +// Addresses from stack traces may point to the next instruction after +// each call. Optionally adjust by -1 to land somewhere on the actual +// call (except for the leaf, which is not a call). +func parseCPUSamples(b []byte, parse func(b []byte) (uint64, []byte), adjust bool, p *Profile) ([]byte, map[uint64]*Location, error) { + locs := make(map[uint64]*Location) + for len(b) > 0 { + var count, nstk uint64 + count, b = parse(b) + nstk, b = parse(b) + if b == nil || nstk > uint64(len(b)/4) { + return nil, nil, errUnrecognized + } + var sloc []*Location + addrs := make([]uint64, nstk) + for i := 0; i < int(nstk); i++ { + addrs[i], b = parse(b) + } + + if count == 0 && nstk == 1 && addrs[0] == 0 { + // End of data marker + break + } + for i, addr := range addrs { + if adjust && i > 0 { + addr-- + } + loc := locs[addr] + if loc == nil { + loc = &Location{ + Address: addr, + } + locs[addr] = loc + p.Location = append(p.Location, loc) + } + sloc = append(sloc, loc) + } + p.Sample = append(p.Sample, + &Sample{ + Value: []int64{int64(count), int64(count) * p.Period}, + Location: sloc, + }) + } + // Reached the end without finding the EOD marker. + return b, locs, nil +} + +// parseHeap parses a heapz legacy or a growthz profile and +// returns a newly populated Profile. +func parseHeap(b []byte) (p *Profile, err error) { + r := bytes.NewBuffer(b) + l, err := r.ReadString('\n') + if err != nil { + return nil, errUnrecognized + } + + sampling := "" + + if header := heapHeaderRE.FindStringSubmatch(l); header != nil { + p = &Profile{ + SampleType: []*ValueType{ + {Type: "objects", Unit: "count"}, + {Type: "space", Unit: "bytes"}, + }, + PeriodType: &ValueType{Type: "objects", Unit: "bytes"}, + } + + var period int64 + if len(header[6]) > 0 { + if period, err = strconv.ParseInt(header[6], 10, 64); err != nil { + return nil, errUnrecognized + } + } + + switch header[5] { + case "heapz_v2", "heap_v2": + sampling, p.Period = "v2", period + case "heapprofile": + sampling, p.Period = "", 1 + case "heap": + sampling, p.Period = "v2", period/2 + default: + return nil, errUnrecognized + } + } else if header = growthHeaderRE.FindStringSubmatch(l); header != nil { + p = &Profile{ + SampleType: []*ValueType{ + {Type: "objects", Unit: "count"}, + {Type: "space", Unit: "bytes"}, + }, + PeriodType: &ValueType{Type: "heapgrowth", Unit: "count"}, + Period: 1, + } + } else if header = fragmentationHeaderRE.FindStringSubmatch(l); header != nil { + p = &Profile{ + SampleType: []*ValueType{ + {Type: "objects", Unit: "count"}, + {Type: "space", Unit: "bytes"}, + }, + PeriodType: &ValueType{Type: "allocations", Unit: "count"}, + Period: 1, + } + } else { + return nil, errUnrecognized + } + + if LegacyHeapAllocated { + for _, st := range p.SampleType { + st.Type = "alloc_" + st.Type + } + } else { + for _, st := range p.SampleType { + st.Type = "inuse_" + st.Type + } + } + + locs := make(map[uint64]*Location) + for { + l, err = r.ReadString('\n') + if err != nil { + if err != io.EOF { + return nil, err + } + + if l == "" { + break + } + } + + if isSpaceOrComment(l) { + continue + } + l = strings.TrimSpace(l) + + if sectionTrigger(l) != unrecognizedSection { + break + } + + value, blocksize, addrs, err := parseHeapSample(l, p.Period, sampling) + if err != nil { + return nil, err + } + var sloc []*Location + for _, addr := range addrs { + // Addresses from stack traces point to the next instruction after + // each call. Adjust by -1 to land somewhere on the actual call. + addr-- + loc := locs[addr] + if locs[addr] == nil { + loc = &Location{ + Address: addr, + } + p.Location = append(p.Location, loc) + locs[addr] = loc + } + sloc = append(sloc, loc) + } + + p.Sample = append(p.Sample, &Sample{ + Value: value, + Location: sloc, + NumLabel: map[string][]int64{"bytes": {blocksize}}, + }) + } + + if err = parseAdditionalSections(l, r, p); err != nil { + return nil, err + } + return p, nil +} + +// parseHeapSample parses a single row from a heap profile into a new Sample. +func parseHeapSample(line string, rate int64, sampling string) (value []int64, blocksize int64, addrs []uint64, err error) { + sampleData := heapSampleRE.FindStringSubmatch(line) + if len(sampleData) != 6 { + return value, blocksize, addrs, fmt.Errorf("unexpected number of sample values: got %d, want 6", len(sampleData)) + } + + // Use first two values by default; tcmalloc sampling generates the + // same value for both, only the older heap-profile collect separate + // stats for in-use and allocated objects. + valueIndex := 1 + if LegacyHeapAllocated { + valueIndex = 3 + } + + var v1, v2 int64 + if v1, err = strconv.ParseInt(sampleData[valueIndex], 10, 64); err != nil { + return value, blocksize, addrs, fmt.Errorf("malformed sample: %s: %v", line, err) + } + if v2, err = strconv.ParseInt(sampleData[valueIndex+1], 10, 64); err != nil { + return value, blocksize, addrs, fmt.Errorf("malformed sample: %s: %v", line, err) + } + + if v1 == 0 { + if v2 != 0 { + return value, blocksize, addrs, fmt.Errorf("allocation count was 0 but allocation bytes was %d", v2) + } + } else { + blocksize = v2 / v1 + if sampling == "v2" { + v1, v2 = scaleHeapSample(v1, v2, rate) + } + } + + value = []int64{v1, v2} + addrs = parseHexAddresses(sampleData[5]) + + return value, blocksize, addrs, nil +} + +// extractHexAddresses extracts hex numbers from a string and returns +// them, together with their numeric value, in a slice. +func extractHexAddresses(s string) ([]string, []uint64) { + hexStrings := hexNumberRE.FindAllString(s, -1) + var ids []uint64 + for _, s := range hexStrings { + if id, err := strconv.ParseUint(s, 0, 64); err == nil { + ids = append(ids, id) + } else { + // Do not expect any parsing failures due to the regexp matching. + panic("failed to parse hex value:" + s) + } + } + return hexStrings, ids +} + +// parseHexAddresses parses hex numbers from a string and returns them +// in a slice. +func parseHexAddresses(s string) []uint64 { + _, ids := extractHexAddresses(s) + return ids +} + +// scaleHeapSample adjusts the data from a heapz Sample to +// account for its probability of appearing in the collected +// data. heapz profiles are a sampling of the memory allocations +// requests in a program. We estimate the unsampled value by dividing +// each collected sample by its probability of appearing in the +// profile. heapz v2 profiles rely on a poisson process to determine +// which samples to collect, based on the desired average collection +// rate R. The probability of a sample of size S to appear in that +// profile is 1-exp(-S/R). +func scaleHeapSample(count, size, rate int64) (int64, int64) { + if count == 0 || size == 0 { + return 0, 0 + } + + if rate <= 1 { + // if rate==1 all samples were collected so no adjustment is needed. + // if rate<1 treat as unknown and skip scaling. + return count, size + } + + avgSize := float64(size) / float64(count) + scale := 1 / (1 - math.Exp(-avgSize/float64(rate))) + + return int64(float64(count) * scale), int64(float64(size) * scale) +} + +// parseContention parses a mutex or contention profile. There are 2 cases: +// "--- contentionz " for legacy C++ profiles (and backwards compatibility) +// "--- mutex:" or "--- contention:" for profiles generated by the Go runtime. +// This code converts the text output from runtime into a *Profile. (In the future +// the runtime might write a serialized Profile directly making this unnecessary.) +func parseContention(b []byte) (*Profile, error) { + r := bytes.NewBuffer(b) + var l string + var err error + for { + // Skip past comments and empty lines seeking a real header. + l, err = r.ReadString('\n') + if err != nil { + return nil, err + } + if !isSpaceOrComment(l) { + break + } + } + + if strings.HasPrefix(l, "--- contentionz ") { + return parseCppContention(r) + } else if strings.HasPrefix(l, "--- mutex:") { + return parseCppContention(r) + } else if strings.HasPrefix(l, "--- contention:") { + return parseCppContention(r) + } + return nil, errUnrecognized +} + +// parseCppContention parses the output from synchronization_profiling.cc +// for backward compatibility, and the compatible (non-debug) block profile +// output from the Go runtime. +func parseCppContention(r *bytes.Buffer) (*Profile, error) { + p := &Profile{ + PeriodType: &ValueType{Type: "contentions", Unit: "count"}, + Period: 1, + SampleType: []*ValueType{ + {Type: "contentions", Unit: "count"}, + {Type: "delay", Unit: "nanoseconds"}, + }, + } + + var cpuHz int64 + var l string + var err error + // Parse text of the form "attribute = value" before the samples. + const delimiter = "=" + for { + l, err = r.ReadString('\n') + if err != nil { + if err != io.EOF { + return nil, err + } + + if l == "" { + break + } + } + if isSpaceOrComment(l) { + continue + } + + if l = strings.TrimSpace(l); l == "" { + continue + } + + if strings.HasPrefix(l, "---") { + break + } + + attr := strings.SplitN(l, delimiter, 2) + if len(attr) != 2 { + break + } + key, val := strings.TrimSpace(attr[0]), strings.TrimSpace(attr[1]) + var err error + switch key { + case "cycles/second": + if cpuHz, err = strconv.ParseInt(val, 0, 64); err != nil { + return nil, errUnrecognized + } + case "sampling period": + if p.Period, err = strconv.ParseInt(val, 0, 64); err != nil { + return nil, errUnrecognized + } + case "ms since reset": + ms, err := strconv.ParseInt(val, 0, 64) + if err != nil { + return nil, errUnrecognized + } + p.DurationNanos = ms * 1000 * 1000 + case "format": + // CPP contentionz profiles don't have format. + return nil, errUnrecognized + case "resolution": + // CPP contentionz profiles don't have resolution. + return nil, errUnrecognized + case "discarded samples": + default: + return nil, errUnrecognized + } + } + + locs := make(map[uint64]*Location) + for { + if !isSpaceOrComment(l) { + if l = strings.TrimSpace(l); strings.HasPrefix(l, "---") { + break + } + value, addrs, err := parseContentionSample(l, p.Period, cpuHz) + if err != nil { + return nil, err + } + var sloc []*Location + for _, addr := range addrs { + // Addresses from stack traces point to the next instruction after + // each call. Adjust by -1 to land somewhere on the actual call. + addr-- + loc := locs[addr] + if locs[addr] == nil { + loc = &Location{ + Address: addr, + } + p.Location = append(p.Location, loc) + locs[addr] = loc + } + sloc = append(sloc, loc) + } + p.Sample = append(p.Sample, &Sample{ + Value: value, + Location: sloc, + }) + } + + if l, err = r.ReadString('\n'); err != nil { + if err != io.EOF { + return nil, err + } + if l == "" { + break + } + } + } + + if err = parseAdditionalSections(l, r, p); err != nil { + return nil, err + } + + return p, nil +} + +// parseContentionSample parses a single row from a contention profile +// into a new Sample. +func parseContentionSample(line string, period, cpuHz int64) (value []int64, addrs []uint64, err error) { + sampleData := contentionSampleRE.FindStringSubmatch(line) + if sampleData == nil { + return value, addrs, errUnrecognized + } + + v1, err := strconv.ParseInt(sampleData[1], 10, 64) + if err != nil { + return value, addrs, fmt.Errorf("malformed sample: %s: %v", line, err) + } + v2, err := strconv.ParseInt(sampleData[2], 10, 64) + if err != nil { + return value, addrs, fmt.Errorf("malformed sample: %s: %v", line, err) + } + + // Unsample values if period and cpuHz are available. + // - Delays are scaled to cycles and then to nanoseconds. + // - Contentions are scaled to cycles. + if period > 0 { + if cpuHz > 0 { + cpuGHz := float64(cpuHz) / 1e9 + v1 = int64(float64(v1) * float64(period) / cpuGHz) + } + v2 = v2 * period + } + + value = []int64{v2, v1} + addrs = parseHexAddresses(sampleData[3]) + + return value, addrs, nil +} + +// parseThread parses a Threadz profile and returns a new Profile. +func parseThread(b []byte) (*Profile, error) { + r := bytes.NewBuffer(b) + + var line string + var err error + for { + // Skip past comments and empty lines seeking a real header. + line, err = r.ReadString('\n') + if err != nil { + return nil, err + } + if !isSpaceOrComment(line) { + break + } + } + + if m := threadzStartRE.FindStringSubmatch(line); m != nil { + // Advance over initial comments until first stack trace. + for { + line, err = r.ReadString('\n') + if err != nil { + if err != io.EOF { + return nil, err + } + + if line == "" { + break + } + } + if sectionTrigger(line) != unrecognizedSection || line[0] == '-' { + break + } + } + } else if t := threadStartRE.FindStringSubmatch(line); len(t) != 4 { + return nil, errUnrecognized + } + + p := &Profile{ + SampleType: []*ValueType{{Type: "thread", Unit: "count"}}, + PeriodType: &ValueType{Type: "thread", Unit: "count"}, + Period: 1, + } + + locs := make(map[uint64]*Location) + // Recognize each thread and populate profile samples. + for sectionTrigger(line) == unrecognizedSection { + if strings.HasPrefix(line, "---- no stack trace for") { + line = "" + break + } + if t := threadStartRE.FindStringSubmatch(line); len(t) != 4 { + return nil, errUnrecognized + } + + var addrs []uint64 + line, addrs, err = parseThreadSample(r) + if err != nil { + return nil, errUnrecognized + } + if len(addrs) == 0 { + // We got a --same as previous threads--. Bump counters. + if len(p.Sample) > 0 { + s := p.Sample[len(p.Sample)-1] + s.Value[0]++ + } + continue + } + + var sloc []*Location + for _, addr := range addrs { + // Addresses from stack traces point to the next instruction after + // each call. Adjust by -1 to land somewhere on the actual call. + addr-- + loc := locs[addr] + if locs[addr] == nil { + loc = &Location{ + Address: addr, + } + p.Location = append(p.Location, loc) + locs[addr] = loc + } + sloc = append(sloc, loc) + } + + p.Sample = append(p.Sample, &Sample{ + Value: []int64{1}, + Location: sloc, + }) + } + + if err = parseAdditionalSections(line, r, p); err != nil { + return nil, err + } + + return p, nil +} + +// parseThreadSample parses a symbolized or unsymbolized stack trace. +// Returns the first line after the traceback, the sample (or nil if +// it hits a 'same-as-previous' marker) and an error. +func parseThreadSample(b *bytes.Buffer) (nextl string, addrs []uint64, err error) { + var l string + sameAsPrevious := false + for { + if l, err = b.ReadString('\n'); err != nil { + if err != io.EOF { + return "", nil, err + } + if l == "" { + break + } + } + if l = strings.TrimSpace(l); l == "" { + continue + } + + if strings.HasPrefix(l, "---") { + break + } + if strings.Contains(l, "same as previous thread") { + sameAsPrevious = true + continue + } + + addrs = append(addrs, parseHexAddresses(l)...) + } + + if sameAsPrevious { + return l, nil, nil + } + return l, addrs, nil +} + +// parseAdditionalSections parses any additional sections in the +// profile, ignoring any unrecognized sections. +func parseAdditionalSections(l string, b *bytes.Buffer, p *Profile) (err error) { + for { + if sectionTrigger(l) == memoryMapSection { + break + } + // Ignore any unrecognized sections. + if l, err := b.ReadString('\n'); err != nil { + if err != io.EOF { + return err + } + if l == "" { + break + } + } + } + return p.ParseMemoryMap(b) +} + +// ParseMemoryMap parses a memory map in the format of +// /proc/self/maps, and overrides the mappings in the current profile. +// It renumbers the samples and locations in the profile correspondingly. +func (p *Profile) ParseMemoryMap(rd io.Reader) error { + b := bufio.NewReader(rd) + + var attrs []string + var r *strings.Replacer + const delimiter = "=" + for { + l, err := b.ReadString('\n') + if err != nil { + if err != io.EOF { + return err + } + if l == "" { + break + } + } + if l = strings.TrimSpace(l); l == "" { + continue + } + + if r != nil { + l = r.Replace(l) + } + m, err := parseMappingEntry(l) + if err != nil { + if err == errUnrecognized { + // Recognize assignments of the form: attr=value, and replace + // $attr with value on subsequent mappings. + if attr := strings.SplitN(l, delimiter, 2); len(attr) == 2 { + attrs = append(attrs, "$"+strings.TrimSpace(attr[0]), strings.TrimSpace(attr[1])) + r = strings.NewReplacer(attrs...) + } + // Ignore any unrecognized entries + continue + } + return err + } + if m == nil || (m.File == "" && len(p.Mapping) != 0) { + // In some cases the first entry may include the address range + // but not the name of the file. It should be followed by + // another entry with the name. + continue + } + if len(p.Mapping) == 1 && p.Mapping[0].File == "" { + // Update the name if this is the entry following that empty one. + p.Mapping[0].File = m.File + continue + } + p.Mapping = append(p.Mapping, m) + } + p.remapLocationIDs() + p.remapFunctionIDs() + p.remapMappingIDs() + return nil +} + +func parseMappingEntry(l string) (*Mapping, error) { + mapping := &Mapping{} + var err error + if me := procMapsRE.FindStringSubmatch(l); len(me) == 9 { + if !strings.Contains(me[3], "x") { + // Skip non-executable entries. + return nil, nil + } + if mapping.Start, err = strconv.ParseUint(me[1], 16, 64); err != nil { + return nil, errUnrecognized + } + if mapping.Limit, err = strconv.ParseUint(me[2], 16, 64); err != nil { + return nil, errUnrecognized + } + if me[4] != "" { + if mapping.Offset, err = strconv.ParseUint(me[4], 16, 64); err != nil { + return nil, errUnrecognized + } + } + mapping.File = me[8] + return mapping, nil + } + + if me := briefMapsRE.FindStringSubmatch(l); len(me) == 6 { + if mapping.Start, err = strconv.ParseUint(me[1], 16, 64); err != nil { + return nil, errUnrecognized + } + if mapping.Limit, err = strconv.ParseUint(me[2], 16, 64); err != nil { + return nil, errUnrecognized + } + mapping.File = me[3] + if me[5] != "" { + if mapping.Offset, err = strconv.ParseUint(me[5], 16, 64); err != nil { + return nil, errUnrecognized + } + } + return mapping, nil + } + + return nil, errUnrecognized +} + +type sectionType int + +const ( + unrecognizedSection sectionType = iota + memoryMapSection +) + +var memoryMapTriggers = []string{ + "--- Memory map: ---", + "MAPPED_LIBRARIES:", +} + +func sectionTrigger(line string) sectionType { + for _, trigger := range memoryMapTriggers { + if strings.Contains(line, trigger) { + return memoryMapSection + } + } + return unrecognizedSection +} + +func (p *Profile) addLegacyFrameInfo() { + switch { + case isProfileType(p, heapzSampleTypes) || + isProfileType(p, heapzInUseSampleTypes) || + isProfileType(p, heapzAllocSampleTypes): + p.DropFrames, p.KeepFrames = allocRxStr, allocSkipRxStr + case isProfileType(p, contentionzSampleTypes): + p.DropFrames, p.KeepFrames = lockRxStr, "" + default: + p.DropFrames, p.KeepFrames = cpuProfilerRxStr, "" + } +} + +var heapzSampleTypes = []string{"allocations", "size"} // early Go pprof profiles +var heapzInUseSampleTypes = []string{"inuse_objects", "inuse_space"} +var heapzAllocSampleTypes = []string{"alloc_objects", "alloc_space"} +var contentionzSampleTypes = []string{"contentions", "delay"} + +func isProfileType(p *Profile, t []string) bool { + st := p.SampleType + if len(st) != len(t) { + return false + } + + for i := range st { + if st[i].Type != t[i] { + return false + } + } + return true +} + +var allocRxStr = strings.Join([]string{ + // POSIX entry points. + `calloc`, + `cfree`, + `malloc`, + `free`, + `memalign`, + `do_memalign`, + `(__)?posix_memalign`, + `pvalloc`, + `valloc`, + `realloc`, + + // TC malloc. + `tcmalloc::.*`, + `tc_calloc`, + `tc_cfree`, + `tc_malloc`, + `tc_free`, + `tc_memalign`, + `tc_posix_memalign`, + `tc_pvalloc`, + `tc_valloc`, + `tc_realloc`, + `tc_new`, + `tc_delete`, + `tc_newarray`, + `tc_deletearray`, + `tc_new_nothrow`, + `tc_newarray_nothrow`, + + // Memory-allocation routines on OS X. + `malloc_zone_malloc`, + `malloc_zone_calloc`, + `malloc_zone_valloc`, + `malloc_zone_realloc`, + `malloc_zone_memalign`, + `malloc_zone_free`, + + // Go runtime + `runtime\..*`, + + // Other misc. memory allocation routines + `BaseArena::.*`, + `(::)?do_malloc_no_errno`, + `(::)?do_malloc_pages`, + `(::)?do_malloc`, + `DoSampledAllocation`, + `MallocedMemBlock::MallocedMemBlock`, + `_M_allocate`, + `__builtin_(vec_)?delete`, + `__builtin_(vec_)?new`, + `__gnu_cxx::new_allocator::allocate`, + `__libc_malloc`, + `__malloc_alloc_template::allocate`, + `allocate`, + `cpp_alloc`, + `operator new(\[\])?`, + `simple_alloc::allocate`, +}, `|`) + +var allocSkipRxStr = strings.Join([]string{ + // Preserve Go runtime frames that appear in the middle/bottom of + // the stack. + `runtime\.panic`, + `runtime\.reflectcall`, + `runtime\.call[0-9]*`, +}, `|`) + +var cpuProfilerRxStr = strings.Join([]string{ + `ProfileData::Add`, + `ProfileData::prof_handler`, + `CpuProfiler::prof_handler`, + `__pthread_sighandler`, + `__restore`, +}, `|`) + +var lockRxStr = strings.Join([]string{ + `RecordLockProfileData`, + `(base::)?RecordLockProfileData.*`, + `(base::)?SubmitMutexProfileData.*`, + `(base::)?SubmitSpinLockProfileData.*`, + `(Mutex::)?AwaitCommon.*`, + `(Mutex::)?Unlock.*`, + `(Mutex::)?UnlockSlow.*`, + `(Mutex::)?ReaderUnlock.*`, + `(MutexLock::)?~MutexLock.*`, + `(SpinLock::)?Unlock.*`, + `(SpinLock::)?SlowUnlock.*`, + `(SpinLockHolder::)?~SpinLockHolder.*`, +}, `|`) diff --git a/libgo/go/internal/profile/merge.go b/libgo/go/internal/profile/merge.go new file mode 100644 index 00000000000..3ea7d4cf42b --- /dev/null +++ b/libgo/go/internal/profile/merge.go @@ -0,0 +1,461 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package profile + +import ( + "fmt" + "sort" + "strconv" + "strings" +) + +// Merge merges all the profiles in profs into a single Profile. +// Returns a new profile independent of the input profiles. The merged +// profile is compacted to eliminate unused samples, locations, +// functions and mappings. Profiles must have identical profile sample +// and period types or the merge will fail. profile.Period of the +// resulting profile will be the maximum of all profiles, and +// profile.TimeNanos will be the earliest nonzero one. +func Merge(srcs []*Profile) (*Profile, error) { + if len(srcs) == 0 { + return nil, fmt.Errorf("no profiles to merge") + } + p, err := combineHeaders(srcs) + if err != nil { + return nil, err + } + + pm := &profileMerger{ + p: p, + samples: make(map[sampleKey]*Sample, len(srcs[0].Sample)), + locations: make(map[locationKey]*Location, len(srcs[0].Location)), + functions: make(map[functionKey]*Function, len(srcs[0].Function)), + mappings: make(map[mappingKey]*Mapping, len(srcs[0].Mapping)), + } + + for _, src := range srcs { + // Clear the profile-specific hash tables + pm.locationsByID = make(map[uint64]*Location, len(src.Location)) + pm.functionsByID = make(map[uint64]*Function, len(src.Function)) + pm.mappingsByID = make(map[uint64]mapInfo, len(src.Mapping)) + + if len(pm.mappings) == 0 && len(src.Mapping) > 0 { + // The Mapping list has the property that the first mapping + // represents the main binary. Take the first Mapping we see, + // otherwise the operations below will add mappings in an + // arbitrary order. + pm.mapMapping(src.Mapping[0]) + } + + for _, s := range src.Sample { + if !isZeroSample(s) { + pm.mapSample(s) + } + } + } + + for _, s := range p.Sample { + if isZeroSample(s) { + // If there are any zero samples, re-merge the profile to GC + // them. + return Merge([]*Profile{p}) + } + } + + return p, nil +} + +// Normalize normalizes the source profile by multiplying each value in profile by the +// ratio of the sum of the base profile's values of that sample type to the sum of the +// source profile's value of that sample type. +func (p *Profile) Normalize(pb *Profile) error { + + if err := p.compatible(pb); err != nil { + return err + } + + baseVals := make([]int64, len(p.SampleType)) + for _, s := range pb.Sample { + for i, v := range s.Value { + baseVals[i] += v + } + } + + srcVals := make([]int64, len(p.SampleType)) + for _, s := range p.Sample { + for i, v := range s.Value { + srcVals[i] += v + } + } + + normScale := make([]float64, len(baseVals)) + for i := range baseVals { + if srcVals[i] == 0 { + normScale[i] = 0.0 + } else { + normScale[i] = float64(baseVals[i]) / float64(srcVals[i]) + } + } + p.ScaleN(normScale) + return nil +} + +func isZeroSample(s *Sample) bool { + for _, v := range s.Value { + if v != 0 { + return false + } + } + return true +} + +type profileMerger struct { + p *Profile + + // Memoization tables within a profile. + locationsByID map[uint64]*Location + functionsByID map[uint64]*Function + mappingsByID map[uint64]mapInfo + + // Memoization tables for profile entities. + samples map[sampleKey]*Sample + locations map[locationKey]*Location + functions map[functionKey]*Function + mappings map[mappingKey]*Mapping +} + +type mapInfo struct { + m *Mapping + offset int64 +} + +func (pm *profileMerger) mapSample(src *Sample) *Sample { + s := &Sample{ + Location: make([]*Location, len(src.Location)), + Value: make([]int64, len(src.Value)), + Label: make(map[string][]string, len(src.Label)), + NumLabel: make(map[string][]int64, len(src.NumLabel)), + NumUnit: make(map[string][]string, len(src.NumLabel)), + } + for i, l := range src.Location { + s.Location[i] = pm.mapLocation(l) + } + for k, v := range src.Label { + vv := make([]string, len(v)) + copy(vv, v) + s.Label[k] = vv + } + for k, v := range src.NumLabel { + u := src.NumUnit[k] + vv := make([]int64, len(v)) + uu := make([]string, len(u)) + copy(vv, v) + copy(uu, u) + s.NumLabel[k] = vv + s.NumUnit[k] = uu + } + // Check memoization table. Must be done on the remapped location to + // account for the remapped mapping. Add current values to the + // existing sample. + k := s.key() + if ss, ok := pm.samples[k]; ok { + for i, v := range src.Value { + ss.Value[i] += v + } + return ss + } + copy(s.Value, src.Value) + pm.samples[k] = s + pm.p.Sample = append(pm.p.Sample, s) + return s +} + +// key generates sampleKey to be used as a key for maps. +func (sample *Sample) key() sampleKey { + ids := make([]string, len(sample.Location)) + for i, l := range sample.Location { + ids[i] = strconv.FormatUint(l.ID, 16) + } + + labels := make([]string, 0, len(sample.Label)) + for k, v := range sample.Label { + labels = append(labels, fmt.Sprintf("%q%q", k, v)) + } + sort.Strings(labels) + + numlabels := make([]string, 0, len(sample.NumLabel)) + for k, v := range sample.NumLabel { + numlabels = append(numlabels, fmt.Sprintf("%q%x%x", k, v, sample.NumUnit[k])) + } + sort.Strings(numlabels) + + return sampleKey{ + strings.Join(ids, "|"), + strings.Join(labels, ""), + strings.Join(numlabels, ""), + } +} + +type sampleKey struct { + locations string + labels string + numlabels string +} + +func (pm *profileMerger) mapLocation(src *Location) *Location { + if src == nil { + return nil + } + + if l, ok := pm.locationsByID[src.ID]; ok { + pm.locationsByID[src.ID] = l + return l + } + + mi := pm.mapMapping(src.Mapping) + l := &Location{ + ID: uint64(len(pm.p.Location) + 1), + Mapping: mi.m, + Address: uint64(int64(src.Address) + mi.offset), + Line: make([]Line, len(src.Line)), + IsFolded: src.IsFolded, + } + for i, ln := range src.Line { + l.Line[i] = pm.mapLine(ln) + } + // Check memoization table. Must be done on the remapped location to + // account for the remapped mapping ID. + k := l.key() + if ll, ok := pm.locations[k]; ok { + pm.locationsByID[src.ID] = ll + return ll + } + pm.locationsByID[src.ID] = l + pm.locations[k] = l + pm.p.Location = append(pm.p.Location, l) + return l +} + +// key generates locationKey to be used as a key for maps. +func (l *Location) key() locationKey { + key := locationKey{ + addr: l.Address, + isFolded: l.IsFolded, + } + if l.Mapping != nil { + // Normalizes address to handle address space randomization. + key.addr -= l.Mapping.Start + key.mappingID = l.Mapping.ID + } + lines := make([]string, len(l.Line)*2) + for i, line := range l.Line { + if line.Function != nil { + lines[i*2] = strconv.FormatUint(line.Function.ID, 16) + } + lines[i*2+1] = strconv.FormatInt(line.Line, 16) + } + key.lines = strings.Join(lines, "|") + return key +} + +type locationKey struct { + addr, mappingID uint64 + lines string + isFolded bool +} + +func (pm *profileMerger) mapMapping(src *Mapping) mapInfo { + if src == nil { + return mapInfo{} + } + + if mi, ok := pm.mappingsByID[src.ID]; ok { + return mi + } + + // Check memoization tables. + mk := src.key() + if m, ok := pm.mappings[mk]; ok { + mi := mapInfo{m, int64(m.Start) - int64(src.Start)} + pm.mappingsByID[src.ID] = mi + return mi + } + m := &Mapping{ + ID: uint64(len(pm.p.Mapping) + 1), + Start: src.Start, + Limit: src.Limit, + Offset: src.Offset, + File: src.File, + BuildID: src.BuildID, + HasFunctions: src.HasFunctions, + HasFilenames: src.HasFilenames, + HasLineNumbers: src.HasLineNumbers, + HasInlineFrames: src.HasInlineFrames, + } + pm.p.Mapping = append(pm.p.Mapping, m) + + // Update memoization tables. + pm.mappings[mk] = m + mi := mapInfo{m, 0} + pm.mappingsByID[src.ID] = mi + return mi +} + +// key generates encoded strings of Mapping to be used as a key for +// maps. +func (m *Mapping) key() mappingKey { + // Normalize addresses to handle address space randomization. + // Round up to next 4K boundary to avoid minor discrepancies. + const mapsizeRounding = 0x1000 + + size := m.Limit - m.Start + size = size + mapsizeRounding - 1 + size = size - (size % mapsizeRounding) + key := mappingKey{ + size: size, + offset: m.Offset, + } + + switch { + case m.BuildID != "": + key.buildIDOrFile = m.BuildID + case m.File != "": + key.buildIDOrFile = m.File + default: + // A mapping containing neither build ID nor file name is a fake mapping. A + // key with empty buildIDOrFile is used for fake mappings so that they are + // treated as the same mapping during merging. + } + return key +} + +type mappingKey struct { + size, offset uint64 + buildIDOrFile string +} + +func (pm *profileMerger) mapLine(src Line) Line { + ln := Line{ + Function: pm.mapFunction(src.Function), + Line: src.Line, + } + return ln +} + +func (pm *profileMerger) mapFunction(src *Function) *Function { + if src == nil { + return nil + } + if f, ok := pm.functionsByID[src.ID]; ok { + return f + } + k := src.key() + if f, ok := pm.functions[k]; ok { + pm.functionsByID[src.ID] = f + return f + } + f := &Function{ + ID: uint64(len(pm.p.Function) + 1), + Name: src.Name, + SystemName: src.SystemName, + Filename: src.Filename, + StartLine: src.StartLine, + } + pm.functions[k] = f + pm.functionsByID[src.ID] = f + pm.p.Function = append(pm.p.Function, f) + return f +} + +// key generates a struct to be used as a key for maps. +func (f *Function) key() functionKey { + return functionKey{ + f.StartLine, + f.Name, + f.SystemName, + f.Filename, + } +} + +type functionKey struct { + startLine int64 + name, systemName, fileName string +} + +// combineHeaders checks that all profiles can be merged and returns +// their combined profile. +func combineHeaders(srcs []*Profile) (*Profile, error) { + for _, s := range srcs[1:] { + if err := srcs[0].compatible(s); err != nil { + return nil, err + } + } + + var timeNanos, durationNanos, period int64 + var comments []string + seenComments := map[string]bool{} + var defaultSampleType string + for _, s := range srcs { + if timeNanos == 0 || s.TimeNanos < timeNanos { + timeNanos = s.TimeNanos + } + durationNanos += s.DurationNanos + if period == 0 || period < s.Period { + period = s.Period + } + for _, c := range s.Comments { + if seen := seenComments[c]; !seen { + comments = append(comments, c) + seenComments[c] = true + } + } + if defaultSampleType == "" { + defaultSampleType = s.DefaultSampleType + } + } + + p := &Profile{ + SampleType: make([]*ValueType, len(srcs[0].SampleType)), + + DropFrames: srcs[0].DropFrames, + KeepFrames: srcs[0].KeepFrames, + + TimeNanos: timeNanos, + DurationNanos: durationNanos, + PeriodType: srcs[0].PeriodType, + Period: period, + + Comments: comments, + DefaultSampleType: defaultSampleType, + } + copy(p.SampleType, srcs[0].SampleType) + return p, nil +} + +// compatible determines if two profiles can be compared/merged. +// returns nil if the profiles are compatible; otherwise an error with +// details on the incompatibility. +func (p *Profile) compatible(pb *Profile) error { + if !equalValueType(p.PeriodType, pb.PeriodType) { + return fmt.Errorf("incompatible period types %v and %v", p.PeriodType, pb.PeriodType) + } + + if len(p.SampleType) != len(pb.SampleType) { + return fmt.Errorf("incompatible sample types %v and %v", p.SampleType, pb.SampleType) + } + + for i := range p.SampleType { + if !equalValueType(p.SampleType[i], pb.SampleType[i]) { + return fmt.Errorf("incompatible sample types %v and %v", p.SampleType, pb.SampleType) + } + } + return nil +} + +// equalValueType returns true if the two value types are semantically +// equal. It ignores the internal fields used during encode/decode. +func equalValueType(st1, st2 *ValueType) bool { + return st1.Type == st2.Type && st1.Unit == st2.Unit +} diff --git a/libgo/go/internal/profile/profile.go b/libgo/go/internal/profile/profile.go new file mode 100644 index 00000000000..a6275bc6de4 --- /dev/null +++ b/libgo/go/internal/profile/profile.go @@ -0,0 +1,614 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package profile provides a representation of +// github.com/google/pprof/proto/profile.proto and +// methods to encode/decode/merge profiles in this format. +package profile + +import ( + "bytes" + "compress/gzip" + "fmt" + "io" + "io/ioutil" + "regexp" + "strings" + "time" +) + +// Profile is an in-memory representation of profile.proto. +type Profile struct { + SampleType []*ValueType + DefaultSampleType string + Sample []*Sample + Mapping []*Mapping + Location []*Location + Function []*Function + Comments []string + + DropFrames string + KeepFrames string + + TimeNanos int64 + DurationNanos int64 + PeriodType *ValueType + Period int64 + + commentX []int64 + dropFramesX int64 + keepFramesX int64 + stringTable []string + defaultSampleTypeX int64 +} + +// ValueType corresponds to Profile.ValueType +type ValueType struct { + Type string // cpu, wall, inuse_space, etc + Unit string // seconds, nanoseconds, bytes, etc + + typeX int64 + unitX int64 +} + +// Sample corresponds to Profile.Sample +type Sample struct { + Location []*Location + Value []int64 + Label map[string][]string + NumLabel map[string][]int64 + NumUnit map[string][]string + + locationIDX []uint64 + labelX []Label +} + +// Label corresponds to Profile.Label +type Label struct { + keyX int64 + // Exactly one of the two following values must be set + strX int64 + numX int64 // Integer value for this label +} + +// Mapping corresponds to Profile.Mapping +type Mapping struct { + ID uint64 + Start uint64 + Limit uint64 + Offset uint64 + File string + BuildID string + HasFunctions bool + HasFilenames bool + HasLineNumbers bool + HasInlineFrames bool + + fileX int64 + buildIDX int64 +} + +// Location corresponds to Profile.Location +type Location struct { + ID uint64 + Mapping *Mapping + Address uint64 + Line []Line + IsFolded bool + + mappingIDX uint64 +} + +// Line corresponds to Profile.Line +type Line struct { + Function *Function + Line int64 + + functionIDX uint64 +} + +// Function corresponds to Profile.Function +type Function struct { + ID uint64 + Name string + SystemName string + Filename string + StartLine int64 + + nameX int64 + systemNameX int64 + filenameX int64 +} + +// Parse parses a profile and checks for its validity. The input +// may be a gzip-compressed encoded protobuf or one of many legacy +// profile formats which may be unsupported in the future. +func Parse(r io.Reader) (*Profile, error) { + orig, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + + var p *Profile + if len(orig) >= 2 && orig[0] == 0x1f && orig[1] == 0x8b { + gz, err := gzip.NewReader(bytes.NewBuffer(orig)) + if err != nil { + return nil, fmt.Errorf("decompressing profile: %v", err) + } + data, err := ioutil.ReadAll(gz) + if err != nil { + return nil, fmt.Errorf("decompressing profile: %v", err) + } + orig = data + } + if p, err = parseUncompressed(orig); err != nil { + if p, err = parseLegacy(orig); err != nil { + return nil, fmt.Errorf("parsing profile: %v", err) + } + } + + if err := p.CheckValid(); err != nil { + return nil, fmt.Errorf("malformed profile: %v", err) + } + return p, nil +} + +var errUnrecognized = fmt.Errorf("unrecognized profile format") +var errMalformed = fmt.Errorf("malformed profile format") + +func parseLegacy(data []byte) (*Profile, error) { + parsers := []func([]byte) (*Profile, error){ + parseCPU, + parseHeap, + parseGoCount, // goroutine, threadcreate + parseThread, + parseContention, + } + + for _, parser := range parsers { + p, err := parser(data) + if err == nil { + p.setMain() + p.addLegacyFrameInfo() + return p, nil + } + if err != errUnrecognized { + return nil, err + } + } + return nil, errUnrecognized +} + +func parseUncompressed(data []byte) (*Profile, error) { + p := &Profile{} + if err := unmarshal(data, p); err != nil { + return nil, err + } + + if err := p.postDecode(); err != nil { + return nil, err + } + + return p, nil +} + +var libRx = regexp.MustCompile(`([.]so$|[.]so[._][0-9]+)`) + +// setMain scans Mapping entries and guesses which entry is main +// because legacy profiles don't obey the convention of putting main +// first. +func (p *Profile) setMain() { + for i := 0; i < len(p.Mapping); i++ { + file := strings.TrimSpace(strings.ReplaceAll(p.Mapping[i].File, "(deleted)", "")) + if len(file) == 0 { + continue + } + if len(libRx.FindStringSubmatch(file)) > 0 { + continue + } + if strings.HasPrefix(file, "[") { + continue + } + // Swap what we guess is main to position 0. + p.Mapping[i], p.Mapping[0] = p.Mapping[0], p.Mapping[i] + break + } +} + +// Write writes the profile as a gzip-compressed marshaled protobuf. +func (p *Profile) Write(w io.Writer) error { + p.preEncode() + b := marshal(p) + zw := gzip.NewWriter(w) + defer zw.Close() + _, err := zw.Write(b) + return err +} + +// CheckValid tests whether the profile is valid. Checks include, but are +// not limited to: +// - len(Profile.Sample[n].value) == len(Profile.value_unit) +// - Sample.id has a corresponding Profile.Location +func (p *Profile) CheckValid() error { + // Check that sample values are consistent + sampleLen := len(p.SampleType) + if sampleLen == 0 && len(p.Sample) != 0 { + return fmt.Errorf("missing sample type information") + } + for _, s := range p.Sample { + if len(s.Value) != sampleLen { + return fmt.Errorf("mismatch: sample has: %d values vs. %d types", len(s.Value), len(p.SampleType)) + } + } + + // Check that all mappings/locations/functions are in the tables + // Check that there are no duplicate ids + mappings := make(map[uint64]*Mapping, len(p.Mapping)) + for _, m := range p.Mapping { + if m.ID == 0 { + return fmt.Errorf("found mapping with reserved ID=0") + } + if mappings[m.ID] != nil { + return fmt.Errorf("multiple mappings with same id: %d", m.ID) + } + mappings[m.ID] = m + } + functions := make(map[uint64]*Function, len(p.Function)) + for _, f := range p.Function { + if f.ID == 0 { + return fmt.Errorf("found function with reserved ID=0") + } + if functions[f.ID] != nil { + return fmt.Errorf("multiple functions with same id: %d", f.ID) + } + functions[f.ID] = f + } + locations := make(map[uint64]*Location, len(p.Location)) + for _, l := range p.Location { + if l.ID == 0 { + return fmt.Errorf("found location with reserved id=0") + } + if locations[l.ID] != nil { + return fmt.Errorf("multiple locations with same id: %d", l.ID) + } + locations[l.ID] = l + if m := l.Mapping; m != nil { + if m.ID == 0 || mappings[m.ID] != m { + return fmt.Errorf("inconsistent mapping %p: %d", m, m.ID) + } + } + for _, ln := range l.Line { + if f := ln.Function; f != nil { + if f.ID == 0 || functions[f.ID] != f { + return fmt.Errorf("inconsistent function %p: %d", f, f.ID) + } + } + } + } + return nil +} + +// Aggregate merges the locations in the profile into equivalence +// classes preserving the request attributes. It also updates the +// samples to point to the merged locations. +func (p *Profile) Aggregate(inlineFrame, function, filename, linenumber, address bool) error { + for _, m := range p.Mapping { + m.HasInlineFrames = m.HasInlineFrames && inlineFrame + m.HasFunctions = m.HasFunctions && function + m.HasFilenames = m.HasFilenames && filename + m.HasLineNumbers = m.HasLineNumbers && linenumber + } + + // Aggregate functions + if !function || !filename { + for _, f := range p.Function { + if !function { + f.Name = "" + f.SystemName = "" + } + if !filename { + f.Filename = "" + } + } + } + + // Aggregate locations + if !inlineFrame || !address || !linenumber { + for _, l := range p.Location { + if !inlineFrame && len(l.Line) > 1 { + l.Line = l.Line[len(l.Line)-1:] + } + if !linenumber { + for i := range l.Line { + l.Line[i].Line = 0 + } + } + if !address { + l.Address = 0 + } + } + } + + return p.CheckValid() +} + +// Print dumps a text representation of a profile. Intended mainly +// for debugging purposes. +func (p *Profile) String() string { + + ss := make([]string, 0, len(p.Sample)+len(p.Mapping)+len(p.Location)) + if pt := p.PeriodType; pt != nil { + ss = append(ss, fmt.Sprintf("PeriodType: %s %s", pt.Type, pt.Unit)) + } + ss = append(ss, fmt.Sprintf("Period: %d", p.Period)) + if p.TimeNanos != 0 { + ss = append(ss, fmt.Sprintf("Time: %v", time.Unix(0, p.TimeNanos))) + } + if p.DurationNanos != 0 { + ss = append(ss, fmt.Sprintf("Duration: %v", time.Duration(p.DurationNanos))) + } + + ss = append(ss, "Samples:") + var sh1 string + for _, s := range p.SampleType { + sh1 = sh1 + fmt.Sprintf("%s/%s ", s.Type, s.Unit) + } + ss = append(ss, strings.TrimSpace(sh1)) + for _, s := range p.Sample { + var sv string + for _, v := range s.Value { + sv = fmt.Sprintf("%s %10d", sv, v) + } + sv = sv + ": " + for _, l := range s.Location { + sv = sv + fmt.Sprintf("%d ", l.ID) + } + ss = append(ss, sv) + const labelHeader = " " + if len(s.Label) > 0 { + ls := labelHeader + for k, v := range s.Label { + ls = ls + fmt.Sprintf("%s:%v ", k, v) + } + ss = append(ss, ls) + } + if len(s.NumLabel) > 0 { + ls := labelHeader + for k, v := range s.NumLabel { + ls = ls + fmt.Sprintf("%s:%v ", k, v) + } + ss = append(ss, ls) + } + } + + ss = append(ss, "Locations") + for _, l := range p.Location { + locStr := fmt.Sprintf("%6d: %#x ", l.ID, l.Address) + if m := l.Mapping; m != nil { + locStr = locStr + fmt.Sprintf("M=%d ", m.ID) + } + if len(l.Line) == 0 { + ss = append(ss, locStr) + } + for li := range l.Line { + lnStr := "??" + if fn := l.Line[li].Function; fn != nil { + lnStr = fmt.Sprintf("%s %s:%d s=%d", + fn.Name, + fn.Filename, + l.Line[li].Line, + fn.StartLine) + if fn.Name != fn.SystemName { + lnStr = lnStr + "(" + fn.SystemName + ")" + } + } + ss = append(ss, locStr+lnStr) + // Do not print location details past the first line + locStr = " " + } + } + + ss = append(ss, "Mappings") + for _, m := range p.Mapping { + bits := "" + if m.HasFunctions { + bits += "[FN]" + } + if m.HasFilenames { + bits += "[FL]" + } + if m.HasLineNumbers { + bits += "[LN]" + } + if m.HasInlineFrames { + bits += "[IN]" + } + ss = append(ss, fmt.Sprintf("%d: %#x/%#x/%#x %s %s %s", + m.ID, + m.Start, m.Limit, m.Offset, + m.File, + m.BuildID, + bits)) + } + + return strings.Join(ss, "\n") + "\n" +} + +// Merge adds profile p adjusted by ratio r into profile p. Profiles +// must be compatible (same Type and SampleType). +// TODO(rsilvera): consider normalizing the profiles based on the +// total samples collected. +func (p *Profile) Merge(pb *Profile, r float64) error { + if err := p.Compatible(pb); err != nil { + return err + } + + pb = pb.Copy() + + // Keep the largest of the two periods. + if pb.Period > p.Period { + p.Period = pb.Period + } + + p.DurationNanos += pb.DurationNanos + + p.Mapping = append(p.Mapping, pb.Mapping...) + for i, m := range p.Mapping { + m.ID = uint64(i + 1) + } + p.Location = append(p.Location, pb.Location...) + for i, l := range p.Location { + l.ID = uint64(i + 1) + } + p.Function = append(p.Function, pb.Function...) + for i, f := range p.Function { + f.ID = uint64(i + 1) + } + + if r != 1.0 { + for _, s := range pb.Sample { + for i, v := range s.Value { + s.Value[i] = int64((float64(v) * r)) + } + } + } + p.Sample = append(p.Sample, pb.Sample...) + return p.CheckValid() +} + +// Compatible determines if two profiles can be compared/merged. +// returns nil if the profiles are compatible; otherwise an error with +// details on the incompatibility. +func (p *Profile) Compatible(pb *Profile) error { + if !compatibleValueTypes(p.PeriodType, pb.PeriodType) { + return fmt.Errorf("incompatible period types %v and %v", p.PeriodType, pb.PeriodType) + } + + if len(p.SampleType) != len(pb.SampleType) { + return fmt.Errorf("incompatible sample types %v and %v", p.SampleType, pb.SampleType) + } + + for i := range p.SampleType { + if !compatibleValueTypes(p.SampleType[i], pb.SampleType[i]) { + return fmt.Errorf("incompatible sample types %v and %v", p.SampleType, pb.SampleType) + } + } + + return nil +} + +// HasFunctions determines if all locations in this profile have +// symbolized function information. +func (p *Profile) HasFunctions() bool { + for _, l := range p.Location { + if l.Mapping == nil || !l.Mapping.HasFunctions { + return false + } + } + return true +} + +// HasFileLines determines if all locations in this profile have +// symbolized file and line number information. +func (p *Profile) HasFileLines() bool { + for _, l := range p.Location { + if l.Mapping == nil || (!l.Mapping.HasFilenames || !l.Mapping.HasLineNumbers) { + return false + } + } + return true +} + +func compatibleValueTypes(v1, v2 *ValueType) bool { + if v1 == nil || v2 == nil { + return true // No grounds to disqualify. + } + return v1.Type == v2.Type && v1.Unit == v2.Unit +} + +// Copy makes a fully independent copy of a profile. +func (p *Profile) Copy() *Profile { + p.preEncode() + b := marshal(p) + + pp := &Profile{} + if err := unmarshal(b, pp); err != nil { + panic(err) + } + if err := pp.postDecode(); err != nil { + panic(err) + } + + return pp +} + +// Demangler maps symbol names to a human-readable form. This may +// include C++ demangling and additional simplification. Names that +// are not demangled may be missing from the resulting map. +type Demangler func(name []string) (map[string]string, error) + +// Demangle attempts to demangle and optionally simplify any function +// names referenced in the profile. It works on a best-effort basis: +// it will silently preserve the original names in case of any errors. +func (p *Profile) Demangle(d Demangler) error { + // Collect names to demangle. + var names []string + for _, fn := range p.Function { + names = append(names, fn.SystemName) + } + + // Update profile with demangled names. + demangled, err := d(names) + if err != nil { + return err + } + for _, fn := range p.Function { + if dd, ok := demangled[fn.SystemName]; ok { + fn.Name = dd + } + } + return nil +} + +// Empty reports whether the profile contains no samples. +func (p *Profile) Empty() bool { + return len(p.Sample) == 0 +} + +// Scale multiplies all sample values in a profile by a constant. +func (p *Profile) Scale(ratio float64) { + if ratio == 1 { + return + } + ratios := make([]float64, len(p.SampleType)) + for i := range p.SampleType { + ratios[i] = ratio + } + p.ScaleN(ratios) +} + +// ScaleN multiplies each sample values in a sample by a different amount. +func (p *Profile) ScaleN(ratios []float64) error { + if len(p.SampleType) != len(ratios) { + return fmt.Errorf("mismatched scale ratios, got %d, want %d", len(ratios), len(p.SampleType)) + } + allOnes := true + for _, r := range ratios { + if r != 1 { + allOnes = false + break + } + } + if allOnes { + return nil + } + for _, s := range p.Sample { + for i, v := range s.Value { + if ratios[i] != 1 { + s.Value[i] = int64(float64(v) * ratios[i]) + } + } + } + return nil +} diff --git a/libgo/go/internal/profile/profile_test.go b/libgo/go/internal/profile/profile_test.go new file mode 100644 index 00000000000..e1963f33515 --- /dev/null +++ b/libgo/go/internal/profile/profile_test.go @@ -0,0 +1,79 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package profile + +import ( + "bytes" + "testing" +) + +func TestEmptyProfile(t *testing.T) { + var buf bytes.Buffer + p, err := Parse(&buf) + if err != nil { + t.Error("Want no error, got", err) + } + if p == nil { + t.Fatal("Want a valid profile, got ") + } + if !p.Empty() { + t.Errorf("Profile should be empty, got %#v", p) + } +} + +func TestParseContention(t *testing.T) { + tests := []struct { + name string + in string + wantErr bool + }{ + { + name: "valid", + in: `--- mutex: +cycles/second=3491920901 +sampling period=1 +43227965305 1659640 @ 0x45e851 0x45f764 0x4a2be1 0x44ea31 +34035731690 15760 @ 0x45e851 0x45f764 0x4a2b17 0x44ea31 +`, + }, + { + name: "valid with comment", + in: `--- mutex: +cycles/second=3491920901 +sampling period=1 +43227965305 1659640 @ 0x45e851 0x45f764 0x4a2be1 0x44ea31 +# 0x45e850 sync.(*Mutex).Unlock+0x80 /go/src/sync/mutex.go:126 +# 0x45f763 sync.(*RWMutex).Unlock+0x83 /go/src/sync/rwmutex.go:125 +# 0x4a2be0 main.main.func3+0x70 /go/src/internal/pprof/profile/a_binary.go:58 + +34035731690 15760 @ 0x45e851 0x45f764 0x4a2b17 0x44ea31 +# 0x45e850 sync.(*Mutex).Unlock+0x80 /go/src/sync/mutex.go:126 +# 0x45f763 sync.(*RWMutex).Unlock+0x83 /go/src/sync/rwmutex.go:125 +# 0x4a2b16 main.main.func2+0xd6 /go/src/internal/pprof/profile/a_binary.go:48 +`, + }, + { + name: "empty", + in: `--- mutex:`, + wantErr: true, + }, + { + name: "invalid header", + in: `--- channel: +43227965305 1659640 @ 0x45e851 0x45f764 0x4a2be1 0x44ea31`, + wantErr: true, + }, + } + for _, tc := range tests { + _, err := parseContention([]byte(tc.in)) + if tc.wantErr && err == nil { + t.Errorf("parseContention(%q) succeeded unexpectedly", tc.name) + } + if !tc.wantErr && err != nil { + t.Errorf("parseContention(%q) failed unexpectedly: %v", tc.name, err) + } + } + +} diff --git a/libgo/go/internal/profile/proto.go b/libgo/go/internal/profile/proto.go new file mode 100644 index 00000000000..52cf1ef2b3b --- /dev/null +++ b/libgo/go/internal/profile/proto.go @@ -0,0 +1,363 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file is a simple protocol buffer encoder and decoder. +// +// A protocol message must implement the message interface: +// decoder() []decoder +// encode(*buffer) +// +// The decode method returns a slice indexed by field number that gives the +// function to decode that field. +// The encode method encodes its receiver into the given buffer. +// +// The two methods are simple enough to be implemented by hand rather than +// by using a protocol compiler. +// +// See profile.go for examples of messages implementing this interface. +// +// There is no support for groups, message sets, or "has" bits. + +package profile + +import ( + "errors" + "fmt" +) + +type buffer struct { + field int + typ int + u64 uint64 + data []byte + tmp [16]byte +} + +type decoder func(*buffer, message) error + +type message interface { + decoder() []decoder + encode(*buffer) +} + +func marshal(m message) []byte { + var b buffer + m.encode(&b) + return b.data +} + +func encodeVarint(b *buffer, x uint64) { + for x >= 128 { + b.data = append(b.data, byte(x)|0x80) + x >>= 7 + } + b.data = append(b.data, byte(x)) +} + +func encodeLength(b *buffer, tag int, len int) { + encodeVarint(b, uint64(tag)<<3|2) + encodeVarint(b, uint64(len)) +} + +func encodeUint64(b *buffer, tag int, x uint64) { + // append varint to b.data + encodeVarint(b, uint64(tag)<<3|0) + encodeVarint(b, x) +} + +func encodeUint64s(b *buffer, tag int, x []uint64) { + if len(x) > 2 { + // Use packed encoding + n1 := len(b.data) + for _, u := range x { + encodeVarint(b, u) + } + n2 := len(b.data) + encodeLength(b, tag, n2-n1) + n3 := len(b.data) + copy(b.tmp[:], b.data[n2:n3]) + copy(b.data[n1+(n3-n2):], b.data[n1:n2]) + copy(b.data[n1:], b.tmp[:n3-n2]) + return + } + for _, u := range x { + encodeUint64(b, tag, u) + } +} + +func encodeUint64Opt(b *buffer, tag int, x uint64) { + if x == 0 { + return + } + encodeUint64(b, tag, x) +} + +func encodeInt64(b *buffer, tag int, x int64) { + u := uint64(x) + encodeUint64(b, tag, u) +} + +func encodeInt64Opt(b *buffer, tag int, x int64) { + if x == 0 { + return + } + encodeInt64(b, tag, x) +} + +func encodeInt64s(b *buffer, tag int, x []int64) { + if len(x) > 2 { + // Use packed encoding + n1 := len(b.data) + for _, u := range x { + encodeVarint(b, uint64(u)) + } + n2 := len(b.data) + encodeLength(b, tag, n2-n1) + n3 := len(b.data) + copy(b.tmp[:], b.data[n2:n3]) + copy(b.data[n1+(n3-n2):], b.data[n1:n2]) + copy(b.data[n1:], b.tmp[:n3-n2]) + return + } + for _, u := range x { + encodeInt64(b, tag, u) + } +} + +func encodeString(b *buffer, tag int, x string) { + encodeLength(b, tag, len(x)) + b.data = append(b.data, x...) +} + +func encodeStrings(b *buffer, tag int, x []string) { + for _, s := range x { + encodeString(b, tag, s) + } +} + +func encodeStringOpt(b *buffer, tag int, x string) { + if x == "" { + return + } + encodeString(b, tag, x) +} + +func encodeBool(b *buffer, tag int, x bool) { + if x { + encodeUint64(b, tag, 1) + } else { + encodeUint64(b, tag, 0) + } +} + +func encodeBoolOpt(b *buffer, tag int, x bool) { + if x == false { + return + } + encodeBool(b, tag, x) +} + +func encodeMessage(b *buffer, tag int, m message) { + n1 := len(b.data) + m.encode(b) + n2 := len(b.data) + encodeLength(b, tag, n2-n1) + n3 := len(b.data) + copy(b.tmp[:], b.data[n2:n3]) + copy(b.data[n1+(n3-n2):], b.data[n1:n2]) + copy(b.data[n1:], b.tmp[:n3-n2]) +} + +func unmarshal(data []byte, m message) (err error) { + b := buffer{data: data, typ: 2} + return decodeMessage(&b, m) +} + +func le64(p []byte) uint64 { + return uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 | uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56 +} + +func le32(p []byte) uint32 { + return uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24 +} + +func decodeVarint(data []byte) (uint64, []byte, error) { + var i int + var u uint64 + for i = 0; ; i++ { + if i >= 10 || i >= len(data) { + return 0, nil, errors.New("bad varint") + } + u |= uint64(data[i]&0x7F) << uint(7*i) + if data[i]&0x80 == 0 { + return u, data[i+1:], nil + } + } +} + +func decodeField(b *buffer, data []byte) ([]byte, error) { + x, data, err := decodeVarint(data) + if err != nil { + return nil, err + } + b.field = int(x >> 3) + b.typ = int(x & 7) + b.data = nil + b.u64 = 0 + switch b.typ { + case 0: + b.u64, data, err = decodeVarint(data) + if err != nil { + return nil, err + } + case 1: + if len(data) < 8 { + return nil, errors.New("not enough data") + } + b.u64 = le64(data[:8]) + data = data[8:] + case 2: + var n uint64 + n, data, err = decodeVarint(data) + if err != nil { + return nil, err + } + if n > uint64(len(data)) { + return nil, errors.New("too much data") + } + b.data = data[:n] + data = data[n:] + case 5: + if len(data) < 4 { + return nil, errors.New("not enough data") + } + b.u64 = uint64(le32(data[:4])) + data = data[4:] + default: + return nil, fmt.Errorf("unknown wire type: %d", b.typ) + } + + return data, nil +} + +func checkType(b *buffer, typ int) error { + if b.typ != typ { + return errors.New("type mismatch") + } + return nil +} + +func decodeMessage(b *buffer, m message) error { + if err := checkType(b, 2); err != nil { + return err + } + dec := m.decoder() + data := b.data + for len(data) > 0 { + // pull varint field# + type + var err error + data, err = decodeField(b, data) + if err != nil { + return err + } + if b.field >= len(dec) || dec[b.field] == nil { + continue + } + if err := dec[b.field](b, m); err != nil { + return err + } + } + return nil +} + +func decodeInt64(b *buffer, x *int64) error { + if err := checkType(b, 0); err != nil { + return err + } + *x = int64(b.u64) + return nil +} + +func decodeInt64s(b *buffer, x *[]int64) error { + if b.typ == 2 { + // Packed encoding + data := b.data + for len(data) > 0 { + var u uint64 + var err error + + if u, data, err = decodeVarint(data); err != nil { + return err + } + *x = append(*x, int64(u)) + } + return nil + } + var i int64 + if err := decodeInt64(b, &i); err != nil { + return err + } + *x = append(*x, i) + return nil +} + +func decodeUint64(b *buffer, x *uint64) error { + if err := checkType(b, 0); err != nil { + return err + } + *x = b.u64 + return nil +} + +func decodeUint64s(b *buffer, x *[]uint64) error { + if b.typ == 2 { + data := b.data + // Packed encoding + for len(data) > 0 { + var u uint64 + var err error + + if u, data, err = decodeVarint(data); err != nil { + return err + } + *x = append(*x, u) + } + return nil + } + var u uint64 + if err := decodeUint64(b, &u); err != nil { + return err + } + *x = append(*x, u) + return nil +} + +func decodeString(b *buffer, x *string) error { + if err := checkType(b, 2); err != nil { + return err + } + *x = string(b.data) + return nil +} + +func decodeStrings(b *buffer, x *[]string) error { + var s string + if err := decodeString(b, &s); err != nil { + return err + } + *x = append(*x, s) + return nil +} + +func decodeBool(b *buffer, x *bool) error { + if err := checkType(b, 0); err != nil { + return err + } + if int64(b.u64) == 0 { + *x = false + } else { + *x = true + } + return nil +} diff --git a/libgo/go/internal/profile/proto_test.go b/libgo/go/internal/profile/proto_test.go new file mode 100644 index 00000000000..c2613fc375a --- /dev/null +++ b/libgo/go/internal/profile/proto_test.go @@ -0,0 +1,67 @@ +package profile + +import ( + "reflect" + "testing" +) + +func TestPackedEncoding(t *testing.T) { + + type testcase struct { + uint64s []uint64 + int64s []int64 + encoded []byte + } + for i, tc := range []testcase{ + { + []uint64{0, 1, 10, 100, 1000, 10000}, + []int64{1000, 0, 1000}, + []byte{10, 8, 0, 1, 10, 100, 232, 7, 144, 78, 18, 5, 232, 7, 0, 232, 7}, + }, + { + []uint64{10000}, + nil, + []byte{8, 144, 78}, + }, + { + nil, + []int64{-10000}, + []byte{16, 240, 177, 255, 255, 255, 255, 255, 255, 255, 1}, + }, + } { + source := &packedInts{tc.uint64s, tc.int64s} + if got, want := marshal(source), tc.encoded; !reflect.DeepEqual(got, want) { + t.Errorf("failed encode %d, got %v, want %v", i, got, want) + } + + dest := new(packedInts) + if err := unmarshal(tc.encoded, dest); err != nil { + t.Errorf("failed decode %d: %v", i, err) + continue + } + if got, want := dest.uint64s, tc.uint64s; !reflect.DeepEqual(got, want) { + t.Errorf("failed decode uint64s %d, got %v, want %v", i, got, want) + } + if got, want := dest.int64s, tc.int64s; !reflect.DeepEqual(got, want) { + t.Errorf("failed decode int64s %d, got %v, want %v", i, got, want) + } + } +} + +type packedInts struct { + uint64s []uint64 + int64s []int64 +} + +func (u *packedInts) decoder() []decoder { + return []decoder{ + nil, + func(b *buffer, m message) error { return decodeUint64s(b, &m.(*packedInts).uint64s) }, + func(b *buffer, m message) error { return decodeInt64s(b, &m.(*packedInts).int64s) }, + } +} + +func (u *packedInts) encode(b *buffer) { + encodeUint64s(b, 1, u.uint64s) + encodeInt64s(b, 2, u.int64s) +} diff --git a/libgo/go/internal/profile/prune.go b/libgo/go/internal/profile/prune.go new file mode 100644 index 00000000000..1924fada7a5 --- /dev/null +++ b/libgo/go/internal/profile/prune.go @@ -0,0 +1,97 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Implements methods to remove frames from profiles. + +package profile + +import ( + "fmt" + "regexp" +) + +// Prune removes all nodes beneath a node matching dropRx, and not +// matching keepRx. If the root node of a Sample matches, the sample +// will have an empty stack. +func (p *Profile) Prune(dropRx, keepRx *regexp.Regexp) { + prune := make(map[uint64]bool) + pruneBeneath := make(map[uint64]bool) + + for _, loc := range p.Location { + var i int + for i = len(loc.Line) - 1; i >= 0; i-- { + if fn := loc.Line[i].Function; fn != nil && fn.Name != "" { + funcName := fn.Name + // Account for leading '.' on the PPC ELF v1 ABI. + if funcName[0] == '.' { + funcName = funcName[1:] + } + if dropRx.MatchString(funcName) { + if keepRx == nil || !keepRx.MatchString(funcName) { + break + } + } + } + } + + if i >= 0 { + // Found matching entry to prune. + pruneBeneath[loc.ID] = true + + // Remove the matching location. + if i == len(loc.Line)-1 { + // Matched the top entry: prune the whole location. + prune[loc.ID] = true + } else { + loc.Line = loc.Line[i+1:] + } + } + } + + // Prune locs from each Sample + for _, sample := range p.Sample { + // Scan from the root to the leaves to find the prune location. + // Do not prune frames before the first user frame, to avoid + // pruning everything. + foundUser := false + for i := len(sample.Location) - 1; i >= 0; i-- { + id := sample.Location[i].ID + if !prune[id] && !pruneBeneath[id] { + foundUser = true + continue + } + if !foundUser { + continue + } + if prune[id] { + sample.Location = sample.Location[i+1:] + break + } + if pruneBeneath[id] { + sample.Location = sample.Location[i:] + break + } + } + } +} + +// RemoveUninteresting prunes and elides profiles using built-in +// tables of uninteresting function names. +func (p *Profile) RemoveUninteresting() error { + var keep, drop *regexp.Regexp + var err error + + if p.DropFrames != "" { + if drop, err = regexp.Compile("^(" + p.DropFrames + ")$"); err != nil { + return fmt.Errorf("failed to compile regexp %s: %v", p.DropFrames, err) + } + if p.KeepFrames != "" { + if keep, err = regexp.Compile("^(" + p.KeepFrames + ")$"); err != nil { + return fmt.Errorf("failed to compile regexp %s: %v", p.KeepFrames, err) + } + } + p.Prune(drop, keep) + } + return nil +} diff --git a/libgo/go/internal/reflectlite/swapper.go b/libgo/go/internal/reflectlite/swapper.go index 4594fb5ee25..6330ab2d346 100644 --- a/libgo/go/internal/reflectlite/swapper.go +++ b/libgo/go/internal/reflectlite/swapper.go @@ -4,7 +4,10 @@ package reflectlite -import "unsafe" +import ( + "internal/unsafeheader" + "unsafe" +) // Swapper returns a function that swaps the elements in the provided // slice. @@ -58,7 +61,7 @@ func Swapper(slice interface{}) func(i, j int) { } } - s := (*sliceHeader)(v.ptr) + s := (*unsafeheader.Slice)(v.ptr) tmp := unsafe_New(typ) // swap scratch space return func(i, j int) { diff --git a/libgo/go/internal/reflectlite/value.go b/libgo/go/internal/reflectlite/value.go index 9a14d18ba2f..b78efaea4be 100644 --- a/libgo/go/internal/reflectlite/value.go +++ b/libgo/go/internal/reflectlite/value.go @@ -5,6 +5,7 @@ package reflectlite import ( + "internal/unsafeheader" "runtime" "unsafe" ) @@ -336,10 +337,10 @@ func (v Value) Len() int { return maplen(v.pointer()) case Slice: // Slice is bigger than a word; assume flagIndir. - return (*sliceHeader)(v.ptr).Len + return (*unsafeheader.Slice)(v.ptr).Len case String: // String is bigger than a word; assume flagIndir. - return (*stringHeader)(v.ptr).Len + return (*unsafeheader.String)(v.ptr).Len } panic(&ValueError{"reflect.Value.Len", v.kind()}) } @@ -380,19 +381,6 @@ func (v Value) Type() Type { return v.typ } -// stringHeader is a safe version of StringHeader used within this package. -type stringHeader struct { - Data unsafe.Pointer - Len int -} - -// sliceHeader is a safe version of SliceHeader used within this package. -type sliceHeader struct { - Data unsafe.Pointer - Len int - Cap int -} - /* * constructors */ diff --git a/libgo/go/internal/syscall/unix/copy_file_range_linux.go b/libgo/go/internal/syscall/unix/copy_file_range_linux.go new file mode 100644 index 00000000000..cf0a279a7a9 --- /dev/null +++ b/libgo/go/internal/syscall/unix/copy_file_range_linux.go @@ -0,0 +1,26 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package unix + +import ( + "syscall" + "unsafe" +) + +func CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) { + r1, _, errno := syscall.Syscall6(copyFileRangeTrap, + uintptr(rfd), + uintptr(unsafe.Pointer(roff)), + uintptr(wfd), + uintptr(unsafe.Pointer(woff)), + uintptr(len), + uintptr(flags), + ) + n = int(r1) + if errno != 0 { + err = errno + } + return +} diff --git a/libgo/go/internal/syscall/unix/getrandom_linux.go b/libgo/go/internal/syscall/unix/getrandom_linux.go index 00d8110f6fc..490d516978d 100644 --- a/libgo/go/internal/syscall/unix/getrandom_linux.go +++ b/libgo/go/internal/syscall/unix/getrandom_linux.go @@ -32,7 +32,7 @@ func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) { if atomic.LoadInt32(&randomUnsupported) != 0 { return 0, syscall.ENOSYS } - r1, _, errno := syscall.Syscall(randomTrap, + r1, _, errno := syscall.Syscall(getrandomTrap, uintptr(unsafe.Pointer(&p[0])), uintptr(len(p)), uintptr(flags)) diff --git a/libgo/go/internal/syscall/unix/getrandom_linux_386.go b/libgo/go/internal/syscall/unix/getrandom_linux_386.go deleted file mode 100644 index a583896e683..00000000000 --- a/libgo/go/internal/syscall/unix/getrandom_linux_386.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package unix - -// Linux getrandom system call number. -// See GetRandom in getrandom_linux.go. -const randomTrap uintptr = 355 diff --git a/libgo/go/internal/syscall/unix/getrandom_linux_amd64.go b/libgo/go/internal/syscall/unix/getrandom_linux_amd64.go deleted file mode 100644 index cff0eb6f052..00000000000 --- a/libgo/go/internal/syscall/unix/getrandom_linux_amd64.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package unix - -// Linux getrandom system call number. -// See GetRandom in getrandom_linux.go. -const randomTrap uintptr = 318 diff --git a/libgo/go/internal/syscall/unix/getrandom_linux_arm.go b/libgo/go/internal/syscall/unix/getrandom_linux_arm.go deleted file mode 100644 index 92e2492cd03..00000000000 --- a/libgo/go/internal/syscall/unix/getrandom_linux_arm.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package unix - -// Linux getrandom system call number. -// See GetRandom in getrandom_linux.go. -const randomTrap uintptr = 384 diff --git a/libgo/go/internal/syscall/unix/getrandom_linux_generic.go b/libgo/go/internal/syscall/unix/getrandom_linux_generic.go deleted file mode 100644 index 007e769c397..00000000000 --- a/libgo/go/internal/syscall/unix/getrandom_linux_generic.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build linux -// +build arm64 arm64be nios2 riscv riscv64 - -package unix - -// Linux getrandom system call number. -// See GetRandom in getrandom_linux.go. -// -// This file is named "generic" because at a certain point Linux started -// standardizing on system call numbers across architectures. So far this means -// only arm64 and riscv64 use the standard numbers. -const randomTrap uintptr = 278 diff --git a/libgo/go/internal/syscall/unix/getrandom_linux_mips64x.go b/libgo/go/internal/syscall/unix/getrandom_linux_mips64x.go deleted file mode 100644 index b328b8f1f0e..00000000000 --- a/libgo/go/internal/syscall/unix/getrandom_linux_mips64x.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build mips64 mips64le - -package unix - -// Linux getrandom system call number. -// See GetRandom in getrandom_linux.go. -const randomTrap uintptr = 5313 diff --git a/libgo/go/internal/syscall/unix/getrandom_linux_mipsx.go b/libgo/go/internal/syscall/unix/getrandom_linux_mipsx.go deleted file mode 100644 index af7b7229b1b..00000000000 --- a/libgo/go/internal/syscall/unix/getrandom_linux_mipsx.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build mips mipsle - -package unix - -// Linux getrandom system call number. -// See GetRandom in getrandom_linux.go. -const randomTrap uintptr = 4353 diff --git a/libgo/go/internal/syscall/unix/getrandom_linux_ppc64x.go b/libgo/go/internal/syscall/unix/getrandom_linux_ppc64x.go deleted file mode 100644 index a7d0bd9f73a..00000000000 --- a/libgo/go/internal/syscall/unix/getrandom_linux_ppc64x.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ppc ppc64 ppc64le - -package unix - -// Linux getrandom system call number. -// See GetRandom in getrandom_linux.go. -const randomTrap uintptr = 359 diff --git a/libgo/go/internal/syscall/unix/getrandom_linux_s390x.go b/libgo/go/internal/syscall/unix/getrandom_linux_s390x.go deleted file mode 100644 index e3bc4ee355c..00000000000 --- a/libgo/go/internal/syscall/unix/getrandom_linux_s390x.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package unix - -// Linux getrandom system call number. -// See GetRandom in getrandom_linux.go. -const randomTrap uintptr = 349 diff --git a/libgo/go/internal/syscall/unix/sysnum_linux_386.go b/libgo/go/internal/syscall/unix/sysnum_linux_386.go new file mode 100644 index 00000000000..2bda08ccf1a --- /dev/null +++ b/libgo/go/internal/syscall/unix/sysnum_linux_386.go @@ -0,0 +1,10 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package unix + +const ( + getrandomTrap uintptr = 355 + copyFileRangeTrap uintptr = 377 +) diff --git a/libgo/go/internal/syscall/unix/sysnum_linux_amd64.go b/libgo/go/internal/syscall/unix/sysnum_linux_amd64.go new file mode 100644 index 00000000000..ae5239ebfb5 --- /dev/null +++ b/libgo/go/internal/syscall/unix/sysnum_linux_amd64.go @@ -0,0 +1,10 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package unix + +const ( + getrandomTrap uintptr = 318 + copyFileRangeTrap uintptr = 326 +) diff --git a/libgo/go/internal/syscall/unix/sysnum_linux_arm.go b/libgo/go/internal/syscall/unix/sysnum_linux_arm.go new file mode 100644 index 00000000000..acaec058790 --- /dev/null +++ b/libgo/go/internal/syscall/unix/sysnum_linux_arm.go @@ -0,0 +1,10 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package unix + +const ( + getrandomTrap uintptr = 384 + copyFileRangeTrap uintptr = 391 +) diff --git a/libgo/go/internal/syscall/unix/sysnum_linux_generic.go b/libgo/go/internal/syscall/unix/sysnum_linux_generic.go new file mode 100644 index 00000000000..f48da40188e --- /dev/null +++ b/libgo/go/internal/syscall/unix/sysnum_linux_generic.go @@ -0,0 +1,17 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build linux +// +build arm64 riscv64 + +package unix + +// This file is named "generic" because at a certain point Linux started +// standardizing on system call numbers across architectures. So far this +// means only arm64 and riscv64 use the standard numbers. + +const ( + getrandomTrap uintptr = 278 + copyFileRangeTrap uintptr = 285 +) diff --git a/libgo/go/internal/syscall/unix/sysnum_linux_mips64x.go b/libgo/go/internal/syscall/unix/sysnum_linux_mips64x.go new file mode 100644 index 00000000000..6680942cb8b --- /dev/null +++ b/libgo/go/internal/syscall/unix/sysnum_linux_mips64x.go @@ -0,0 +1,12 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build mips64 mips64le + +package unix + +const ( + getrandomTrap uintptr = 5313 + copyFileRangeTrap uintptr = 5320 +) diff --git a/libgo/go/internal/syscall/unix/sysnum_linux_mipsx.go b/libgo/go/internal/syscall/unix/sysnum_linux_mipsx.go new file mode 100644 index 00000000000..185d8320c9e --- /dev/null +++ b/libgo/go/internal/syscall/unix/sysnum_linux_mipsx.go @@ -0,0 +1,12 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build mips mipsle + +package unix + +const ( + getrandomTrap uintptr = 4353 + copyFileRangeTrap uintptr = 4360 +) diff --git a/libgo/go/internal/syscall/unix/sysnum_linux_ppc64x.go b/libgo/go/internal/syscall/unix/sysnum_linux_ppc64x.go new file mode 100644 index 00000000000..576937e3f5c --- /dev/null +++ b/libgo/go/internal/syscall/unix/sysnum_linux_ppc64x.go @@ -0,0 +1,12 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ppc64 ppc64le + +package unix + +const ( + getrandomTrap uintptr = 359 + copyFileRangeTrap uintptr = 379 +) diff --git a/libgo/go/internal/syscall/unix/sysnum_linux_s390x.go b/libgo/go/internal/syscall/unix/sysnum_linux_s390x.go new file mode 100644 index 00000000000..bf2c01e4e16 --- /dev/null +++ b/libgo/go/internal/syscall/unix/sysnum_linux_s390x.go @@ -0,0 +1,10 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package unix + +const ( + getrandomTrap uintptr = 349 + copyFileRangeTrap uintptr = 375 +) diff --git a/libgo/go/internal/syscall/windows/syscall_windows.go b/libgo/go/internal/syscall/windows/syscall_windows.go index dc641116bae..edf0b5a40b8 100644 --- a/libgo/go/internal/syscall/windows/syscall_windows.go +++ b/libgo/go/internal/syscall/windows/syscall_windows.go @@ -5,6 +5,7 @@ package windows import ( + "internal/unsafeheader" "sync" "syscall" "unicode/utf16" @@ -13,20 +14,24 @@ import ( // UTF16PtrToString is like UTF16ToString, but takes *uint16 // as a parameter instead of []uint16. -// max is how many times p can be advanced looking for the null terminator. -// If max is hit, the string is truncated at that point. -func UTF16PtrToString(p *uint16, max int) string { +func UTF16PtrToString(p *uint16) string { if p == nil { return "" } // Find NUL terminator. end := unsafe.Pointer(p) n := 0 - for *(*uint16)(end) != 0 && n < max { + for *(*uint16)(end) != 0 { end = unsafe.Pointer(uintptr(end) + unsafe.Sizeof(*p)) n++ } - s := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(p))[:n:n] + // Turn *uint16 into []uint16. + var s []uint16 + hdr := (*unsafeheader.Slice)(unsafe.Pointer(&s)) + hdr.Data = unsafe.Pointer(p) + hdr.Cap = n + hdr.Len = n + // Decode []uint16 into string. return string(utf16.Decode(s)) } @@ -176,7 +181,7 @@ var sendRecvMsgFunc struct { } type WSAMsg struct { - Name *syscall.RawSockaddrAny + Name syscall.Pointer Namelen int32 Buffers *syscall.WSABuf BufferCount uint32 diff --git a/libgo/go/internal/testenv/testenv.go b/libgo/go/internal/testenv/testenv.go index c2e9d98f03c..5de56d99ece 100644 --- a/libgo/go/internal/testenv/testenv.go +++ b/libgo/go/internal/testenv/testenv.go @@ -53,7 +53,7 @@ func HasGoBuild() bool { case "android", "js": return false case "darwin": - if strings.HasPrefix(runtime.GOARCH, "arm") { + if runtime.GOARCH == "arm64" { return false } } @@ -139,7 +139,7 @@ func HasExec() bool { case "js": return false case "darwin": - if strings.HasPrefix(runtime.GOARCH, "arm") { + if runtime.GOARCH == "arm64" { return false } } @@ -150,7 +150,7 @@ func HasExec() bool { func HasSrc() bool { switch runtime.GOOS { case "darwin": - if strings.HasPrefix(runtime.GOARCH, "arm") { + if runtime.GOARCH == "arm64" { return false } } diff --git a/libgo/go/internal/trace/writer.go b/libgo/go/internal/trace/writer.go index af5fec84fd1..dd0b9f104ed 100644 --- a/libgo/go/internal/trace/writer.go +++ b/libgo/go/internal/trace/writer.go @@ -1,3 +1,7 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package trace import "bytes" diff --git a/libgo/go/internal/unsafeheader/unsafeheader.go b/libgo/go/internal/unsafeheader/unsafeheader.go new file mode 100644 index 00000000000..6d092c629a2 --- /dev/null +++ b/libgo/go/internal/unsafeheader/unsafeheader.go @@ -0,0 +1,37 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package unsafeheader contains header declarations for the Go runtime's slice +// and string implementations. +// +// This package allows packages that cannot import "reflect" to use types that +// are tested to be equivalent to reflect.SliceHeader and reflect.StringHeader. +package unsafeheader + +import ( + "unsafe" +) + +// Slice is the runtime representation of a slice. +// It cannot be used safely or portably and its representation may +// change in a later release. +// +// Unlike reflect.SliceHeader, its Data field is sufficient to guarantee the +// data it references will not be garbage collected. +type Slice struct { + Data unsafe.Pointer + Len int + Cap int +} + +// String is the runtime representation of a string. +// It cannot be used safely or portably and its representation may +// change in a later release. +// +// Unlike reflect.StringHeader, its Data field is sufficient to guarantee the +// data it references will not be garbage collected. +type String struct { + Data unsafe.Pointer + Len int +} diff --git a/libgo/go/internal/unsafeheader/unsafeheader_test.go b/libgo/go/internal/unsafeheader/unsafeheader_test.go new file mode 100644 index 00000000000..6fb7cca888f --- /dev/null +++ b/libgo/go/internal/unsafeheader/unsafeheader_test.go @@ -0,0 +1,100 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package unsafeheader_test + +import ( + "bytes" + "internal/unsafeheader" + "reflect" + "testing" + "unsafe" +) + +// TestTypeMatchesReflectType ensures that the name and layout of the +// unsafeheader types matches the corresponding Header types in the reflect +// package. +func TestTypeMatchesReflectType(t *testing.T) { + t.Run("Slice", func(t *testing.T) { + testHeaderMatchesReflect(t, unsafeheader.Slice{}, reflect.SliceHeader{}) + }) + + t.Run("String", func(t *testing.T) { + testHeaderMatchesReflect(t, unsafeheader.String{}, reflect.StringHeader{}) + }) +} + +func testHeaderMatchesReflect(t *testing.T, header, reflectHeader interface{}) { + h := reflect.TypeOf(header) + rh := reflect.TypeOf(reflectHeader) + + for i := 0; i < h.NumField(); i++ { + f := h.Field(i) + rf, ok := rh.FieldByName(f.Name) + if !ok { + t.Errorf("Field %d of %v is named %s, but no such field exists in %v", i, h, f.Name, rh) + continue + } + if !typeCompatible(f.Type, rf.Type) { + t.Errorf("%v.%s has type %v, but %v.%s has type %v", h, f.Name, f.Type, rh, rf.Name, rf.Type) + } + if f.Offset != rf.Offset { + t.Errorf("%v.%s has offset %d, but %v.%s has offset %d", h, f.Name, f.Offset, rh, rf.Name, rf.Offset) + } + } + + if h.NumField() != rh.NumField() { + t.Errorf("%v has %d fields, but %v has %d", h, h.NumField(), rh, rh.NumField()) + } + if h.Align() != rh.Align() { + t.Errorf("%v has alignment %d, but %v has alignment %d", h, h.Align(), rh, rh.Align()) + } +} + +var ( + unsafePointerType = reflect.TypeOf(unsafe.Pointer(nil)) + uintptrType = reflect.TypeOf(uintptr(0)) +) + +func typeCompatible(t, rt reflect.Type) bool { + return t == rt || (t == unsafePointerType && rt == uintptrType) +} + +// TestWriteThroughHeader ensures that the headers in the unsafeheader package +// can successfully mutate variables of the corresponding built-in types. +// +// This test is expected to fail under -race (which implicitly enables +// -d=checkptr) if the runtime views the header types as incompatible with the +// underlying built-in types. +func TestWriteThroughHeader(t *testing.T) { + t.Run("Slice", func(t *testing.T) { + s := []byte("Hello, checkptr!")[:5] + + var alias []byte + hdr := (*unsafeheader.Slice)(unsafe.Pointer(&alias)) + hdr.Data = unsafe.Pointer(&s[0]) + hdr.Cap = cap(s) + hdr.Len = len(s) + + if !bytes.Equal(alias, s) { + t.Errorf("alias of %T(%q) constructed via Slice = %T(%q)", s, s, alias, alias) + } + if cap(alias) != cap(s) { + t.Errorf("alias of %T with cap %d has cap %d", s, cap(s), cap(alias)) + } + }) + + t.Run("String", func(t *testing.T) { + s := "Hello, checkptr!" + + var alias string + hdr := (*unsafeheader.String)(unsafe.Pointer(&alias)) + hdr.Data = (*unsafeheader.String)(unsafe.Pointer(&s)).Data + hdr.Len = len(s) + + if alias != s { + t.Errorf("alias of %q constructed via String = %q", s, alias) + } + }) +} diff --git a/libgo/go/internal/xcoff/file.go b/libgo/go/internal/xcoff/file.go index 66b5391d583..05e4fd555cc 100644 --- a/libgo/go/internal/xcoff/file.go +++ b/libgo/go/internal/xcoff/file.go @@ -412,10 +412,10 @@ func NewFile(r io.ReaderAt) (*File, error) { sect.Relocs[i].Type = rel.Rtype sect.Relocs[i].Length = rel.Rsize&0x3F + 1 - if rel.Rsize&0x80 == 1 { + if rel.Rsize&0x80 != 0 { sect.Relocs[i].Signed = true } - if rel.Rsize&0x40 == 1 { + if rel.Rsize&0x40 != 0 { sect.Relocs[i].InstructionFixed = true } @@ -428,10 +428,10 @@ func NewFile(r io.ReaderAt) (*File, error) { sect.Relocs[i].Symbol = idxToSym[int(rel.Rsymndx)] sect.Relocs[i].Type = rel.Rtype sect.Relocs[i].Length = rel.Rsize&0x3F + 1 - if rel.Rsize&0x80 == 1 { + if rel.Rsize&0x80 != 0 { sect.Relocs[i].Signed = true } - if rel.Rsize&0x40 == 1 { + if rel.Rsize&0x40 != 0 { sect.Relocs[i].InstructionFixed = true } } diff --git a/libgo/go/io/example_test.go b/libgo/go/io/example_test.go index 2eaab678c9f..465eed4d5e4 100644 --- a/libgo/go/io/example_test.go +++ b/libgo/go/io/example_test.go @@ -48,7 +48,7 @@ func ExampleCopyBuffer() { func ExampleCopyN() { r := strings.NewReader("some io.Reader stream to be read") - if _, err := io.CopyN(os.Stdout, r, 5); err != nil { + if _, err := io.CopyN(os.Stdout, r, 4); err != nil { log.Fatal(err) } @@ -136,25 +136,15 @@ func ExampleMultiReader() { } func ExampleTeeReader() { - r := strings.NewReader("some io.Reader stream to be read\n") - var buf bytes.Buffer - tee := io.TeeReader(r, &buf) - - printall := func(r io.Reader) { - b, err := ioutil.ReadAll(r) - if err != nil { - log.Fatal(err) - } + var r io.Reader = strings.NewReader("some io.Reader stream to be read\n") - fmt.Printf("%s", b) - } + r = io.TeeReader(r, os.Stdout) - printall(tee) - printall(&buf) + // Everything read from r will be copied to stdout. + ioutil.ReadAll(r) // Output: // some io.Reader stream to be read - // some io.Reader stream to be read } func ExampleSectionReader() { @@ -171,7 +161,7 @@ func ExampleSectionReader() { func ExampleSectionReader_ReadAt() { r := strings.NewReader("some io.Reader stream to be read\n") - s := io.NewSectionReader(r, 5, 16) + s := io.NewSectionReader(r, 5, 17) buf := make([]byte, 6) if _, err := s.ReadAt(buf, 10); err != nil { @@ -186,30 +176,24 @@ func ExampleSectionReader_ReadAt() { func ExampleSectionReader_Seek() { r := strings.NewReader("some io.Reader stream to be read\n") - s := io.NewSectionReader(r, 5, 16) + s := io.NewSectionReader(r, 5, 17) if _, err := s.Seek(10, io.SeekStart); err != nil { log.Fatal(err) } - buf := make([]byte, 6) - if _, err := s.Read(buf); err != nil { + if _, err := io.Copy(os.Stdout, s); err != nil { log.Fatal(err) } - fmt.Printf("%s\n", buf) - // Output: // stream } func ExampleSeeker_Seek() { r := strings.NewReader("some io.Reader stream to be read\n") - if _, err := io.Copy(os.Stdout, r); err != nil { - log.Fatal(err) - } - r.Seek(15, io.SeekStart) + r.Seek(5, io.SeekStart) // move to the 5th char from the start if _, err := io.Copy(os.Stdout, r); err != nil { log.Fatal(err) } @@ -220,8 +204,7 @@ func ExampleSeeker_Seek() { } // Output: - // some io.Reader stream to be read - // stream to be read + // io.Reader stream to be read // read } @@ -247,14 +230,14 @@ func ExamplePipe() { r, w := io.Pipe() go func() { - fmt.Fprint(w, "some text to be read\n") + fmt.Fprint(w, "some io.Reader stream to be read\n") w.Close() }() - buf := new(bytes.Buffer) - buf.ReadFrom(r) - fmt.Print(buf.String()) + if _, err := io.Copy(os.Stdout, r); err != nil { + log.Fatal(err) + } // Output: - // some text to be read + // some io.Reader stream to be read } diff --git a/libgo/go/io/io.go b/libgo/go/io/io.go index 9cc3086c19b..3dea70b947b 100644 --- a/libgo/go/io/io.go +++ b/libgo/go/io/io.go @@ -236,6 +236,10 @@ type WriterAt interface { // ReadByte reads and returns the next byte from the input or // any error encountered. If ReadByte returns an error, no input // byte was consumed, and the returned byte value is undefined. +// +// ReadByte provides an efficient interface for byte-at-time +// processing. A Reader that does not implement ByteReader +// can be wrapped using bufio.NewReader to add this method. type ByteReader interface { ReadByte() (byte, error) } diff --git a/libgo/go/io/io_test.go b/libgo/go/io/io_test.go index ca90403c59c..170513dcc0d 100644 --- a/libgo/go/io/io_test.go +++ b/libgo/go/io/io_test.go @@ -285,6 +285,9 @@ func testReadAtLeast(t *testing.T, rb ReadWriter) { if err != nil { t.Error(err) } + if n != 2 { + t.Errorf("expected to have read 2 bytes, got %v", n) + } n, err = ReadAtLeast(rb, buf, 4) if err != ErrShortBuffer { t.Errorf("expected ErrShortBuffer got %v", err) diff --git a/libgo/go/io/ioutil/export_test.go b/libgo/go/io/ioutil/export_test.go new file mode 100644 index 00000000000..dff55f07e26 --- /dev/null +++ b/libgo/go/io/ioutil/export_test.go @@ -0,0 +1,7 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ioutil + +var ErrPatternHasSeparator = errPatternHasSeparator diff --git a/libgo/go/io/ioutil/ioutil.go b/libgo/go/io/ioutil/ioutil.go index b1cb841468f..acc6ec3a40a 100644 --- a/libgo/go/io/ioutil/ioutil.go +++ b/libgo/go/io/ioutil/ioutil.go @@ -75,7 +75,7 @@ func ReadFile(filename string) ([]byte, error) { // WriteFile writes data to a file named by filename. // If the file does not exist, WriteFile creates it with permissions perm -// (before umask); otherwise WriteFile truncates it before writing. +// (before umask); otherwise WriteFile truncates it before writing, without changing permissions. func WriteFile(filename string, data []byte, perm os.FileMode) error { f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) if err != nil { diff --git a/libgo/go/io/ioutil/ioutil_test.go b/libgo/go/io/ioutil/ioutil_test.go index 1fc4c8b7949..faea02ced52 100644 --- a/libgo/go/io/ioutil/ioutil_test.go +++ b/libgo/go/io/ioutil/ioutil_test.go @@ -2,10 +2,11 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package ioutil +package ioutil_test import ( "bytes" + . "io/ioutil" "os" "path/filepath" "testing" diff --git a/libgo/go/io/ioutil/tempfile.go b/libgo/go/io/ioutil/tempfile.go index 3aa23c5f017..af7c6fd7c1a 100644 --- a/libgo/go/io/ioutil/tempfile.go +++ b/libgo/go/io/ioutil/tempfile.go @@ -5,6 +5,7 @@ package ioutil import ( + "errors" "os" "path/filepath" "strconv" @@ -52,7 +53,10 @@ func TempFile(dir, pattern string) (f *os.File, err error) { dir = os.TempDir() } - prefix, suffix := prefixAndSuffix(pattern) + prefix, suffix, err := prefixAndSuffix(pattern) + if err != nil { + return + } nconflict := 0 for i := 0; i < 10000; i++ { @@ -71,9 +75,15 @@ func TempFile(dir, pattern string) (f *os.File, err error) { return } +var errPatternHasSeparator = errors.New("pattern contains path separator") + // prefixAndSuffix splits pattern by the last wildcard "*", if applicable, // returning prefix as the part before "*" and suffix as the part after "*". -func prefixAndSuffix(pattern string) (prefix, suffix string) { +func prefixAndSuffix(pattern string) (prefix, suffix string, err error) { + if strings.ContainsRune(pattern, os.PathSeparator) { + err = errPatternHasSeparator + return + } if pos := strings.LastIndex(pattern, "*"); pos != -1 { prefix, suffix = pattern[:pos], pattern[pos+1:] } else { @@ -96,7 +106,10 @@ func TempDir(dir, pattern string) (name string, err error) { dir = os.TempDir() } - prefix, suffix := prefixAndSuffix(pattern) + prefix, suffix, err := prefixAndSuffix(pattern) + if err != nil { + return + } nconflict := 0 for i := 0; i < 10000; i++ { diff --git a/libgo/go/io/ioutil/tempfile_test.go b/libgo/go/io/ioutil/tempfile_test.go index 698ebabee9e..fcc5101fcc8 100644 --- a/libgo/go/io/ioutil/tempfile_test.go +++ b/libgo/go/io/ioutil/tempfile_test.go @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package ioutil +package ioutil_test import ( + . "io/ioutil" "os" "path/filepath" "regexp" @@ -48,6 +49,48 @@ func TestTempFile_pattern(t *testing.T) { } } +func TestTempFile_BadPattern(t *testing.T) { + tmpDir, err := TempDir("", t.Name()) + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpDir) + + const sep = string(os.PathSeparator) + tests := []struct { + pattern string + wantErr bool + }{ + {"ioutil*test", false}, + {"ioutil_test*foo", false}, + {"ioutil_test" + sep + "foo", true}, + {"ioutil_test*" + sep + "foo", true}, + {"ioutil_test" + sep + "*foo", true}, + {sep + "ioutil_test" + sep + "*foo", true}, + {"ioutil_test*foo" + sep, true}, + } + for _, tt := range tests { + t.Run(tt.pattern, func(t *testing.T) { + tmpfile, err := TempFile(tmpDir, tt.pattern) + defer func() { + if tmpfile != nil { + tmpfile.Close() + } + }() + if tt.wantErr { + if err == nil { + t.Errorf("Expected an error for pattern %q", tt.pattern) + } + if g, w := err, ErrPatternHasSeparator; g != w { + t.Errorf("Error mismatch: got %#v, want %#v for pattern %q", g, w, tt.pattern) + } + } else if err != nil { + t.Errorf("Unexpected error %v for pattern %q", err, tt.pattern) + } + }) + } +} + func TestTempDir(t *testing.T) { name, err := TempDir("/_not_exists_", "foo") if name != "" || err == nil { @@ -112,3 +155,40 @@ func TestTempDir_BadDir(t *testing.T) { t.Errorf("TempDir error = %#v; want PathError for path %q satisifying os.IsNotExist", err, badDir) } } + +func TestTempDir_BadPattern(t *testing.T) { + tmpDir, err := TempDir("", t.Name()) + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpDir) + + const sep = string(os.PathSeparator) + tests := []struct { + pattern string + wantErr bool + }{ + {"ioutil*test", false}, + {"ioutil_test*foo", false}, + {"ioutil_test" + sep + "foo", true}, + {"ioutil_test*" + sep + "foo", true}, + {"ioutil_test" + sep + "*foo", true}, + {sep + "ioutil_test" + sep + "*foo", true}, + {"ioutil_test*foo" + sep, true}, + } + for _, tt := range tests { + t.Run(tt.pattern, func(t *testing.T) { + _, err := TempDir(tmpDir, tt.pattern) + if tt.wantErr { + if err == nil { + t.Errorf("Expected an error for pattern %q", tt.pattern) + } + if g, w := err, ErrPatternHasSeparator; g != w { + t.Errorf("Error mismatch: got %#v, want %#v for pattern %q", g, w, tt.pattern) + } + } else if err != nil { + t.Errorf("Unexpected error %v for pattern %q", err, tt.pattern) + } + }) + } +} diff --git a/libgo/go/log/syslog/syslog_test.go b/libgo/go/log/syslog/syslog_test.go index 8df8ebbf585..f778e965f3b 100644 --- a/libgo/go/log/syslog/syslog_test.go +++ b/libgo/go/log/syslog/syslog_test.go @@ -53,7 +53,7 @@ func testableNetwork(network string) bool { switch runtime.GOOS { case "darwin": switch runtime.GOARCH { - case "arm", "arm64": + case "arm64": return false } case "android": @@ -356,7 +356,7 @@ func TestConcurrentReconnect(t *testing.T) { } // count all the messages arriving - count := make(chan int) + count := make(chan int, 1) go func() { ct := 0 for range done { diff --git a/libgo/go/math/all_test.go b/libgo/go/math/all_test.go index 1ac9d71a251..3aae0373c76 100644 --- a/libgo/go/math/all_test.go +++ b/libgo/go/math/all_test.go @@ -827,6 +827,8 @@ var vfatan2SC = [][2]float64{ {+Pi, Inf(-1)}, {+Pi, 0}, {+Pi, Inf(1)}, + {1.0, Inf(1)}, + {-1.0, Inf(1)}, {+Pi, NaN()}, {Inf(1), Inf(-1)}, {Inf(1), -Pi}, @@ -864,6 +866,8 @@ var atan2SC = []float64{ Pi, // atan2(+Pi, -Inf) Pi / 2, // atan2(+Pi, +0) 0, // atan2(+Pi, +Inf) + 0, // atan2(+1, +Inf) + Copysign(0, -1), // atan2(-1, +Inf) NaN(), // atan2(+Pi, NaN) 3 * Pi / 4, // atan2(+Inf, -Inf) Pi / 2, // atan2(+Inf, -Pi) diff --git a/libgo/go/math/arith_s390x.go b/libgo/go/math/arith_s390x.go index 8d1fa6afb90..c28651e5f9f 100644 --- a/libgo/go/math/arith_s390x.go +++ b/libgo/go/math/arith_s390x.go @@ -6,6 +6,8 @@ package math +import "internal/cpu" + func log10TrampolineSetup(x float64) float64 func log10Asm(x float64) float64 @@ -72,8 +74,6 @@ func expm1Asm(x float64) float64 func powTrampolineSetup(x, y float64) float64 func powAsm(x, y float64) float64 -// hasVectorFacility reports whether the machine has the z/Architecture +// hasVX reports whether the machine has the z/Architecture // vector facility installed and enabled. -func hasVectorFacility() bool - -var hasVX = hasVectorFacility() +var hasVX = cpu.S390X.HasVX diff --git a/libgo/go/math/big/arith_decl.go b/libgo/go/math/big/arith_decl.go index 0a139f189dc..61df0df9f24 100644 --- a/libgo/go/math/big/arith_decl.go +++ b/libgo/go/math/big/arith_decl.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // +build ignore -// +build !math_big_pure_go,!riscv64 +// +build !math_big_pure_go package big diff --git a/libgo/go/math/big/arith_decl_pure.go b/libgo/go/math/big/arith_decl_pure.go index 8853eb68540..ee8f92211e8 100644 --- a/libgo/go/math/big/arith_decl_pure.go +++ b/libgo/go/math/big/arith_decl_pure.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// -build math_big_pure_go riscv64 +// -build math_big_pure_go package big diff --git a/libgo/go/math/big/arith_decl_s390x.go b/libgo/go/math/big/arith_decl_s390x.go index 3936d3faad4..712f115e7d1 100644 --- a/libgo/go/math/big/arith_decl_s390x.go +++ b/libgo/go/math/big/arith_decl_s390x.go @@ -7,18 +7,13 @@ package big +import "internal/cpu" + func addVV_check(z, x, y []Word) (c Word) func addVV_vec(z, x, y []Word) (c Word) func addVV_novec(z, x, y []Word) (c Word) func subVV_check(z, x, y []Word) (c Word) func subVV_vec(z, x, y []Word) (c Word) func subVV_novec(z, x, y []Word) (c Word) -func addVW_check(z, x []Word, y Word) (c Word) -func addVW_vec(z, x []Word, y Word) (c Word) -func addVW_novec(z, x []Word, y Word) (c Word) -func subVW_check(z, x []Word, y Word) (c Word) -func subVW_vec(z, x []Word, y Word) (c Word) -func subVW_novec(z, x []Word, y Word) (c Word) -func hasVectorFacility() bool -var hasVX = hasVectorFacility() +var hasVX = cpu.S390X.HasVX diff --git a/libgo/go/math/big/arith_s390x_test.go b/libgo/go/math/big/arith_s390x_test.go index 0e8ac857d96..be1ca7dda36 100644 --- a/libgo/go/math/big/arith_s390x_test.go +++ b/libgo/go/math/big/arith_s390x_test.go @@ -31,15 +31,3 @@ func TestFunVVnovec(t *testing.T) { } } } - -func TestFunVWnovec(t *testing.T) { - if hasVX == true { - for _, a := range sumVW { - arg := a - testFunVW(t, "addVW_novec", addVW_novec, arg) - - arg = argVW{a.x, a.z, a.y, a.c} - testFunVW(t, "subVW_novec", subVW_novec, arg) - } - } -} diff --git a/libgo/go/math/big/float.go b/libgo/go/math/big/float.go index b3c32952014..da964eef3e8 100644 --- a/libgo/go/math/big/float.go +++ b/libgo/go/math/big/float.go @@ -224,7 +224,9 @@ func (x *Float) Mode() RoundingMode { return x.mode } -// Acc returns the accuracy of x produced by the most recent operation. +// Acc returns the accuracy of x produced by the most recent +// operation, unless explicitly documented otherwise by that +// operation. func (x *Float) Acc() Accuracy { return x.acc } diff --git a/libgo/go/math/big/floatconv.go b/libgo/go/math/big/floatconv.go index 95e32d3319c..57b7df3936f 100644 --- a/libgo/go/math/big/floatconv.go +++ b/libgo/go/math/big/floatconv.go @@ -290,7 +290,7 @@ func ParseFloat(s string, base int, prec uint, mode RoundingMode) (f *Float, b i return new(Float).SetPrec(prec).SetMode(mode).Parse(s, base) } -var _ fmt.Scanner = &floatZero // *Float must implement fmt.Scanner +var _ fmt.Scanner = (*Float)(nil) // *Float must implement fmt.Scanner // Scan is a support routine for fmt.Scanner; it sets z to the value of // the scanned number. It accepts formats whose verbs are supported by diff --git a/libgo/go/math/big/int.go b/libgo/go/math/big/int.go index 18f122e953c..65f32487b58 100644 --- a/libgo/go/math/big/int.go +++ b/libgo/go/math/big/int.go @@ -447,11 +447,26 @@ func (z *Int) SetBytes(buf []byte) *Int { } // Bytes returns the absolute value of x as a big-endian byte slice. +// +// To use a fixed length slice, or a preallocated one, use FillBytes. func (x *Int) Bytes() []byte { buf := make([]byte, len(x.abs)*_S) return buf[x.abs.bytes(buf):] } +// FillBytes sets buf to the absolute value of x, storing it as a zero-extended +// big-endian byte slice, and returns buf. +// +// If the absolute value of x doesn't fit in buf, FillBytes will panic. +func (x *Int) FillBytes(buf []byte) []byte { + // Clear whole buffer. (This gets optimized into a memclr.) + for i := range buf { + buf[i] = 0 + } + x.abs.bytes(buf) + return buf +} + // BitLen returns the length of the absolute value of x in bits. // The bit length of 0 is 0. func (x *Int) BitLen() int { @@ -465,8 +480,8 @@ func (x *Int) TrailingZeroBits() uint { } // Exp sets z = x**y mod |m| (i.e. the sign of m is ignored), and returns z. -// If m == nil or m == 0, z = x**y unless y <= 0 then z = 1. If m > 0, y < 0, -// and x and n are not relatively prime, z is unchanged and nil is returned. +// If m == nil or m == 0, z = x**y unless y <= 0 then z = 1. If m != 0, y < 0, +// and x and m are not relatively prime, z is unchanged and nil is returned. // // Modular exponentiation of inputs of a particular size is not a // cryptographically constant-time operation. diff --git a/libgo/go/math/big/int_test.go b/libgo/go/math/big/int_test.go index e3a1587b3f0..3c8557323a0 100644 --- a/libgo/go/math/big/int_test.go +++ b/libgo/go/math/big/int_test.go @@ -1840,3 +1840,57 @@ func BenchmarkDiv(b *testing.B) { }) } } + +func TestFillBytes(t *testing.T) { + checkResult := func(t *testing.T, buf []byte, want *Int) { + t.Helper() + got := new(Int).SetBytes(buf) + if got.CmpAbs(want) != 0 { + t.Errorf("got 0x%x, want 0x%x: %x", got, want, buf) + } + } + panics := func(f func()) (panic bool) { + defer func() { panic = recover() != nil }() + f() + return + } + + for _, n := range []string{ + "0", + "1000", + "0xffffffff", + "-0xffffffff", + "0xffffffffffffffff", + "0x10000000000000000", + "0xabababababababababababababababababababababababababa", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + } { + t.Run(n, func(t *testing.T) { + t.Logf(n) + x, ok := new(Int).SetString(n, 0) + if !ok { + panic("invalid test entry") + } + + // Perfectly sized buffer. + byteLen := (x.BitLen() + 7) / 8 + buf := make([]byte, byteLen) + checkResult(t, x.FillBytes(buf), x) + + // Way larger, checking all bytes get zeroed. + buf = make([]byte, 100) + for i := range buf { + buf[i] = 0xff + } + checkResult(t, x.FillBytes(buf), x) + + // Too small. + if byteLen > 0 { + buf = make([]byte, byteLen-1) + if !panics(func() { x.FillBytes(buf) }) { + t.Errorf("expected panic for small buffer and value %x", x) + } + } + }) + } +} diff --git a/libgo/go/math/big/link_test.go b/libgo/go/math/big/link_test.go new file mode 100644 index 00000000000..2212bd444ff --- /dev/null +++ b/libgo/go/math/big/link_test.go @@ -0,0 +1,63 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package big + +import ( + "bytes" + "internal/testenv" + "io/ioutil" + "os/exec" + "path/filepath" + "testing" +) + +// Tests that the linker is able to remove references to Float, Rat, +// and Int if unused (notably, not used by init). +func TestLinkerGC(t *testing.T) { + if testing.Short() { + t.Skip("skipping in short mode") + } + t.Parallel() + tmp := t.TempDir() + goBin := testenv.GoToolPath(t) + goFile := filepath.Join(tmp, "x.go") + file := []byte(`package main +import _ "math/big" +func main() {} +`) + if err := ioutil.WriteFile(goFile, file, 0644); err != nil { + t.Fatal(err) + } + cmd := exec.Command(goBin, "build", "-o", "x.exe", "x.go") + cmd.Dir = tmp + if out, err := cmd.CombinedOutput(); err != nil { + t.Fatalf("compile: %v, %s", err, out) + } + + cmd = exec.Command(goBin, "tool", "nm", "x.exe") + cmd.Dir = tmp + nm, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("nm: %v, %s", err, nm) + } + const want = "runtime.(*Frames).Next" + if !bytes.Contains(nm, []byte(want)) { + // Test the test. + t.Errorf("expected symbol %q not found", want) + } + bad := []string{ + "math/big.(*Float)", + "math/big.(*Rat)", + "math/big.(*Int)", + } + for _, sym := range bad { + if bytes.Contains(nm, []byte(sym)) { + t.Errorf("unexpected symbol %q found", sym) + } + } + if t.Failed() { + t.Logf("Got: %s", nm) + } +} diff --git a/libgo/go/math/big/nat.go b/libgo/go/math/big/nat.go index c31ec5156b8..6a3989bf9d8 100644 --- a/libgo/go/math/big/nat.go +++ b/libgo/go/math/big/nat.go @@ -1476,19 +1476,26 @@ func (z nat) expNNMontgomery(x, y, m nat) nat { } // bytes writes the value of z into buf using big-endian encoding. -// len(buf) must be >= len(z)*_S. The value of z is encoded in the -// slice buf[i:]. The number i of unused bytes at the beginning of -// buf is returned as result. +// The value of z is encoded in the slice buf[i:]. If the value of z +// cannot be represented in buf, bytes panics. The number i of unused +// bytes at the beginning of buf is returned as result. func (z nat) bytes(buf []byte) (i int) { i = len(buf) for _, d := range z { for j := 0; j < _S; j++ { i-- - buf[i] = byte(d) + if i >= 0 { + buf[i] = byte(d) + } else if byte(d) != 0 { + panic("math/big: buffer too small to fit value") + } d >>= 8 } } + if i < 0 { + i = 0 + } for i < len(buf) && buf[i] == 0 { i++ } diff --git a/libgo/go/math/big/sqrt.go b/libgo/go/math/big/sqrt.go index 53403aa41d7..0d50164557c 100644 --- a/libgo/go/math/big/sqrt.go +++ b/libgo/go/math/big/sqrt.go @@ -4,17 +4,29 @@ package big -import "math" - -var ( - three = NewFloat(3.0) +import ( + "math" + "sync" ) +var threeOnce struct { + sync.Once + v *Float +} + +func three() *Float { + threeOnce.Do(func() { + threeOnce.v = NewFloat(3.0) + }) + return threeOnce.v +} + // Sqrt sets z to the rounded square root of x, and returns it. // // If z's precision is 0, it is changed to x's precision before the // operation. Rounding is performed according to z's precision and -// rounding mode. +// rounding mode, but z's accuracy is not computed. Specifically, the +// result of z.Acc() is undefined. // // The function panics if z < 0. The value of z is undefined in that // case. @@ -61,61 +73,14 @@ func (z *Float) Sqrt(x *Float) *Float { } // 0.25 <= z < 2.0 - // Solving x² - z = 0 directly requires a Quo call, but it's - // faster for small precisions. - // - // Solving 1/x² - z = 0 avoids the Quo call and is much faster for - // high precisions. - // - // 128bit precision is an empirically chosen threshold. - if z.prec <= 128 { - z.sqrtDirect(z) - } else { - z.sqrtInverse(z) - } + // Solving 1/x² - z = 0 avoids Quo calls and is faster, especially + // for high precisions. + z.sqrtInverse(z) // re-attach halved exponent return z.SetMantExp(z, b/2) } -// Compute √x (up to prec 128) by solving -// t² - x = 0 -// for t, starting with a 53 bits precision guess from math.Sqrt and -// then using at most two iterations of Newton's method. -func (z *Float) sqrtDirect(x *Float) { - // let - // f(t) = t² - x - // then - // g(t) = f(t)/f'(t) = ½(t² - x)/t - // and the next guess is given by - // t2 = t - g(t) = ½(t² + x)/t - u := new(Float) - ng := func(t *Float) *Float { - u.prec = t.prec - u.Mul(t, t) // u = t² - u.Add(u, x) // = t² + x - u.exp-- // = ½(t² + x) - return t.Quo(u, t) // = ½(t² + x)/t - } - - xf, _ := x.Float64() - sq := NewFloat(math.Sqrt(xf)) - - switch { - case z.prec > 128: - panic("sqrtDirect: only for z.prec <= 128") - case z.prec > 64: - sq.prec *= 2 - sq = ng(sq) - fallthrough - default: - sq.prec *= 2 - sq = ng(sq) - } - - z.Set(sq) -} - // Compute √x (to z.prec precision) by solving // 1/t² - x = 0 // for t (using Newton's method), and then inverting. @@ -128,6 +93,7 @@ func (z *Float) sqrtInverse(x *Float) { // t2 = t - g(t) = ½t(3 - xt²) u := newFloat(z.prec) v := newFloat(z.prec) + three := three() ng := func(t *Float) *Float { u.prec = t.prec v.prec = t.prec @@ -137,7 +103,6 @@ func (z *Float) sqrtInverse(x *Float) { u.Mul(t, v) // u = t(3 - xt²) u.exp-- // = ½t(3 - xt²) return t.Set(u) - } xf, _ := x.Float64() diff --git a/libgo/go/math/bits/bits_test.go b/libgo/go/math/bits/bits_test.go index c0f43093d9b..23b4539fcd6 100644 --- a/libgo/go/math/bits/bits_test.go +++ b/libgo/go/math/bits/bits_test.go @@ -806,6 +806,130 @@ func TestAddSubUint64(t *testing.T) { } } +func TestAdd64OverflowPanic(t *testing.T) { + // Test that 64-bit overflow panics fire correctly. + // These are designed to improve coverage of compiler intrinsics. + tests := []func(uint64, uint64) uint64{ + func(a, b uint64) uint64 { + x, c := Add64(a, b, 0) + if c > 0 { + panic("overflow") + } + return x + }, + func(a, b uint64) uint64 { + x, c := Add64(a, b, 0) + if c != 0 { + panic("overflow") + } + return x + }, + func(a, b uint64) uint64 { + x, c := Add64(a, b, 0) + if c == 1 { + panic("overflow") + } + return x + }, + func(a, b uint64) uint64 { + x, c := Add64(a, b, 0) + if c != 1 { + return x + } + panic("overflow") + }, + func(a, b uint64) uint64 { + x, c := Add64(a, b, 0) + if c == 0 { + return x + } + panic("overflow") + }, + } + for _, test := range tests { + shouldPanic := func(f func()) { + defer func() { + if err := recover(); err == nil { + t.Fatalf("expected panic") + } + }() + f() + } + + // overflow + shouldPanic(func() { test(_M64, 1) }) + shouldPanic(func() { test(1, _M64) }) + shouldPanic(func() { test(_M64, _M64) }) + + // no overflow + test(_M64, 0) + test(0, 0) + test(1, 1) + } +} + +func TestSub64OverflowPanic(t *testing.T) { + // Test that 64-bit overflow panics fire correctly. + // These are designed to improve coverage of compiler intrinsics. + tests := []func(uint64, uint64) uint64{ + func(a, b uint64) uint64 { + x, c := Sub64(a, b, 0) + if c > 0 { + panic("overflow") + } + return x + }, + func(a, b uint64) uint64 { + x, c := Sub64(a, b, 0) + if c != 0 { + panic("overflow") + } + return x + }, + func(a, b uint64) uint64 { + x, c := Sub64(a, b, 0) + if c == 1 { + panic("overflow") + } + return x + }, + func(a, b uint64) uint64 { + x, c := Sub64(a, b, 0) + if c != 1 { + return x + } + panic("overflow") + }, + func(a, b uint64) uint64 { + x, c := Sub64(a, b, 0) + if c == 0 { + return x + } + panic("overflow") + }, + } + for _, test := range tests { + shouldPanic := func(f func()) { + defer func() { + if err := recover(); err == nil { + t.Fatalf("expected panic") + } + }() + f() + } + + // overflow + shouldPanic(func() { test(0, 1) }) + shouldPanic(func() { test(1, _M64) }) + shouldPanic(func() { test(_M64-1, _M64) }) + + // no overflow + test(_M64, 0) + test(0, 0) + test(1, 1) + } +} + func TestMulDiv(t *testing.T) { testMul := func(msg string, f func(x, y uint) (hi, lo uint), x, y, hi, lo uint) { hi1, lo1 := f(x, y) diff --git a/libgo/go/math/cmplx/abs.go b/libgo/go/math/cmplx/abs.go index f3cd1073ed2..2f89d1bcfc7 100644 --- a/libgo/go/math/cmplx/abs.go +++ b/libgo/go/math/cmplx/abs.go @@ -3,7 +3,8 @@ // license that can be found in the LICENSE file. // Package cmplx provides basic constants and mathematical functions for -// complex numbers. +// complex numbers. Special case handling conforms to the C99 standard +// Annex G IEC 60559-compatible complex arithmetic. package cmplx import "math" diff --git a/libgo/go/math/cmplx/asin.go b/libgo/go/math/cmplx/asin.go index 062f324ce2c..30d019e9d47 100644 --- a/libgo/go/math/cmplx/asin.go +++ b/libgo/go/math/cmplx/asin.go @@ -49,8 +49,31 @@ import "math" // Asin returns the inverse sine of x. func Asin(x complex128) complex128 { - if imag(x) == 0 && math.Abs(real(x)) <= 1 { - return complex(math.Asin(real(x)), imag(x)) + switch re, im := real(x), imag(x); { + case im == 0 && math.Abs(re) <= 1: + return complex(math.Asin(re), im) + case re == 0 && math.Abs(im) <= 1: + return complex(re, math.Asinh(im)) + case math.IsNaN(im): + switch { + case re == 0: + return complex(re, math.NaN()) + case math.IsInf(re, 0): + return complex(math.NaN(), re) + default: + return NaN() + } + case math.IsInf(im, 0): + switch { + case math.IsNaN(re): + return x + case math.IsInf(re, 0): + return complex(math.Copysign(math.Pi/4, re), im) + default: + return complex(math.Copysign(0, re), im) + } + case math.IsInf(re, 0): + return complex(math.Copysign(math.Pi/2, re), math.Copysign(re, im)) } ct := complex(-imag(x), real(x)) // i * x xx := x * x @@ -62,8 +85,31 @@ func Asin(x complex128) complex128 { // Asinh returns the inverse hyperbolic sine of x. func Asinh(x complex128) complex128 { - if imag(x) == 0 && math.Abs(real(x)) <= 1 { - return complex(math.Asinh(real(x)), imag(x)) + switch re, im := real(x), imag(x); { + case im == 0 && math.Abs(re) <= 1: + return complex(math.Asinh(re), im) + case re == 0 && math.Abs(im) <= 1: + return complex(re, math.Asin(im)) + case math.IsInf(re, 0): + switch { + case math.IsInf(im, 0): + return complex(re, math.Copysign(math.Pi/4, im)) + case math.IsNaN(im): + return x + default: + return complex(re, math.Copysign(0.0, im)) + } + case math.IsNaN(re): + switch { + case im == 0: + return x + case math.IsInf(im, 0): + return complex(im, re) + default: + return NaN() + } + case math.IsInf(im, 0): + return complex(math.Copysign(im, re), math.Copysign(math.Pi/2, im)) } xx := x * x x1 := complex(1+real(xx), imag(xx)) // 1 + x*x @@ -91,6 +137,9 @@ func Acos(x complex128) complex128 { // Acosh returns the inverse hyperbolic cosine of x. func Acosh(x complex128) complex128 { + if x == 0 { + return complex(0, math.Copysign(math.Pi/2, imag(x))) + } w := Acos(x) if imag(w) <= 0 { return complex(-imag(w), real(w)) // i * w @@ -133,6 +182,19 @@ func Acosh(x complex128) complex128 { // Atan returns the inverse tangent of x. func Atan(x complex128) complex128 { + switch re, im := real(x), imag(x); { + case im == 0: + return complex(math.Atan(re), im) + case re == 0 && math.Abs(im) <= 1: + return complex(re, math.Atanh(im)) + case math.IsInf(im, 0) || math.IsInf(re, 0): + if math.IsNaN(re) { + return complex(math.NaN(), math.Copysign(0, im)) + } + return complex(math.Copysign(math.Pi/2, re), math.Copysign(0, im)) + case math.IsNaN(re) || math.IsNaN(im): + return NaN() + } x2 := real(x) * real(x) a := 1 - x2 - imag(x)*imag(x) if a == 0 { diff --git a/libgo/go/math/cmplx/cmath_test.go b/libgo/go/math/cmplx/cmath_test.go index 57ba76a7671..3011e8327d5 100644 --- a/libgo/go/math/cmplx/cmath_test.go +++ b/libgo/go/math/cmplx/cmath_test.go @@ -291,48 +291,219 @@ var tanh = []complex128{ (-1.0000000491604982429364892e+00 - 2.901873195374433112227349e-08i), } -// special cases +// huge values along the real axis for testing reducePi in Tan +var hugeIn = []complex128{ + 1 << 28, + 1 << 29, + 1 << 30, + 1 << 35, + -1 << 120, + 1 << 240, + 1 << 300, + -1 << 480, + 1234567891234567 << 180, + -1234567891234567 << 300, +} + +// Results for tanHuge[i] calculated with https://github.com/robpike/ivy +// using 4096 bits of working precision. +var tanHuge = []complex128{ + 5.95641897939639421, + -0.34551069233430392, + -0.78469661331920043, + 0.84276385870875983, + 0.40806638884180424, + -0.37603456702698076, + 4.60901287677810962, + 3.39135965054779932, + -6.76813854009065030, + -0.76417695016604922, +} + +// special cases conform to C99 standard appendix G.6 Complex arithmetic +var inf, nan = math.Inf(1), math.NaN() + var vcAbsSC = []complex128{ NaN(), } var absSC = []float64{ math.NaN(), } -var vcAcosSC = []complex128{ - NaN(), -} -var acosSC = []complex128{ - NaN(), -} -var vcAcoshSC = []complex128{ - NaN(), -} -var acoshSC = []complex128{ - NaN(), -} -var vcAsinSC = []complex128{ - NaN(), -} -var asinSC = []complex128{ - NaN(), -} -var vcAsinhSC = []complex128{ - NaN(), -} -var asinhSC = []complex128{ - NaN(), -} -var vcAtanSC = []complex128{ - NaN(), -} -var atanSC = []complex128{ - NaN(), -} -var vcAtanhSC = []complex128{ - NaN(), -} -var atanhSC = []complex128{ - NaN(), +var acosSC = []struct { + in, + want complex128 +}{ + // G.6.1.1 + {complex(zero, zero), + complex(math.Pi/2, -zero)}, + {complex(-zero, zero), + complex(math.Pi/2, -zero)}, + {complex(zero, nan), + complex(math.Pi/2, nan)}, + {complex(-zero, nan), + complex(math.Pi/2, nan)}, + {complex(1.0, inf), + complex(math.Pi/2, -inf)}, + {complex(1.0, nan), + NaN()}, + {complex(-inf, 1.0), + complex(math.Pi, -inf)}, + {complex(inf, 1.0), + complex(0.0, -inf)}, + {complex(-inf, inf), + complex(3*math.Pi/4, -inf)}, + {complex(inf, inf), + complex(math.Pi/4, -inf)}, + {complex(inf, nan), + complex(nan, -inf)}, // imaginary sign unspecified + {complex(-inf, nan), + complex(nan, inf)}, // imaginary sign unspecified + {complex(nan, 1.0), + NaN()}, + {complex(nan, inf), + complex(nan, -inf)}, + {NaN(), + NaN()}, +} +var acoshSC = []struct { + in, + want complex128 +}{ + // G.6.2.1 + {complex(zero, zero), + complex(zero, math.Pi/2)}, + {complex(-zero, zero), + complex(zero, math.Pi/2)}, + {complex(1.0, inf), + complex(inf, math.Pi/2)}, + {complex(1.0, nan), + NaN()}, + {complex(-inf, 1.0), + complex(inf, math.Pi)}, + {complex(inf, 1.0), + complex(inf, zero)}, + {complex(-inf, inf), + complex(inf, 3*math.Pi/4)}, + {complex(inf, inf), + complex(inf, math.Pi/4)}, + {complex(inf, nan), + complex(inf, nan)}, + {complex(-inf, nan), + complex(inf, nan)}, + {complex(nan, 1.0), + NaN()}, + {complex(nan, inf), + complex(inf, nan)}, + {NaN(), + NaN()}, +} +var asinSC = []struct { + in, + want complex128 +}{ + // Derived from Asin(z) = -i * Asinh(i * z), G.6 #7 + {complex(zero, zero), + complex(zero, zero)}, + {complex(1.0, inf), + complex(0, inf)}, + {complex(1.0, nan), + NaN()}, + {complex(inf, 1), + complex(math.Pi/2, inf)}, + {complex(inf, inf), + complex(math.Pi/4, inf)}, + {complex(inf, nan), + complex(nan, inf)}, // imaginary sign unspecified + {complex(nan, zero), + NaN()}, + {complex(nan, 1), + NaN()}, + {complex(nan, inf), + complex(nan, inf)}, + {NaN(), + NaN()}, +} +var asinhSC = []struct { + in, + want complex128 +}{ + // G.6.2.2 + {complex(zero, zero), + complex(zero, zero)}, + {complex(1.0, inf), + complex(inf, math.Pi/2)}, + {complex(1.0, nan), + NaN()}, + {complex(inf, 1.0), + complex(inf, zero)}, + {complex(inf, inf), + complex(inf, math.Pi/4)}, + {complex(inf, nan), + complex(inf, nan)}, + {complex(nan, zero), + complex(nan, zero)}, + {complex(nan, 1.0), + NaN()}, + {complex(nan, inf), + complex(inf, nan)}, // sign of real part unspecified + {NaN(), + NaN()}, +} +var atanSC = []struct { + in, + want complex128 +}{ + // Derived from Atan(z) = -i * Atanh(i * z), G.6 #7 + {complex(0, zero), + complex(0, zero)}, + {complex(0, nan), + NaN()}, + {complex(1.0, zero), + complex(math.Pi/4, zero)}, + {complex(1.0, inf), + complex(math.Pi/2, zero)}, + {complex(1.0, nan), + NaN()}, + {complex(inf, 1), + complex(math.Pi/2, zero)}, + {complex(inf, inf), + complex(math.Pi/2, zero)}, + {complex(inf, nan), + complex(math.Pi/2, zero)}, + {complex(nan, 1), + NaN()}, + {complex(nan, inf), + complex(nan, zero)}, + {NaN(), + NaN()}, +} +var atanhSC = []struct { + in, + want complex128 +}{ + // G.6.2.3 + {complex(zero, zero), + complex(zero, zero)}, + {complex(zero, nan), + complex(zero, nan)}, + {complex(1.0, zero), + complex(inf, zero)}, + {complex(1.0, inf), + complex(0, math.Pi/2)}, + {complex(1.0, nan), + NaN()}, + {complex(inf, 1.0), + complex(zero, math.Pi/2)}, + {complex(inf, inf), + complex(zero, math.Pi/2)}, + {complex(inf, nan), + complex(0, nan)}, + {complex(nan, 1.0), + NaN()}, + {complex(nan, inf), + complex(zero, math.Pi/2)}, // sign of real part not specified. + {NaN(), + NaN()}, } var vcConjSC = []complex128{ NaN(), @@ -340,23 +511,105 @@ var vcConjSC = []complex128{ var conjSC = []complex128{ NaN(), } -var vcCosSC = []complex128{ - NaN(), -} -var cosSC = []complex128{ - NaN(), -} -var vcCoshSC = []complex128{ - NaN(), -} -var coshSC = []complex128{ - NaN(), -} -var vcExpSC = []complex128{ - NaN(), -} -var expSC = []complex128{ - NaN(), +var cosSC = []struct { + in, + want complex128 +}{ + // Derived from Cos(z) = Cosh(i * z), G.6 #7 + {complex(zero, zero), + complex(1.0, -zero)}, + {complex(zero, inf), + complex(inf, -zero)}, + {complex(zero, nan), + complex(nan, zero)}, // imaginary sign unspecified + {complex(1.0, inf), + complex(inf, -inf)}, + {complex(1.0, nan), + NaN()}, + {complex(inf, zero), + complex(nan, -zero)}, + {complex(inf, 1.0), + NaN()}, + {complex(inf, inf), + complex(inf, nan)}, // real sign unspecified + {complex(inf, nan), + NaN()}, + {complex(nan, zero), + complex(nan, -zero)}, // imaginary sign unspecified + {complex(nan, 1.0), + NaN()}, + {complex(nan, inf), + complex(inf, nan)}, + {NaN(), + NaN()}, +} +var coshSC = []struct { + in, + want complex128 +}{ + // G.6.2.4 + {complex(zero, zero), + complex(1.0, zero)}, + {complex(zero, inf), + complex(nan, zero)}, // imaginary sign unspecified + {complex(zero, nan), + complex(nan, zero)}, // imaginary sign unspecified + {complex(1.0, inf), + NaN()}, + {complex(1.0, nan), + NaN()}, + {complex(inf, zero), + complex(inf, zero)}, + {complex(inf, 1.0), + complex(inf*math.Cos(1.0), inf*math.Sin(1.0))}, // +inf cis(y) + {complex(inf, inf), + complex(inf, nan)}, // real sign unspecified + {complex(inf, nan), + complex(inf, nan)}, + {complex(nan, zero), + complex(nan, zero)}, // imaginary sign unspecified + {complex(nan, 1.0), + NaN()}, + {complex(nan, inf), + NaN()}, + {NaN(), + NaN()}, +} +var expSC = []struct { + in, + want complex128 +}{ + // G.6.3.1 + {complex(zero, zero), + complex(1.0, zero)}, + {complex(-zero, zero), + complex(1.0, zero)}, + {complex(1.0, inf), + NaN()}, + {complex(1.0, nan), + NaN()}, + {complex(inf, zero), + complex(inf, zero)}, + {complex(-inf, 1.0), + complex(math.Copysign(0.0, math.Cos(1.0)), math.Copysign(0.0, math.Sin(1.0)))}, // +0 cis(y) + {complex(inf, 1.0), + complex(inf*math.Cos(1.0), inf*math.Sin(1.0))}, // +inf cis(y) + {complex(-inf, inf), + complex(zero, zero)}, // real and imaginary sign unspecified + {complex(inf, inf), + complex(inf, nan)}, // real sign unspecified + {complex(-inf, nan), + complex(zero, zero)}, // real and imaginary sign unspecified + {complex(inf, nan), + complex(inf, nan)}, // real sign unspecified + {complex(nan, zero), + complex(nan, zero)}, + {complex(nan, 1.0), + NaN()}, + {complex(nan, inf), + NaN()}, + {NaN(), + NaN()}, } var vcIsNaNSC = []complex128{ complex(math.Inf(-1), math.Inf(-1)), @@ -380,17 +633,70 @@ var isNaNSC = []bool{ false, true, } -var vcLogSC = []complex128{ - NaN(), -} -var logSC = []complex128{ - NaN(), -} -var vcLog10SC = []complex128{ - NaN(), -} -var log10SC = []complex128{ - NaN(), + +var logSC = []struct { + in, + want complex128 +}{ + // G.6.3.2 + {complex(zero, zero), + complex(-inf, zero)}, + {complex(-zero, zero), + complex(-inf, math.Pi)}, + {complex(1.0, inf), + complex(inf, math.Pi/2)}, + {complex(1.0, nan), + NaN()}, + {complex(-inf, 1.0), + complex(inf, math.Pi)}, + {complex(inf, 1.0), + complex(inf, 0.0)}, + {complex(-inf, inf), + complex(inf, 3*math.Pi/4)}, + {complex(inf, inf), + complex(inf, math.Pi/4)}, + {complex(-inf, nan), + complex(inf, nan)}, + {complex(inf, nan), + complex(inf, nan)}, + {complex(nan, 1.0), + NaN()}, + {complex(nan, inf), + complex(inf, nan)}, + {NaN(), + NaN()}, +} +var log10SC = []struct { + in, + want complex128 +}{ + // derived from Log special cases via Log10(x) = math.Log10E*Log(x) + {complex(zero, zero), + complex(-inf, zero)}, + {complex(-zero, zero), + complex(-inf, float64(math.Log10E)*float64(math.Pi))}, + {complex(1.0, inf), + complex(inf, float64(math.Log10E)*float64(math.Pi/2))}, + {complex(1.0, nan), + NaN()}, + {complex(-inf, 1.0), + complex(inf, float64(math.Log10E)*float64(math.Pi))}, + {complex(inf, 1.0), + complex(inf, 0.0)}, + {complex(-inf, inf), + complex(inf, float64(math.Log10E)*float64(3*math.Pi/4))}, + {complex(inf, inf), + complex(inf, float64(math.Log10E)*float64(math.Pi/4))}, + {complex(-inf, nan), + complex(inf, nan)}, + {complex(inf, nan), + complex(inf, nan)}, + {complex(nan, 1.0), + NaN()}, + {complex(nan, inf), + complex(inf, nan)}, + {NaN(), + NaN()}, } var vcPolarSC = []complex128{ NaN(), @@ -406,35 +712,153 @@ var powSC = []complex128{ NaN(), NaN(), } -var vcSinSC = []complex128{ - NaN(), -} -var sinSC = []complex128{ - NaN(), -} -var vcSinhSC = []complex128{ - NaN(), -} -var sinhSC = []complex128{ - NaN(), -} -var vcSqrtSC = []complex128{ - NaN(), -} -var sqrtSC = []complex128{ - NaN(), -} -var vcTanSC = []complex128{ - NaN(), -} -var tanSC = []complex128{ - NaN(), +var sinSC = []struct { + in, + want complex128 +}{ + // Derived from Sin(z) = -i * Sinh(i * z), G.6 #7 + {complex(zero, zero), + complex(zero, zero)}, + {complex(zero, inf), + complex(zero, inf)}, + {complex(zero, nan), + complex(zero, nan)}, + {complex(1.0, inf), + complex(inf, inf)}, + {complex(1.0, nan), + NaN()}, + {complex(inf, zero), + complex(nan, zero)}, + {complex(inf, 1.0), + NaN()}, + {complex(inf, inf), + complex(nan, inf)}, + {complex(inf, nan), + NaN()}, + {complex(nan, zero), + complex(nan, zero)}, + {complex(nan, 1.0), + NaN()}, + {complex(nan, inf), + complex(nan, inf)}, + {NaN(), + NaN()}, } -var vcTanhSC = []complex128{ - NaN(), + +var sinhSC = []struct { + in, + want complex128 +}{ + // G.6.2.5 + {complex(zero, zero), + complex(zero, zero)}, + {complex(zero, inf), + complex(zero, nan)}, // real sign unspecified + {complex(zero, nan), + complex(zero, nan)}, // real sign unspecified + {complex(1.0, inf), + NaN()}, + {complex(1.0, nan), + NaN()}, + {complex(inf, zero), + complex(inf, zero)}, + {complex(inf, 1.0), + complex(inf*math.Cos(1.0), inf*math.Sin(1.0))}, // +inf cis(y) + {complex(inf, inf), + complex(inf, nan)}, // real sign unspecified + {complex(inf, nan), + complex(inf, nan)}, // real sign unspecified + {complex(nan, zero), + complex(nan, zero)}, + {complex(nan, 1.0), + NaN()}, + {complex(nan, inf), + NaN()}, + {NaN(), + NaN()}, } -var tanhSC = []complex128{ - NaN(), + +var sqrtSC = []struct { + in, + want complex128 +}{ + // G.6.4.2 + {complex(zero, zero), + complex(zero, zero)}, + {complex(-zero, zero), + complex(zero, zero)}, + {complex(1.0, inf), + complex(inf, inf)}, + {complex(nan, inf), + complex(inf, inf)}, + {complex(1.0, nan), + NaN()}, + {complex(-inf, 1.0), + complex(zero, inf)}, + {complex(inf, 1.0), + complex(inf, zero)}, + {complex(-inf, nan), + complex(nan, inf)}, // imaginary sign unspecified + {complex(inf, nan), + complex(inf, nan)}, + {complex(nan, 1.0), + NaN()}, + {NaN(), + NaN()}, +} +var tanSC = []struct { + in, + want complex128 +}{ + // Derived from Tan(z) = -i * Tanh(i * z), G.6 #7 + {complex(zero, zero), + complex(zero, zero)}, + {complex(zero, nan), + complex(zero, nan)}, + {complex(1.0, inf), + complex(zero, 1.0)}, + {complex(1.0, nan), + NaN()}, + {complex(inf, 1.0), + NaN()}, + {complex(inf, inf), + complex(zero, 1.0)}, + {complex(inf, nan), + NaN()}, + {complex(nan, zero), + NaN()}, + {complex(nan, 1.0), + NaN()}, + {complex(nan, inf), + complex(zero, 1.0)}, + {NaN(), + NaN()}, +} +var tanhSC = []struct { + in, + want complex128 +}{ + // G.6.2.6 + {complex(zero, zero), + complex(zero, zero)}, + {complex(1.0, inf), + NaN()}, + {complex(1.0, nan), + NaN()}, + {complex(inf, 1.0), + complex(1.0, math.Copysign(0.0, math.Sin(2*1.0)))}, // 1 + i 0 sin(2y) + {complex(inf, inf), + complex(1.0, zero)}, // imaginary sign unspecified + {complex(inf, nan), + complex(1.0, zero)}, // imaginary sign unspecified + {complex(nan, zero), + complex(nan, zero)}, + {complex(nan, 1.0), + NaN()}, + {complex(nan, inf), + NaN()}, + {NaN(), + NaN()}, } // branch cut continuity checks @@ -496,13 +920,25 @@ func cTolerance(a, b complex128, e float64) bool { func cSoclose(a, b complex128, e float64) bool { return cTolerance(a, b, e) } func cVeryclose(a, b complex128) bool { return cTolerance(a, b, 4e-16) } func cAlike(a, b complex128) bool { - switch { - case IsNaN(a) && IsNaN(b): - return true - case a == b: - return math.Signbit(real(a)) == math.Signbit(real(b)) && math.Signbit(imag(a)) == math.Signbit(imag(b)) - } - return false + var realAlike, imagAlike bool + if isExact(real(b)) { + realAlike = alike(real(a), real(b)) + } else { + // Allow non-exact special cases to have errors in ULP. + realAlike = veryclose(real(a), real(b)) + } + if isExact(imag(b)) { + imagAlike = alike(imag(a), imag(b)) + } else { + // Allow non-exact special cases to have errors in ULP. + imagAlike = veryclose(imag(a), imag(b)) + } + return realAlike && imagAlike +} +func isExact(x float64) bool { + // Special cases that should match exactly. Other cases are multiples + // of Pi that may not be last bit identical on all platforms. + return math.IsNaN(x) || math.IsInf(x, 0) || x == 0 || x == 1 || x == -1 } func TestAbs(t *testing.T) { @@ -523,9 +959,17 @@ func TestAcos(t *testing.T) { t.Errorf("Acos(%g) = %g, want %g", vc[i], f, acos[i]) } } - for i := 0; i < len(vcAcosSC); i++ { - if f := Acos(vcAcosSC[i]); !cAlike(acosSC[i], f) { - t.Errorf("Acos(%g) = %g, want %g", vcAcosSC[i], f, acosSC[i]) + for _, v := range acosSC { + if f := Acos(v.in); !cAlike(v.want, f) { + t.Errorf("Acos(%g) = %g, want %g", v.in, f, v.want) + } + if math.IsNaN(imag(v.in)) || math.IsNaN(imag(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Acos(Conj(z)) == Conj(Acos(z)) + if f := Acos(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) { + t.Errorf("Acos(%g) = %g, want %g", Conj(v.in), f, Conj(v.want)) } } for _, pt := range branchPoints { @@ -540,10 +984,19 @@ func TestAcosh(t *testing.T) { t.Errorf("Acosh(%g) = %g, want %g", vc[i], f, acosh[i]) } } - for i := 0; i < len(vcAcoshSC); i++ { - if f := Acosh(vcAcoshSC[i]); !cAlike(acoshSC[i], f) { - t.Errorf("Acosh(%g) = %g, want %g", vcAcoshSC[i], f, acoshSC[i]) + for _, v := range acoshSC { + if f := Acosh(v.in); !cAlike(v.want, f) { + t.Errorf("Acosh(%g) = %g, want %g", v.in, f, v.want) + } + if math.IsNaN(imag(v.in)) || math.IsNaN(imag(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue } + // Acosh(Conj(z)) == Conj(Acosh(z)) + if f := Acosh(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) { + t.Errorf("Acosh(%g) = %g, want %g", Conj(v.in), f, Conj(v.want)) + } + } for _, pt := range branchPoints { if f0, f1 := Acosh(pt[0]), Acosh(pt[1]); !cVeryclose(f0, f1) { @@ -557,9 +1010,25 @@ func TestAsin(t *testing.T) { t.Errorf("Asin(%g) = %g, want %g", vc[i], f, asin[i]) } } - for i := 0; i < len(vcAsinSC); i++ { - if f := Asin(vcAsinSC[i]); !cAlike(asinSC[i], f) { - t.Errorf("Asin(%g) = %g, want %g", vcAsinSC[i], f, asinSC[i]) + for _, v := range asinSC { + if f := Asin(v.in); !cAlike(v.want, f) { + t.Errorf("Asin(%g) = %g, want %g", v.in, f, v.want) + } + if math.IsNaN(imag(v.in)) || math.IsNaN(imag(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Asin(Conj(z)) == Asin(Sinh(z)) + if f := Asin(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) { + t.Errorf("Asin(%g) = %g, want %g", Conj(v.in), f, Conj(v.want)) + } + if math.IsNaN(real(v.in)) || math.IsNaN(real(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Asin(-z) == -Asin(z) + if f := Asin(-v.in); !cAlike(-v.want, f) && !cAlike(v.in, -v.in) { + t.Errorf("Asin(%g) = %g, want %g", -v.in, f, -v.want) } } for _, pt := range branchPoints { @@ -574,9 +1043,25 @@ func TestAsinh(t *testing.T) { t.Errorf("Asinh(%g) = %g, want %g", vc[i], f, asinh[i]) } } - for i := 0; i < len(vcAsinhSC); i++ { - if f := Asinh(vcAsinhSC[i]); !cAlike(asinhSC[i], f) { - t.Errorf("Asinh(%g) = %g, want %g", vcAsinhSC[i], f, asinhSC[i]) + for _, v := range asinhSC { + if f := Asinh(v.in); !cAlike(v.want, f) { + t.Errorf("Asinh(%g) = %g, want %g", v.in, f, v.want) + } + if math.IsNaN(imag(v.in)) || math.IsNaN(imag(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Asinh(Conj(z)) == Asinh(Sinh(z)) + if f := Asinh(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) { + t.Errorf("Asinh(%g) = %g, want %g", Conj(v.in), f, Conj(v.want)) + } + if math.IsNaN(real(v.in)) || math.IsNaN(real(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Asinh(-z) == -Asinh(z) + if f := Asinh(-v.in); !cAlike(-v.want, f) && !cAlike(v.in, -v.in) { + t.Errorf("Asinh(%g) = %g, want %g", -v.in, f, -v.want) } } for _, pt := range branchPoints { @@ -591,9 +1076,25 @@ func TestAtan(t *testing.T) { t.Errorf("Atan(%g) = %g, want %g", vc[i], f, atan[i]) } } - for i := 0; i < len(vcAtanSC); i++ { - if f := Atan(vcAtanSC[i]); !cAlike(atanSC[i], f) { - t.Errorf("Atan(%g) = %g, want %g", vcAtanSC[i], f, atanSC[i]) + for _, v := range atanSC { + if f := Atan(v.in); !cAlike(v.want, f) { + t.Errorf("Atan(%g) = %g, want %g", v.in, f, v.want) + } + if math.IsNaN(imag(v.in)) || math.IsNaN(imag(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Atan(Conj(z)) == Conj(Atan(z)) + if f := Atan(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) { + t.Errorf("Atan(%g) = %g, want %g", Conj(v.in), f, Conj(v.want)) + } + if math.IsNaN(real(v.in)) || math.IsNaN(real(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Atan(-z) == -Atan(z) + if f := Atan(-v.in); !cAlike(-v.want, f) && !cAlike(v.in, -v.in) { + t.Errorf("Atan(%g) = %g, want %g", -v.in, f, -v.want) } } for _, pt := range branchPoints { @@ -608,9 +1109,25 @@ func TestAtanh(t *testing.T) { t.Errorf("Atanh(%g) = %g, want %g", vc[i], f, atanh[i]) } } - for i := 0; i < len(vcAtanhSC); i++ { - if f := Atanh(vcAtanhSC[i]); !cAlike(atanhSC[i], f) { - t.Errorf("Atanh(%g) = %g, want %g", vcAtanhSC[i], f, atanhSC[i]) + for _, v := range atanhSC { + if f := Atanh(v.in); !cAlike(v.want, f) { + t.Errorf("Atanh(%g) = %g, want %g", v.in, f, v.want) + } + if math.IsNaN(imag(v.in)) || math.IsNaN(imag(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Atanh(Conj(z)) == Conj(Atanh(z)) + if f := Atanh(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) { + t.Errorf("Atanh(%g) = %g, want %g", Conj(v.in), f, Conj(v.want)) + } + if math.IsNaN(real(v.in)) || math.IsNaN(real(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Atanh(-z) == -Atanh(z) + if f := Atanh(-v.in); !cAlike(-v.want, f) && !cAlike(v.in, -v.in) { + t.Errorf("Atanh(%g) = %g, want %g", -v.in, f, -v.want) } } for _, pt := range branchPoints { @@ -637,9 +1154,25 @@ func TestCos(t *testing.T) { t.Errorf("Cos(%g) = %g, want %g", vc[i], f, cos[i]) } } - for i := 0; i < len(vcCosSC); i++ { - if f := Cos(vcCosSC[i]); !cAlike(cosSC[i], f) { - t.Errorf("Cos(%g) = %g, want %g", vcCosSC[i], f, cosSC[i]) + for _, v := range cosSC { + if f := Cos(v.in); !cAlike(v.want, f) { + t.Errorf("Cos(%g) = %g, want %g", v.in, f, v.want) + } + if math.IsNaN(imag(v.in)) || math.IsNaN(imag(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Cos(Conj(z)) == Cos(Cosh(z)) + if f := Cos(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) { + t.Errorf("Cos(%g) = %g, want %g", Conj(v.in), f, Conj(v.want)) + } + if math.IsNaN(real(v.in)) || math.IsNaN(real(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Cos(-z) == Cos(z) + if f := Cos(-v.in); !cAlike(v.want, f) && !cAlike(v.in, -v.in) { + t.Errorf("Cos(%g) = %g, want %g", -v.in, f, v.want) } } } @@ -649,9 +1182,25 @@ func TestCosh(t *testing.T) { t.Errorf("Cosh(%g) = %g, want %g", vc[i], f, cosh[i]) } } - for i := 0; i < len(vcCoshSC); i++ { - if f := Cosh(vcCoshSC[i]); !cAlike(coshSC[i], f) { - t.Errorf("Cosh(%g) = %g, want %g", vcCoshSC[i], f, coshSC[i]) + for _, v := range coshSC { + if f := Cosh(v.in); !cAlike(v.want, f) { + t.Errorf("Cosh(%g) = %g, want %g", v.in, f, v.want) + } + if math.IsNaN(imag(v.in)) || math.IsNaN(imag(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Cosh(Conj(z)) == Conj(Cosh(z)) + if f := Cosh(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) { + t.Errorf("Cosh(%g) = %g, want %g", Conj(v.in), f, Conj(v.want)) + } + if math.IsNaN(real(v.in)) || math.IsNaN(real(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Cosh(-z) == Cosh(z) + if f := Cosh(-v.in); !cAlike(v.want, f) && !cAlike(v.in, -v.in) { + t.Errorf("Cosh(%g) = %g, want %g", -v.in, f, v.want) } } } @@ -661,9 +1210,17 @@ func TestExp(t *testing.T) { t.Errorf("Exp(%g) = %g, want %g", vc[i], f, exp[i]) } } - for i := 0; i < len(vcExpSC); i++ { - if f := Exp(vcExpSC[i]); !cAlike(expSC[i], f) { - t.Errorf("Exp(%g) = %g, want %g", vcExpSC[i], f, expSC[i]) + for _, v := range expSC { + if f := Exp(v.in); !cAlike(v.want, f) { + t.Errorf("Exp(%g) = %g, want %g", v.in, f, v.want) + } + if math.IsNaN(imag(v.in)) || math.IsNaN(imag(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Exp(Conj(z)) == Exp(Cosh(z)) + if f := Exp(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) { + t.Errorf("Exp(%g) = %g, want %g", Conj(v.in), f, Conj(v.want)) } } } @@ -680,9 +1237,17 @@ func TestLog(t *testing.T) { t.Errorf("Log(%g) = %g, want %g", vc[i], f, log[i]) } } - for i := 0; i < len(vcLogSC); i++ { - if f := Log(vcLogSC[i]); !cAlike(logSC[i], f) { - t.Errorf("Log(%g) = %g, want %g", vcLogSC[i], f, logSC[i]) + for _, v := range logSC { + if f := Log(v.in); !cAlike(v.want, f) { + t.Errorf("Log(%g) = %g, want %g", v.in, f, v.want) + } + if math.IsNaN(imag(v.in)) || math.IsNaN(imag(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Log(Conj(z)) == Conj(Log(z)) + if f := Log(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) { + t.Errorf("Log(%g) = %g, want %g", Conj(v.in), f, Conj(v.want)) } } for _, pt := range branchPoints { @@ -697,9 +1262,17 @@ func TestLog10(t *testing.T) { t.Errorf("Log10(%g) = %g, want %g", vc[i], f, log10[i]) } } - for i := 0; i < len(vcLog10SC); i++ { - if f := Log10(vcLog10SC[i]); !cAlike(log10SC[i], f) { - t.Errorf("Log10(%g) = %g, want %g", vcLog10SC[i], f, log10SC[i]) + for _, v := range log10SC { + if f := Log10(v.in); !cAlike(v.want, f) { + t.Errorf("Log10(%g) = %g, want %g", v.in, f, v.want) + } + if math.IsNaN(imag(v.in)) || math.IsNaN(imag(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Log10(Conj(z)) == Conj(Log10(z)) + if f := Log10(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) { + t.Errorf("Log10(%g) = %g, want %g", Conj(v.in), f, Conj(v.want)) } } } @@ -764,9 +1337,25 @@ func TestSin(t *testing.T) { t.Errorf("Sin(%g) = %g, want %g", vc[i], f, sin[i]) } } - for i := 0; i < len(vcSinSC); i++ { - if f := Sin(vcSinSC[i]); !cAlike(sinSC[i], f) { - t.Errorf("Sin(%g) = %g, want %g", vcSinSC[i], f, sinSC[i]) + for _, v := range sinSC { + if f := Sin(v.in); !cAlike(v.want, f) { + t.Errorf("Sin(%g) = %g, want %g", v.in, f, v.want) + } + if math.IsNaN(imag(v.in)) || math.IsNaN(imag(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Sin(Conj(z)) == Conj(Sin(z)) + if f := Sin(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) { + t.Errorf("Sinh(%g) = %g, want %g", Conj(v.in), f, Conj(v.want)) + } + if math.IsNaN(real(v.in)) || math.IsNaN(real(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Sin(-z) == -Sin(z) + if f := Sin(-v.in); !cAlike(-v.want, f) && !cAlike(v.in, -v.in) { + t.Errorf("Sinh(%g) = %g, want %g", -v.in, f, -v.want) } } } @@ -776,9 +1365,25 @@ func TestSinh(t *testing.T) { t.Errorf("Sinh(%g) = %g, want %g", vc[i], f, sinh[i]) } } - for i := 0; i < len(vcSinhSC); i++ { - if f := Sinh(vcSinhSC[i]); !cAlike(sinhSC[i], f) { - t.Errorf("Sinh(%g) = %g, want %g", vcSinhSC[i], f, sinhSC[i]) + for _, v := range sinhSC { + if f := Sinh(v.in); !cAlike(v.want, f) { + t.Errorf("Sinh(%g) = %g, want %g", v.in, f, v.want) + } + if math.IsNaN(imag(v.in)) || math.IsNaN(imag(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Sinh(Conj(z)) == Conj(Sinh(z)) + if f := Sinh(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) { + t.Errorf("Sinh(%g) = %g, want %g", Conj(v.in), f, Conj(v.want)) + } + if math.IsNaN(real(v.in)) || math.IsNaN(real(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Sinh(-z) == -Sinh(z) + if f := Sinh(-v.in); !cAlike(-v.want, f) && !cAlike(v.in, -v.in) { + t.Errorf("Sinh(%g) = %g, want %g", -v.in, f, -v.want) } } } @@ -788,9 +1393,17 @@ func TestSqrt(t *testing.T) { t.Errorf("Sqrt(%g) = %g, want %g", vc[i], f, sqrt[i]) } } - for i := 0; i < len(vcSqrtSC); i++ { - if f := Sqrt(vcSqrtSC[i]); !cAlike(sqrtSC[i], f) { - t.Errorf("Sqrt(%g) = %g, want %g", vcSqrtSC[i], f, sqrtSC[i]) + for _, v := range sqrtSC { + if f := Sqrt(v.in); !cAlike(v.want, f) { + t.Errorf("Sqrt(%g) = %g, want %g", v.in, f, v.want) + } + if math.IsNaN(imag(v.in)) || math.IsNaN(imag(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Sqrt(Conj(z)) == Conj(Sqrt(z)) + if f := Sqrt(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) { + t.Errorf("Sqrt(%g) = %g, want %g", Conj(v.in), f, Conj(v.want)) } } for _, pt := range branchPoints { @@ -805,9 +1418,25 @@ func TestTan(t *testing.T) { t.Errorf("Tan(%g) = %g, want %g", vc[i], f, tan[i]) } } - for i := 0; i < len(vcTanSC); i++ { - if f := Tan(vcTanSC[i]); !cAlike(tanSC[i], f) { - t.Errorf("Tan(%g) = %g, want %g", vcTanSC[i], f, tanSC[i]) + for _, v := range tanSC { + if f := Tan(v.in); !cAlike(v.want, f) { + t.Errorf("Tan(%g) = %g, want %g", v.in, f, v.want) + } + if math.IsNaN(imag(v.in)) || math.IsNaN(imag(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Tan(Conj(z)) == Conj(Tan(z)) + if f := Tan(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) { + t.Errorf("Tan(%g) = %g, want %g", Conj(v.in), f, Conj(v.want)) + } + if math.IsNaN(real(v.in)) || math.IsNaN(real(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Tan(-z) == -Tan(z) + if f := Tan(-v.in); !cAlike(-v.want, f) && !cAlike(v.in, -v.in) { + t.Errorf("Tan(%g) = %g, want %g", -v.in, f, -v.want) } } } @@ -817,9 +1446,25 @@ func TestTanh(t *testing.T) { t.Errorf("Tanh(%g) = %g, want %g", vc[i], f, tanh[i]) } } - for i := 0; i < len(vcTanhSC); i++ { - if f := Tanh(vcTanhSC[i]); !cAlike(tanhSC[i], f) { - t.Errorf("Tanh(%g) = %g, want %g", vcTanhSC[i], f, tanhSC[i]) + for _, v := range tanhSC { + if f := Tanh(v.in); !cAlike(v.want, f) { + t.Errorf("Tanh(%g) = %g, want %g", v.in, f, v.want) + } + if math.IsNaN(imag(v.in)) || math.IsNaN(imag(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Tanh(Conj(z)) == Conj(Tanh(z)) + if f := Tanh(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) { + t.Errorf("Tanh(%g) = %g, want %g", Conj(v.in), f, Conj(v.want)) + } + if math.IsNaN(real(v.in)) || math.IsNaN(real(v.want)) { + // Negating NaN is undefined with regard to the sign bit produced. + continue + } + // Tanh(-z) == -Tanh(z) + if f := Tanh(-v.in); !cAlike(-v.want, f) && !cAlike(v.in, -v.in) { + t.Errorf("Tanh(%g) = %g, want %g", -v.in, f, -v.want) } } } diff --git a/libgo/go/math/cmplx/exp.go b/libgo/go/math/cmplx/exp.go index 485ed2c78d9..d5d0a5d470c 100644 --- a/libgo/go/math/cmplx/exp.go +++ b/libgo/go/math/cmplx/exp.go @@ -49,6 +49,23 @@ import "math" // Exp returns e**x, the base-e exponential of x. func Exp(x complex128) complex128 { + switch re, im := real(x), imag(x); { + case math.IsInf(re, 0): + switch { + case re > 0 && im == 0: + return x + case math.IsInf(im, 0) || math.IsNaN(im): + if re < 0 { + return complex(0, math.Copysign(0, im)) + } else { + return complex(math.Inf(1.0), math.NaN()) + } + } + case math.IsNaN(re): + if im == 0 { + return complex(math.NaN(), im) + } + } r := math.Exp(real(x)) s, c := math.Sincos(imag(x)) return complex(r*c, r*s) diff --git a/libgo/go/math/cmplx/huge_test.go b/libgo/go/math/cmplx/huge_test.go new file mode 100644 index 00000000000..f8e60c265f6 --- /dev/null +++ b/libgo/go/math/cmplx/huge_test.go @@ -0,0 +1,22 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Disabled for s390x because it uses assembly routines that are not +// accurate for huge arguments. + +// +build !s390x + +package cmplx + +import ( + "testing" +) + +func TestTanHuge(t *testing.T) { + for i, x := range hugeIn { + if f := Tan(x); !cSoclose(tanHuge[i], f, 3e-15) { + t.Errorf("Tan(%g) = %g, want %g", x, f, tanHuge[i]) + } + } +} diff --git a/libgo/go/math/cmplx/log.go b/libgo/go/math/cmplx/log.go index 881a064d8b8..fd39c76cde1 100644 --- a/libgo/go/math/cmplx/log.go +++ b/libgo/go/math/cmplx/log.go @@ -60,5 +60,6 @@ func Log(x complex128) complex128 { // Log10 returns the decimal logarithm of x. func Log10(x complex128) complex128 { - return math.Log10E * Log(x) + z := Log(x) + return complex(math.Log10E*real(z), math.Log10E*imag(z)) } diff --git a/libgo/go/math/cmplx/sin.go b/libgo/go/math/cmplx/sin.go index 2c57536edfc..febac0e0bbd 100644 --- a/libgo/go/math/cmplx/sin.go +++ b/libgo/go/math/cmplx/sin.go @@ -51,6 +51,19 @@ import "math" // Sin returns the sine of x. func Sin(x complex128) complex128 { + switch re, im := real(x), imag(x); { + case im == 0 && (math.IsInf(re, 0) || math.IsNaN(re)): + return complex(math.NaN(), im) + case math.IsInf(im, 0): + switch { + case re == 0: + return x + case math.IsInf(re, 0) || math.IsNaN(re): + return complex(math.NaN(), im) + } + case re == 0 && math.IsNaN(im): + return x + } s, c := math.Sincos(real(x)) sh, ch := sinhcosh(imag(x)) return complex(s*ch, c*sh) @@ -71,6 +84,19 @@ func Sin(x complex128) complex128 { // Sinh returns the hyperbolic sine of x. func Sinh(x complex128) complex128 { + switch re, im := real(x), imag(x); { + case re == 0 && (math.IsInf(im, 0) || math.IsNaN(im)): + return complex(re, math.NaN()) + case math.IsInf(re, 0): + switch { + case im == 0: + return complex(re, im) + case math.IsInf(im, 0) || math.IsNaN(im): + return complex(re, math.NaN()) + } + case im == 0 && math.IsNaN(re): + return complex(math.NaN(), im) + } s, c := math.Sincos(imag(x)) sh, ch := sinhcosh(real(x)) return complex(c*sh, s*ch) @@ -96,6 +122,19 @@ func Sinh(x complex128) complex128 { // Cos returns the cosine of x. func Cos(x complex128) complex128 { + switch re, im := real(x), imag(x); { + case im == 0 && (math.IsInf(re, 0) || math.IsNaN(re)): + return complex(math.NaN(), -im*math.Copysign(0, re)) + case math.IsInf(im, 0): + switch { + case re == 0: + return complex(math.Inf(1), -re*math.Copysign(0, im)) + case math.IsInf(re, 0) || math.IsNaN(re): + return complex(math.Inf(1), math.NaN()) + } + case re == 0 && math.IsNaN(im): + return complex(math.NaN(), 0) + } s, c := math.Sincos(real(x)) sh, ch := sinhcosh(imag(x)) return complex(c*ch, -s*sh) @@ -115,6 +154,19 @@ func Cos(x complex128) complex128 { // Cosh returns the hyperbolic cosine of x. func Cosh(x complex128) complex128 { + switch re, im := real(x), imag(x); { + case re == 0 && (math.IsInf(im, 0) || math.IsNaN(im)): + return complex(math.NaN(), re*math.Copysign(0, im)) + case math.IsInf(re, 0): + switch { + case im == 0: + return complex(math.Inf(1), im*math.Copysign(0, re)) + case math.IsInf(im, 0) || math.IsNaN(im): + return complex(math.Inf(1), math.NaN()) + } + case im == 0 && math.IsNaN(re): + return complex(math.NaN(), im) + } s, c := math.Sincos(imag(x)) sh, ch := sinhcosh(real(x)) return complex(c*ch, s*sh) diff --git a/libgo/go/math/cmplx/sqrt.go b/libgo/go/math/cmplx/sqrt.go index 0fbdcdedd36..eddce2fdfbd 100644 --- a/libgo/go/math/cmplx/sqrt.go +++ b/libgo/go/math/cmplx/sqrt.go @@ -40,7 +40,7 @@ import "math" // 1/2 // Im w = [ (r - x)/2 ] . // -// Cancelation error in r-x or r+x is avoided by using the +// Cancellation error in r-x or r+x is avoided by using the // identity 2 Re w Im w = y. // // Note that -w is also a square root of z. The root chosen @@ -65,6 +65,8 @@ func Sqrt(x complex128) complex128 { return complex(0, math.Copysign(math.Sqrt(-real(x)), imag(x))) } return complex(math.Sqrt(real(x)), imag(x)) + } else if math.IsInf(imag(x), 0) { + return complex(math.Inf(1.0), imag(x)) } if real(x) == 0 { if imag(x) < 0 { diff --git a/libgo/go/math/cmplx/tan.go b/libgo/go/math/cmplx/tan.go index 0243ea0417f..67a1133a6f4 100644 --- a/libgo/go/math/cmplx/tan.go +++ b/libgo/go/math/cmplx/tan.go @@ -4,7 +4,10 @@ package cmplx -import "math" +import ( + "math" + "math/bits" +) // The original C code, the long comment, and the constants // below are from http://netlib.sandia.gov/cephes/c9x-complex/clog.c. @@ -42,7 +45,7 @@ import "math" // cos 2x + cosh 2y // // On the real axis the denominator is zero at odd multiples -// of PI/2. The denominator is evaluated by its Taylor +// of PI/2. The denominator is evaluated by its Taylor // series near these points. // // ctan(z) = -i ctanh(iz). @@ -57,6 +60,16 @@ import "math" // Tan returns the tangent of x. func Tan(x complex128) complex128 { + switch re, im := real(x), imag(x); { + case math.IsInf(im, 0): + switch { + case math.IsInf(re, 0) || math.IsNaN(re): + return complex(math.Copysign(0, re), math.Copysign(1, im)) + } + return complex(math.Copysign(0, math.Sin(2*re)), math.Copysign(1, im)) + case re == 0 && math.IsNaN(im): + return x + } d := math.Cos(2*real(x)) + math.Cosh(2*imag(x)) if math.Abs(d) < 0.25 { d = tanSeries(x) @@ -81,6 +94,16 @@ func Tan(x complex128) complex128 { // Tanh returns the hyperbolic tangent of x. func Tanh(x complex128) complex128 { + switch re, im := real(x), imag(x); { + case math.IsInf(re, 0): + switch { + case math.IsInf(im, 0) || math.IsNaN(im): + return complex(math.Copysign(1, re), math.Copysign(0, im)) + } + return complex(math.Copysign(1, re), math.Copysign(0, math.Sin(2*im))) + case im == 0 && math.IsNaN(re): + return x + } d := math.Cosh(2*real(x)) + math.Cos(2*imag(x)) if d == 0 { return Inf() @@ -88,22 +111,110 @@ func Tanh(x complex128) complex128 { return complex(math.Sinh(2*real(x))/d, math.Sin(2*imag(x))/d) } -// Program to subtract nearest integer multiple of PI +// reducePi reduces the input argument x to the range (-Pi/2, Pi/2]. +// x must be greater than or equal to 0. For small arguments it +// uses Cody-Waite reduction in 3 float64 parts based on: +// "Elementary Function Evaluation: Algorithms and Implementation" +// Jean-Michel Muller, 1997. +// For very large arguments it uses Payne-Hanek range reduction based on: +// "ARGUMENT REDUCTION FOR HUGE ARGUMENTS: Good to the Last Bit" +// K. C. Ng et al, March 24, 1992. func reducePi(x float64) float64 { + // reduceThreshold is the maximum value of x where the reduction using + // Cody-Waite reduction still gives accurate results. This threshold + // is set by t*PIn being representable as a float64 without error + // where t is given by t = floor(x * (1 / Pi)) and PIn are the leading partial + // terms of Pi. Since the leading terms, PI1 and PI2 below, have 30 and 32 + // trailing zero bits respectively, t should have less than 30 significant bits. + // t < 1<<30 -> floor(x*(1/Pi)+0.5) < 1<<30 -> x < (1<<30-1) * Pi - 0.5 + // So, conservatively we can take x < 1<<30. + const reduceThreshold float64 = 1 << 30 + if math.Abs(x) < reduceThreshold { + // Use Cody-Waite reduction in three parts. + const ( + // PI1, PI2 and PI3 comprise an extended precision value of PI + // such that PI ~= PI1 + PI2 + PI3. The parts are chosen so + // that PI1 and PI2 have an approximately equal number of trailing + // zero bits. This ensures that t*PI1 and t*PI2 are exact for + // large integer values of t. The full precision PI3 ensures the + // approximation of PI is accurate to 102 bits to handle cancellation + // during subtraction. + PI1 = 3.141592502593994 // 0x400921fb40000000 + PI2 = 1.5099578831723193e-07 // 0x3e84442d00000000 + PI3 = 1.0780605716316238e-14 // 0x3d08469898cc5170 + ) + t := x / math.Pi + t += 0.5 + t = float64(int64(t)) // int64(t) = the multiple + return ((x - t*PI1) - t*PI2) - t*PI3 + } + // Must apply Payne-Hanek range reduction const ( - // extended precision value of PI: - DP1 = 3.14159265160560607910e0 // ?? 0x400921fb54000000 - DP2 = 1.98418714791870343106e-9 // ?? 0x3e210b4610000000 - DP3 = 1.14423774522196636802e-17 // ?? 0x3c6a62633145c06e + mask = 0x7FF + shift = 64 - 11 - 1 + bias = 1023 + fracMask = 1<= 0 { - t += 0.5 - } else { - t -= 0.5 + // Extract out the integer and exponent such that, + // x = ix * 2 ** exp. + ix := math.Float64bits(x) + exp := int(ix>>shift&mask) - bias - shift + ix &= fracMask + ix |= 1 << shift + + // mPi is the binary digits of 1/Pi as a uint64 array, + // that is, 1/Pi = Sum mPi[i]*2^(-64*i). + // 19 64-bit digits give 1216 bits of precision + // to handle the largest possible float64 exponent. + var mPi = [...]uint64{ + 0x0000000000000000, + 0x517cc1b727220a94, + 0xfe13abe8fa9a6ee0, + 0x6db14acc9e21c820, + 0xff28b1d5ef5de2b0, + 0xdb92371d2126e970, + 0x0324977504e8c90e, + 0x7f0ef58e5894d39f, + 0x74411afa975da242, + 0x74ce38135a2fbf20, + 0x9cc8eb1cc1a99cfa, + 0x4e422fc5defc941d, + 0x8ffc4bffef02cc07, + 0xf79788c5ad05368f, + 0xb69b3f6793e584db, + 0xa7a31fb34f2ff516, + 0xba93dd63f5f2f8bd, + 0x9e839cfbc5294975, + 0x35fdafd88fc6ae84, + 0x2b0198237e3db5d5, + } + // Use the exponent to extract the 3 appropriate uint64 digits from mPi, + // B ~ (z0, z1, z2), such that the product leading digit has the exponent -64. + // Note, exp >= 50 since x >= reduceThreshold and exp < 971 for maximum float64. + digit, bitshift := uint(exp+64)/64, uint(exp+64)%64 + z0 := (mPi[digit] << bitshift) | (mPi[digit+1] >> (64 - bitshift)) + z1 := (mPi[digit+1] << bitshift) | (mPi[digit+2] >> (64 - bitshift)) + z2 := (mPi[digit+2] << bitshift) | (mPi[digit+3] >> (64 - bitshift)) + // Multiply mantissa by the digits and extract the upper two digits (hi, lo). + z2hi, _ := bits.Mul64(z2, ix) + z1hi, z1lo := bits.Mul64(z1, ix) + z0lo := z0 * ix + lo, c := bits.Add64(z1lo, z2hi, 0) + hi, _ := bits.Add64(z0lo, z1hi, c) + // Find the magnitude of the fraction. + lz := uint(bits.LeadingZeros64(hi)) + e := uint64(bias - (lz + 1)) + // Clear implicit mantissa bit and shift into place. + hi = (hi << (lz + 1)) | (lo >> (64 - (lz + 1))) + hi >>= 64 - shift + // Include the exponent and convert to a float. + hi |= e << shift + x = math.Float64frombits(hi) + // map to (-Pi/2, Pi/2] + if x > 0.5 { + x-- } - t = float64(int64(t)) // int64(t) = the multiple - return ((x - t*DP1) - t*DP2) - t*DP3 + return math.Pi * x } // Taylor series expansion for cosh(2y) - cos(2x) diff --git a/libgo/go/math/example_test.go b/libgo/go/math/example_test.go index 50c74269792..9fc19679679 100644 --- a/libgo/go/math/example_test.go +++ b/libgo/go/math/example_test.go @@ -219,3 +219,22 @@ func ExampleTrunc() { // 3.00 // -1.00 } + +func ExampleCbrt() { + fmt.Printf("%.2f\n", math.Cbrt(8)) + fmt.Printf("%.2f\n", math.Cbrt(27)) + // Output: + // 2.00 + // 3.00 +} + +func ExampleModf() { + int, frac := math.Modf(3.14) + fmt.Printf("%.2f, %.2f\n", int, frac) + + int, frac = math.Modf(-2.71) + fmt.Printf("%.2f, %.2f\n", int, frac) + // Output: + // 3.00, 0.14 + // -2.00, -0.71 +} diff --git a/libgo/go/math/huge_test.go b/libgo/go/math/huge_test.go index 0b45dbf5b12..9448edc3394 100644 --- a/libgo/go/math/huge_test.go +++ b/libgo/go/math/huge_test.go @@ -16,6 +16,10 @@ import ( // Inputs to test trig_reduce var trigHuge = []float64{ + 1 << 28, + 1 << 29, + 1 << 30, + 1 << 35, 1 << 120, 1 << 240, 1 << 480, @@ -29,6 +33,10 @@ var trigHuge = []float64{ // 102 decimal digits (1 << 120, 1 << 240, 1 << 480, 1234567891234567 << 180) // were confirmed via https://keisan.casio.com/ var cosHuge = []float64{ + -0.16556897949057876, + -0.94517382606089662, + 0.78670712294118812, + -0.76466301249635305, -0.92587902285483787, 0.93601042593353793, -0.28282777640193788, @@ -38,6 +46,10 @@ var cosHuge = []float64{ } var sinHuge = []float64{ + -0.98619821183697566, + 0.32656766301856334, + -0.61732641504604217, + -0.64443035102329113, 0.37782010936075202, -0.35197227524865778, 0.95917070894368716, @@ -47,6 +59,10 @@ var sinHuge = []float64{ } var tanHuge = []float64{ + 5.95641897939639421, + -0.34551069233430392, + -0.78469661331920043, + 0.84276385870875983, -0.40806638884180424, -0.37603456702698076, -3.39135965054779932, diff --git a/libgo/go/math/trig_reduce.go b/libgo/go/math/trig_reduce.go index 6f8eaba9b91..5cdf4fa0137 100644 --- a/libgo/go/math/trig_reduce.go +++ b/libgo/go/math/trig_reduce.go @@ -8,13 +8,19 @@ import ( "math/bits" ) -// reduceThreshold is the maximum value where the reduction using Pi/4 -// in 3 float64 parts still gives accurate results. Above this -// threshold Payne-Hanek range reduction must be used. -const reduceThreshold = (1 << 52) / (4 / Pi) +// reduceThreshold is the maximum value of x where the reduction using Pi/4 +// in 3 float64 parts still gives accurate results. This threshold +// is set by y*C being representable as a float64 without error +// where y is given by y = floor(x * (4 / Pi)) and C is the leading partial +// terms of 4/Pi. Since the leading terms (PI4A and PI4B in sin.go) have 30 +// and 32 trailing zero bits, y should have less than 30 significant bits. +// y < 1<<30 -> floor(x*4/Pi) < 1<<30 -> x < (1<<30 - 1) * Pi/4 +// So, conservatively we can take x < 1<<29. +// Above this threshold Payne-Hanek range reduction must be used. +const reduceThreshold = 1 << 29 // trigReduce implements Payne-Hanek range reduction by Pi/4 -// for x > 0. It returns the integer part mod 8 (j) and +// for x > 0. It returns the integer part mod 8 (j) and // the fractional part (z) of x / (Pi/4). // The implementation is based on: // "ARGUMENT REDUCTION FOR HUGE ARGUMENTS: Good to the Last Bit" diff --git a/libgo/go/mime/type.go b/libgo/go/mime/type.go index aa05077e221..6d2b89e4059 100644 --- a/libgo/go/mime/type.go +++ b/libgo/go/mime/type.go @@ -7,6 +7,7 @@ package mime import ( "fmt" + "sort" "strings" "sync" ) @@ -49,7 +50,7 @@ func setMimeTypes(lowerExt, mixExt map[string]string) { panic(err) } var exts []string - if ei, ok := extensions.Load(k); ok { + if ei, ok := extensions.Load(justType); ok { exts = ei.([]string) } extensions.Store(justType, append(exts, k)) @@ -64,6 +65,7 @@ var builtinTypesLower = map[string]string{ ".jpeg": "image/jpeg", ".jpg": "image/jpeg", ".js": "text/javascript; charset=utf-8", + ".json": "application/json", ".mjs": "text/javascript; charset=utf-8", ".pdf": "application/pdf", ".png": "image/png", @@ -151,7 +153,9 @@ func ExtensionsByType(typ string) ([]string, error) { if !ok { return nil, nil } - return append([]string{}, s.([]string)...), nil + ret := append([]string(nil), s.([]string)...) + sort.Strings(ret) + return ret, nil } // AddExtensionType sets the MIME type associated with diff --git a/libgo/go/mime/type_test.go b/libgo/go/mime/type_test.go index de5c700faaf..5e4d25cc872 100644 --- a/libgo/go/mime/type_test.go +++ b/libgo/go/mime/type_test.go @@ -189,3 +189,30 @@ func BenchmarkExtensionsByType(b *testing.B) { }) } } + +func TestExtensionsByType2(t *testing.T) { + cleanup := setMimeInit(func() { + clearMimeTypes() + // Initialize built-in types like in type.go before osInitMime. + setMimeTypes(builtinTypesLower, builtinTypesLower) + }) + defer cleanup() + + tests := []struct { + typ string + want []string + }{ + {typ: "image/jpeg", want: []string{".jpeg", ".jpg"}}, + } + + for _, tt := range tests { + got, err := ExtensionsByType(tt.typ) + if err != nil { + t.Errorf("ExtensionsByType(%q): %v", tt.typ, err) + continue + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ExtensionsByType(%q) = %q; want %q", tt.typ, got, tt.want) + } + } +} diff --git a/libgo/go/net/dial.go b/libgo/go/net/dial.go index d8be1c222d0..13a312a91ae 100644 --- a/libgo/go/net/dial.go +++ b/libgo/go/net/dial.go @@ -7,7 +7,6 @@ package net import ( "context" "internal/nettrace" - "internal/poll" "syscall" "time" ) @@ -141,7 +140,7 @@ func partialDeadline(now, deadline time.Time, addrsRemaining int) (time.Time, er } timeRemaining := deadline.Sub(now) if timeRemaining <= 0 { - return time.Time{}, poll.ErrTimeout + return time.Time{}, errTimeout } // Tentatively allocate equal time to each remaining address. timeout := timeRemaining / time.Duration(addrsRemaining) diff --git a/libgo/go/net/dial_test.go b/libgo/go/net/dial_test.go index 493cdfc6481..01582489de1 100644 --- a/libgo/go/net/dial_test.go +++ b/libgo/go/net/dial_test.go @@ -9,7 +9,6 @@ package net import ( "bufio" "context" - "internal/poll" "internal/testenv" "io" "os" @@ -441,6 +440,14 @@ func TestDialParallelSpuriousConnection(t *testing.T) { t.Skip("both IPv4 and IPv6 are required") } + var readDeadline time.Time + if td, ok := t.Deadline(); ok { + const arbitraryCleanupMargin = 1 * time.Second + readDeadline = td.Add(-arbitraryCleanupMargin) + } else { + readDeadline = time.Now().Add(5 * time.Second) + } + var wg sync.WaitGroup wg.Add(2) handler := func(dss *dualStackServer, ln Listener) { @@ -450,7 +457,7 @@ func TestDialParallelSpuriousConnection(t *testing.T) { t.Fatal(err) } // The client should close itself, without sending data. - c.SetReadDeadline(time.Now().Add(1 * time.Second)) + c.SetReadDeadline(readDeadline) var b [1]byte if _, err := c.Read(b[:]); err != io.EOF { t.Errorf("got %v; want %v", err, io.EOF) @@ -532,8 +539,8 @@ func TestDialerPartialDeadline(t *testing.T) { {now, noDeadline, 1, noDeadline, nil}, // Step the clock forward and cross the deadline. {now.Add(-1 * time.Millisecond), now, 1, now, nil}, - {now.Add(0 * time.Millisecond), now, 1, noDeadline, poll.ErrTimeout}, - {now.Add(1 * time.Millisecond), now, 1, noDeadline, poll.ErrTimeout}, + {now.Add(0 * time.Millisecond), now, 1, noDeadline, errTimeout}, + {now.Add(1 * time.Millisecond), now, 1, noDeadline, errTimeout}, } for i, tt := range testCases { deadline, err := partialDeadline(tt.now, tt.deadline, tt.addrs) @@ -983,7 +990,7 @@ func TestDialerControl(t *testing.T) { // except that it won't skip testing on non-mobile builders. func mustHaveExternalNetwork(t *testing.T) { t.Helper() - mobile := runtime.GOOS == "android" || runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") + mobile := runtime.GOOS == "android" || runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" if testenv.Builder() == "" || mobile { testenv.MustHaveExternalNetwork(t) } diff --git a/libgo/go/net/dnsclient_test.go b/libgo/go/net/dnsclient_test.go index 3ab2b836ef6..f3ed62db36a 100644 --- a/libgo/go/net/dnsclient_test.go +++ b/libgo/go/net/dnsclient_test.go @@ -42,7 +42,7 @@ func testUniformity(t *testing.T, size int, margin float64) { rand.Seed(1) data := make([]*SRV, size) for i := 0; i < size; i++ { - data[i] = &SRV{Target: string('a' + i), Weight: 1} + data[i] = &SRV{Target: string('a' + rune(i)), Weight: 1} } checkDistribution(t, data, margin) } diff --git a/libgo/go/net/dnsclient_unix.go b/libgo/go/net/dnsclient_unix.go index da6baf34b57..5f6c8706be8 100644 --- a/libgo/go/net/dnsclient_unix.go +++ b/libgo/go/net/dnsclient_unix.go @@ -40,10 +40,10 @@ var ( errInvalidDNSResponse = errors.New("invalid DNS response") errNoAnswerFromDNSServer = errors.New("no answer from DNS server") - // errServerTemporarlyMisbehaving is like errServerMisbehaving, except + // errServerTemporarilyMisbehaving is like errServerMisbehaving, except // that when it gets translated to a DNSError, the IsTemporary field // gets set to true. - errServerTemporarlyMisbehaving = errors.New("server misbehaving") + errServerTemporarilyMisbehaving = errors.New("server misbehaving") ) func newRequest(q dnsmessage.Question) (id uint16, udpReq, tcpReq []byte, err error) { @@ -206,7 +206,7 @@ func checkHeader(p *dnsmessage.Parser, h dnsmessage.Header) error { // the server is behaving incorrectly or // having temporary trouble. if h.RCode == dnsmessage.RCodeServerFailure { - return errServerTemporarlyMisbehaving + return errServerTemporarilyMisbehaving } return errServerMisbehaving } @@ -278,7 +278,7 @@ func (r *Resolver) tryOneName(ctx context.Context, cfg *dnsConfig, name string, Name: name, Server: server, } - if err == errServerTemporarlyMisbehaving { + if err == errServerTemporarilyMisbehaving { dnsErr.IsTemporary = true } if err == errNoSuchHost { diff --git a/libgo/go/net/dnsclient_unix_test.go b/libgo/go/net/dnsclient_unix_test.go index e8f81e82905..a89dcccbc58 100644 --- a/libgo/go/net/dnsclient_unix_test.go +++ b/libgo/go/net/dnsclient_unix_test.go @@ -10,7 +10,6 @@ import ( "context" "errors" "fmt" - "internal/poll" "io/ioutil" "os" "path" @@ -480,7 +479,7 @@ func TestGoLookupIPWithResolverConfig(t *testing.T) { break default: time.Sleep(10 * time.Millisecond) - return dnsmessage.Message{}, poll.ErrTimeout + return dnsmessage.Message{}, os.ErrDeadlineExceeded } r := dnsmessage.Message{ Header: dnsmessage.Header{ @@ -993,7 +992,7 @@ func TestRetryTimeout(t *testing.T) { if s == "192.0.2.1:53" { deadline0 = deadline time.Sleep(10 * time.Millisecond) - return dnsmessage.Message{}, poll.ErrTimeout + return dnsmessage.Message{}, os.ErrDeadlineExceeded } if deadline.Equal(deadline0) { @@ -1131,7 +1130,7 @@ func TestStrictErrorsLookupIP(t *testing.T) { } makeTimeout := func() error { return &DNSError{ - Err: poll.ErrTimeout.Error(), + Err: os.ErrDeadlineExceeded.Error(), Name: name, Server: server, IsTimeout: true, @@ -1247,7 +1246,7 @@ func TestStrictErrorsLookupIP(t *testing.T) { Questions: q.Questions, }, nil case resolveTimeout: - return dnsmessage.Message{}, poll.ErrTimeout + return dnsmessage.Message{}, os.ErrDeadlineExceeded default: t.Fatal("Impossible resolveWhich") } @@ -1372,7 +1371,7 @@ func TestStrictErrorsLookupTXT(t *testing.T) { switch q.Questions[0].Name.String() { case searchX: - return dnsmessage.Message{}, poll.ErrTimeout + return dnsmessage.Message{}, os.ErrDeadlineExceeded case searchY: return mockTXTResponse(q), nil default: @@ -1387,7 +1386,7 @@ func TestStrictErrorsLookupTXT(t *testing.T) { var wantRRs int if strict { wantErr = &DNSError{ - Err: poll.ErrTimeout.Error(), + Err: os.ErrDeadlineExceeded.Error(), Name: name, Server: server, IsTimeout: true, @@ -1415,7 +1414,7 @@ func TestDNSGoroutineRace(t *testing.T) { fake := fakeDNSServer{rh: func(n, s string, q dnsmessage.Message, t time.Time) (dnsmessage.Message, error) { time.Sleep(10 * time.Microsecond) - return dnsmessage.Message{}, poll.ErrTimeout + return dnsmessage.Message{}, os.ErrDeadlineExceeded }} r := Resolver{PreferGo: true, Dial: fake.DialContext} diff --git a/libgo/go/net/error_test.go b/libgo/go/net/error_test.go index 89dcc2e6e6e..8d4a7ffb3d0 100644 --- a/libgo/go/net/error_test.go +++ b/libgo/go/net/error_test.go @@ -91,7 +91,7 @@ second: return nil } switch err := nestedErr.(type) { - case *AddrError, addrinfoErrno, *DNSError, InvalidAddrError, *ParseError, *poll.TimeoutError, UnknownNetworkError: + case *AddrError, addrinfoErrno, *timeoutError, *DNSError, InvalidAddrError, *ParseError, *poll.DeadlineExceededError, UnknownNetworkError: return nil case *os.SyscallError: nestedErr = err.Err @@ -436,7 +436,7 @@ second: goto third } switch nestedErr { - case poll.ErrNetClosing, poll.ErrTimeout, poll.ErrNotPollable: + case poll.ErrNetClosing, errTimeout, poll.ErrNotPollable, os.ErrDeadlineExceeded: return nil } return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr) @@ -471,14 +471,14 @@ second: return nil } switch err := nestedErr.(type) { - case *AddrError, addrinfoErrno, *DNSError, InvalidAddrError, *ParseError, *poll.TimeoutError, UnknownNetworkError: + case *AddrError, addrinfoErrno, *timeoutError, *DNSError, InvalidAddrError, *ParseError, *poll.DeadlineExceededError, UnknownNetworkError: return nil case *os.SyscallError: nestedErr = err.Err goto third } switch nestedErr { - case errCanceled, poll.ErrNetClosing, errMissingAddress, poll.ErrTimeout, ErrWriteToConnected, io.ErrUnexpectedEOF: + case errCanceled, poll.ErrNetClosing, errMissingAddress, errTimeout, os.ErrDeadlineExceeded, ErrWriteToConnected, io.ErrUnexpectedEOF: return nil } return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr) @@ -627,7 +627,7 @@ second: goto third } switch nestedErr { - case poll.ErrNetClosing, poll.ErrTimeout, poll.ErrNotPollable: + case poll.ErrNetClosing, errTimeout, poll.ErrNotPollable, os.ErrDeadlineExceeded: return nil } return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr) diff --git a/libgo/go/net/fd_posix.go b/libgo/go/net/fd_posix.go new file mode 100644 index 00000000000..53abd152c7c --- /dev/null +++ b/libgo/go/net/fd_posix.go @@ -0,0 +1,100 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows + +package net + +import ( + "internal/poll" + "runtime" + "syscall" + "time" +) + +// Network file descriptor. +type netFD struct { + pfd poll.FD + + // immutable until Close + family int + sotype int + isConnected bool // handshake completed or use of association with peer + net string + laddr Addr + raddr Addr +} + +func (fd *netFD) setAddr(laddr, raddr Addr) { + fd.laddr = laddr + fd.raddr = raddr + runtime.SetFinalizer(fd, (*netFD).Close) +} + +func (fd *netFD) Close() error { + runtime.SetFinalizer(fd, nil) + return fd.pfd.Close() +} + +func (fd *netFD) shutdown(how int) error { + err := fd.pfd.Shutdown(how) + runtime.KeepAlive(fd) + return wrapSyscallError("shutdown", err) +} + +func (fd *netFD) closeRead() error { + return fd.shutdown(syscall.SHUT_RD) +} + +func (fd *netFD) closeWrite() error { + return fd.shutdown(syscall.SHUT_WR) +} + +func (fd *netFD) Read(p []byte) (n int, err error) { + n, err = fd.pfd.Read(p) + runtime.KeepAlive(fd) + return n, wrapSyscallError(readSyscallName, err) +} + +func (fd *netFD) readFrom(p []byte) (n int, sa syscall.Sockaddr, err error) { + n, sa, err = fd.pfd.ReadFrom(p) + runtime.KeepAlive(fd) + return n, sa, wrapSyscallError(readFromSyscallName, err) +} + +func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) { + n, oobn, flags, sa, err = fd.pfd.ReadMsg(p, oob) + runtime.KeepAlive(fd) + return n, oobn, flags, sa, wrapSyscallError(readMsgSyscallName, err) +} + +func (fd *netFD) Write(p []byte) (nn int, err error) { + nn, err = fd.pfd.Write(p) + runtime.KeepAlive(fd) + return nn, wrapSyscallError(writeSyscallName, err) +} + +func (fd *netFD) writeTo(p []byte, sa syscall.Sockaddr) (n int, err error) { + n, err = fd.pfd.WriteTo(p, sa) + runtime.KeepAlive(fd) + return n, wrapSyscallError(writeToSyscallName, err) +} + +func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) { + n, oobn, err = fd.pfd.WriteMsg(p, oob, sa) + runtime.KeepAlive(fd) + return n, oobn, wrapSyscallError(writeMsgSyscallName, err) +} + +func (fd *netFD) SetDeadline(t time.Time) error { + return fd.pfd.SetDeadline(t) +} + +func (fd *netFD) SetReadDeadline(t time.Time) error { + return fd.pfd.SetReadDeadline(t) +} + +func (fd *netFD) SetWriteDeadline(t time.Time) error { + return fd.pfd.SetWriteDeadline(t) +} diff --git a/libgo/go/net/fd_unix.go b/libgo/go/net/fd_unix.go index 117f5a994fe..ad79c067792 100644 --- a/libgo/go/net/fd_unix.go +++ b/libgo/go/net/fd_unix.go @@ -12,21 +12,16 @@ import ( "os" "runtime" "syscall" - "time" ) -// Network file descriptor. -type netFD struct { - pfd poll.FD - - // immutable until Close - family int - sotype int - isConnected bool // handshake completed or use of association with peer - net string - laddr Addr - raddr Addr -} +const ( + readSyscallName = "read" + readFromSyscallName = "recvfrom" + readMsgSyscallName = "recvmsg" + writeSyscallName = "write" + writeToSyscallName = "sendto" + writeMsgSyscallName = "sendmsg" +) func newFD(sysfd, family, sotype int, net string) (*netFD, error) { ret := &netFD{ @@ -46,12 +41,6 @@ func (fd *netFD) init() error { return fd.pfd.Init(fd.net, true) } -func (fd *netFD) setAddr(laddr, raddr Addr) { - fd.laddr = laddr - fd.raddr = raddr - runtime.SetFinalizer(fd, (*netFD).Close) -} - func (fd *netFD) name() string { var ls, rs string if fd.laddr != nil { @@ -179,61 +168,6 @@ func (fd *netFD) connect(ctx context.Context, la, ra syscall.Sockaddr) (rsa sysc } } -func (fd *netFD) Close() error { - runtime.SetFinalizer(fd, nil) - return fd.pfd.Close() -} - -func (fd *netFD) shutdown(how int) error { - err := fd.pfd.Shutdown(how) - runtime.KeepAlive(fd) - return wrapSyscallError("shutdown", err) -} - -func (fd *netFD) closeRead() error { - return fd.shutdown(syscall.SHUT_RD) -} - -func (fd *netFD) closeWrite() error { - return fd.shutdown(syscall.SHUT_WR) -} - -func (fd *netFD) Read(p []byte) (n int, err error) { - n, err = fd.pfd.Read(p) - runtime.KeepAlive(fd) - return n, wrapSyscallError("read", err) -} - -func (fd *netFD) readFrom(p []byte) (n int, sa syscall.Sockaddr, err error) { - n, sa, err = fd.pfd.ReadFrom(p) - runtime.KeepAlive(fd) - return n, sa, wrapSyscallError("recvfrom", err) -} - -func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) { - n, oobn, flags, sa, err = fd.pfd.ReadMsg(p, oob) - runtime.KeepAlive(fd) - return n, oobn, flags, sa, wrapSyscallError("recvmsg", err) -} - -func (fd *netFD) Write(p []byte) (nn int, err error) { - nn, err = fd.pfd.Write(p) - runtime.KeepAlive(fd) - return nn, wrapSyscallError("write", err) -} - -func (fd *netFD) writeTo(p []byte, sa syscall.Sockaddr) (n int, err error) { - n, err = fd.pfd.WriteTo(p, sa) - runtime.KeepAlive(fd) - return n, wrapSyscallError("sendto", err) -} - -func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) { - n, oobn, err = fd.pfd.WriteMsg(p, oob, sa) - runtime.KeepAlive(fd) - return n, oobn, wrapSyscallError("sendmsg", err) -} - func (fd *netFD) accept() (netfd *netFD, err error) { d, rsa, errcall, err := fd.pfd.Accept() if err != nil { @@ -267,15 +201,3 @@ func (fd *netFD) dup() (f *os.File, err error) { return os.NewFile(uintptr(ns), fd.name()), nil } - -func (fd *netFD) SetDeadline(t time.Time) error { - return fd.pfd.SetDeadline(t) -} - -func (fd *netFD) SetReadDeadline(t time.Time) error { - return fd.pfd.SetReadDeadline(t) -} - -func (fd *netFD) SetWriteDeadline(t time.Time) error { - return fd.pfd.SetWriteDeadline(t) -} diff --git a/libgo/go/net/fd_windows.go b/libgo/go/net/fd_windows.go index 3cc4c7a6a22..030b6a15fb5 100644 --- a/libgo/go/net/fd_windows.go +++ b/libgo/go/net/fd_windows.go @@ -10,10 +10,18 @@ import ( "os" "runtime" "syscall" - "time" "unsafe" ) +const ( + readSyscallName = "wsarecv" + readFromSyscallName = "wsarecvfrom" + readMsgSyscallName = "wsarecvmsg" + writeSyscallName = "wsasend" + writeToSyscallName = "wsasendto" + writeMsgSyscallName = "wsasendmsg" +) + // canUseConnectEx reports whether we can use the ConnectEx Windows API call // for the given network type. func canUseConnectEx(net string) bool { @@ -25,19 +33,6 @@ func canUseConnectEx(net string) bool { return false } -// Network file descriptor. -type netFD struct { - pfd poll.FD - - // immutable until Close - family int - sotype int - isConnected bool // handshake completed or use of association with peer - net string - laddr Addr - raddr Addr -} - func newFD(sysfd syscall.Handle, family, sotype int, net string) (*netFD, error) { ret := &netFD{ pfd: poll.FD{ @@ -60,12 +55,6 @@ func (fd *netFD) init() error { return err } -func (fd *netFD) setAddr(laddr, raddr Addr) { - fd.laddr = laddr - fd.raddr = raddr - runtime.SetFinalizer(fd, (*netFD).Close) -} - // Always returns nil for connected peer address result. func (fd *netFD) connect(ctx context.Context, la, ra syscall.Sockaddr) (syscall.Sockaddr, error) { // Do not need to call fd.writeLock here, @@ -129,43 +118,6 @@ func (fd *netFD) connect(ctx context.Context, la, ra syscall.Sockaddr) (syscall. return nil, os.NewSyscallError("setsockopt", syscall.Setsockopt(fd.pfd.Sysfd, syscall.SOL_SOCKET, syscall.SO_UPDATE_CONNECT_CONTEXT, (*byte)(unsafe.Pointer(&fd.pfd.Sysfd)), int32(unsafe.Sizeof(fd.pfd.Sysfd)))) } -func (fd *netFD) Close() error { - runtime.SetFinalizer(fd, nil) - return fd.pfd.Close() -} - -func (fd *netFD) shutdown(how int) error { - err := fd.pfd.Shutdown(how) - runtime.KeepAlive(fd) - return err -} - -func (fd *netFD) closeRead() error { - return fd.shutdown(syscall.SHUT_RD) -} - -func (fd *netFD) closeWrite() error { - return fd.shutdown(syscall.SHUT_WR) -} - -func (fd *netFD) Read(buf []byte) (int, error) { - n, err := fd.pfd.Read(buf) - runtime.KeepAlive(fd) - return n, wrapSyscallError("wsarecv", err) -} - -func (fd *netFD) readFrom(buf []byte) (int, syscall.Sockaddr, error) { - n, sa, err := fd.pfd.ReadFrom(buf) - runtime.KeepAlive(fd) - return n, sa, wrapSyscallError("wsarecvfrom", err) -} - -func (fd *netFD) Write(buf []byte) (int, error) { - n, err := fd.pfd.Write(buf) - runtime.KeepAlive(fd) - return n, wrapSyscallError("wsasend", err) -} - func (c *conn) writeBuffers(v *Buffers) (int64, error) { if !c.ok() { return 0, syscall.EINVAL @@ -183,12 +135,6 @@ func (fd *netFD) writeBuffers(buf *Buffers) (int64, error) { return n, wrapSyscallError("wsasend", err) } -func (fd *netFD) writeTo(buf []byte, sa syscall.Sockaddr) (int, error) { - n, err := fd.pfd.WriteTo(buf, sa) - runtime.KeepAlive(fd) - return n, wrapSyscallError("wsasendto", err) -} - func (fd *netFD) accept() (*netFD, error) { s, rawsa, rsan, errcall, err := fd.pfd.Accept(func() (syscall.Handle, error) { return sysSocket(fd.family, fd.sotype, 0) @@ -224,33 +170,9 @@ func (fd *netFD) accept() (*netFD, error) { return netfd, nil } -func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) { - n, oobn, flags, sa, err = fd.pfd.ReadMsg(p, oob) - runtime.KeepAlive(fd) - return n, oobn, flags, sa, wrapSyscallError("wsarecvmsg", err) -} - -func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) { - n, oobn, err = fd.pfd.WriteMsg(p, oob, sa) - runtime.KeepAlive(fd) - return n, oobn, wrapSyscallError("wsasendmsg", err) -} - // Unimplemented functions. func (fd *netFD) dup() (*os.File, error) { // TODO: Implement this return nil, syscall.EWINDOWS } - -func (fd *netFD) SetDeadline(t time.Time) error { - return fd.pfd.SetDeadline(t) -} - -func (fd *netFD) SetReadDeadline(t time.Time) error { - return fd.pfd.SetReadDeadline(t) -} - -func (fd *netFD) SetWriteDeadline(t time.Time) error { - return fd.pfd.SetWriteDeadline(t) -} diff --git a/libgo/go/net/http/cgi/child.go b/libgo/go/net/http/cgi/child.go index cb140f8f2f6..9474175f179 100644 --- a/libgo/go/net/http/cgi/child.go +++ b/libgo/go/net/http/cgi/child.go @@ -89,8 +89,6 @@ func RequestFromMap(params map[string]string) (*http.Request, error) { r.Header.Add(strings.ReplaceAll(k[5:], "_", "-"), v) } - // TODO: cookies. parsing them isn't exported, though. - uriStr := params["REQUEST_URI"] if uriStr == "" { // Fallback to SCRIPT_NAME, PATH_INFO and QUERY_STRING. diff --git a/libgo/go/net/http/cgi/host.go b/libgo/go/net/http/cgi/host.go index 58e9f7132a8..863f40638ab 100644 --- a/libgo/go/net/http/cgi/host.go +++ b/libgo/go/net/http/cgi/host.go @@ -21,6 +21,7 @@ import ( "log" "net" "net/http" + "net/textproto" "os" "os/exec" "path/filepath" @@ -28,20 +29,29 @@ import ( "runtime" "strconv" "strings" + + "golang.org/x/net/http/httpguts" ) var trailingPort = regexp.MustCompile(`:([0-9]+)$`) -var osDefaultInheritEnv = map[string][]string{ - "darwin": {"DYLD_LIBRARY_PATH"}, - "freebsd": {"LD_LIBRARY_PATH"}, - "hpux": {"LD_LIBRARY_PATH", "SHLIB_PATH"}, - "irix": {"LD_LIBRARY_PATH", "LD_LIBRARYN32_PATH", "LD_LIBRARY64_PATH"}, - "linux": {"LD_LIBRARY_PATH"}, - "openbsd": {"LD_LIBRARY_PATH"}, - "solaris": {"LD_LIBRARY_PATH", "LD_LIBRARY_PATH_32", "LD_LIBRARY_PATH_64"}, - "windows": {"SystemRoot", "COMSPEC", "PATHEXT", "WINDIR"}, -} +var osDefaultInheritEnv = func() []string { + switch runtime.GOOS { + case "darwin": + return []string{"DYLD_LIBRARY_PATH"} + case "linux", "freebsd", "openbsd": + return []string{"LD_LIBRARY_PATH"} + case "hpux": + return []string{"LD_LIBRARY_PATH", "SHLIB_PATH"} + case "irix": + return []string{"LD_LIBRARY_PATH", "LD_LIBRARYN32_PATH", "LD_LIBRARY64_PATH"} + case "solaris": + return []string{"LD_LIBRARY_PATH", "LD_LIBRARY_PATH_32", "LD_LIBRARY_PATH_64"} + case "windows": + return []string{"SystemRoot", "COMSPEC", "PATHEXT", "WINDIR"} + } + return nil +}() // Handler runs an executable in a subprocess with a CGI environment. type Handler struct { @@ -183,7 +193,7 @@ func (h *Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { } } - for _, e := range osDefaultInheritEnv[runtime.GOOS] { + for _, e := range osDefaultInheritEnv { if v := os.Getenv(e); v != "" { env = append(env, e+"="+v) } @@ -269,8 +279,11 @@ func (h *Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { continue } header, val := parts[0], parts[1] - header = strings.TrimSpace(header) - val = strings.TrimSpace(val) + if !httpguts.ValidHeaderFieldName(header) { + h.printf("cgi: invalid header name: %q", header) + continue + } + val = textproto.TrimString(val) switch { case header == "Status": if len(val) < 3 { diff --git a/libgo/go/net/http/client.go b/libgo/go/net/http/client.go index a496f1c0c75..3860d97d8f4 100644 --- a/libgo/go/net/http/client.go +++ b/libgo/go/net/http/client.go @@ -216,7 +216,7 @@ func send(ireq *Request, rt RoundTripper, deadline time.Time) (resp *Response, d if req.RequestURI != "" { req.closeBody() - return nil, alwaysFalse, errors.New("http: Request.RequestURI can't be set in client requests.") + return nil, alwaysFalse, errors.New("http: Request.RequestURI can't be set in client requests") } // forkReq forks req into a shallow clone of ireq the first @@ -265,6 +265,25 @@ func send(ireq *Request, rt RoundTripper, deadline time.Time) (resp *Response, d } return nil, didTimeout, err } + if resp == nil { + return nil, didTimeout, fmt.Errorf("http: RoundTripper implementation (%T) returned a nil *Response with a nil error", rt) + } + if resp.Body == nil { + // The documentation on the Body field says “The http Client and Transport + // guarantee that Body is always non-nil, even on responses without a body + // or responses with a zero-length body.” Unfortunately, we didn't document + // that same constraint for arbitrary RoundTripper implementations, and + // RoundTripper implementations in the wild (mostly in tests) assume that + // they can use a nil Body to mean an empty one (similar to Request.Body). + // (See https://golang.org/issue/38095.) + // + // If the ContentLength allows the Body to be empty, fill in an empty one + // here to ensure that it is non-nil. + if resp.ContentLength > 0 && req.Method != "HEAD" { + return nil, didTimeout, fmt.Errorf("http: RoundTripper implementation (%T) returned a *Response with content length %d but a nil Body", rt, resp.ContentLength) + } + resp.Body = ioutil.NopCloser(strings.NewReader("")) + } if !deadline.IsZero() { resp.Body = &cancelTimerBody{ stop: stopTimer, diff --git a/libgo/go/net/http/client_test.go b/libgo/go/net/http/client_test.go index 2b4f53f802b..80807fae7a4 100644 --- a/libgo/go/net/http/client_test.go +++ b/libgo/go/net/http/client_test.go @@ -1991,3 +1991,38 @@ func testClientDoCanceledVsTimeout(t *testing.T, h2 bool) { }) } } + +type nilBodyRoundTripper struct{} + +func (nilBodyRoundTripper) RoundTrip(req *Request) (*Response, error) { + return &Response{ + StatusCode: StatusOK, + Status: StatusText(StatusOK), + Body: nil, + Request: req, + }, nil +} + +func TestClientPopulatesNilResponseBody(t *testing.T) { + c := &Client{Transport: nilBodyRoundTripper{}} + + resp, err := c.Get("http://localhost/anything") + if err != nil { + t.Fatalf("Client.Get rejected Response with nil Body: %v", err) + } + + if resp.Body == nil { + t.Fatalf("Client failed to provide a non-nil Body as documented") + } + defer func() { + if err := resp.Body.Close(); err != nil { + t.Fatalf("error from Close on substitute Response.Body: %v", err) + } + }() + + if b, err := ioutil.ReadAll(resp.Body); err != nil { + t.Errorf("read error from substitute Response.Body: %v", err) + } else if len(b) != 0 { + t.Errorf("substitute Response.Body was unexpectedly non-empty: %q", b) + } +} diff --git a/libgo/go/net/http/cookie.go b/libgo/go/net/http/cookie.go index 5c572d6dc5a..d7a8f5e94e5 100644 --- a/libgo/go/net/http/cookie.go +++ b/libgo/go/net/http/cookie.go @@ -7,6 +7,7 @@ package http import ( "log" "net" + "net/textproto" "strconv" "strings" "time" @@ -60,11 +61,11 @@ func readSetCookies(h Header) []*Cookie { } cookies := make([]*Cookie, 0, cookieCount) for _, line := range h["Set-Cookie"] { - parts := strings.Split(strings.TrimSpace(line), ";") + parts := strings.Split(textproto.TrimString(line), ";") if len(parts) == 1 && parts[0] == "" { continue } - parts[0] = strings.TrimSpace(parts[0]) + parts[0] = textproto.TrimString(parts[0]) j := strings.Index(parts[0], "=") if j < 0 { continue @@ -83,7 +84,7 @@ func readSetCookies(h Header) []*Cookie { Raw: line, } for i := 1; i < len(parts); i++ { - parts[i] = strings.TrimSpace(parts[i]) + parts[i] = textproto.TrimString(parts[i]) if len(parts[i]) == 0 { continue } @@ -242,7 +243,7 @@ func readCookies(h Header, filter string) []*Cookie { cookies := make([]*Cookie, 0, len(lines)+strings.Count(lines[0], ";")) for _, line := range lines { - line = strings.TrimSpace(line) + line = textproto.TrimString(line) var part string for len(line) > 0 { // continue since we have rest @@ -251,7 +252,7 @@ func readCookies(h Header, filter string) []*Cookie { } else { part, line = line, "" } - part = strings.TrimSpace(part) + part = textproto.TrimString(part) if len(part) == 0 { continue } diff --git a/libgo/go/net/http/fs.go b/libgo/go/net/http/fs.go index b8a68cc460f..922706ada14 100644 --- a/libgo/go/net/http/fs.go +++ b/libgo/go/net/http/fs.go @@ -30,11 +30,13 @@ import ( // value is a filename on the native file system, not a URL, so it is separated // by filepath.Separator, which isn't necessarily '/'. // -// Note that Dir will allow access to files and directories starting with a -// period, which could expose sensitive directories like a .git directory or -// sensitive files like .htpasswd. To exclude files with a leading period, -// remove the files/directories from the server or create a custom FileSystem -// implementation. +// Note that Dir could expose sensitive files and directories. Dir will follow +// symlinks pointing out of the directory tree, which can be especially dangerous +// if serving from a directory in which users are able to create arbitrary symlinks. +// Dir will also allow access to files and directories starting with a period, +// which could expose sensitive directories like .git or sensitive files like +// .htpasswd. To exclude files with a leading period, remove the files/directories +// from the server or create a custom FileSystem implementation. // // An empty Dir is treated as ".". type Dir string @@ -757,7 +759,7 @@ func parseRange(s string, size int64) ([]httpRange, error) { var ranges []httpRange noOverlap := false for _, ra := range strings.Split(s[len(b):], ",") { - ra = strings.TrimSpace(ra) + ra = textproto.TrimString(ra) if ra == "" { continue } @@ -765,7 +767,7 @@ func parseRange(s string, size int64) ([]httpRange, error) { if i < 0 { return nil, errors.New("invalid range") } - start, end := strings.TrimSpace(ra[:i]), strings.TrimSpace(ra[i+1:]) + start, end := textproto.TrimString(ra[:i]), textproto.TrimString(ra[i+1:]) var r httpRange if start == "" { // If no start is specified, end specifies the diff --git a/libgo/go/net/http/h2_bundle.go b/libgo/go/net/http/h2_bundle.go index f03dbba729b..779da4fdfdf 100644 --- a/libgo/go/net/http/h2_bundle.go +++ b/libgo/go/net/http/h2_bundle.go @@ -783,6 +783,7 @@ func (p *http2clientConnPool) getClientConn(req *Request, addr string, dialOnMis // dialCall is an in-flight Transport dial call to a host. type http2dialCall struct { + _ http2incomparable p *http2clientConnPool done chan struct{} // closed when done res *http2ClientConn // valid after done is closed @@ -856,6 +857,7 @@ func (p *http2clientConnPool) addConnIfNeeded(key string, t *http2Transport, c * } type http2addConnCall struct { + _ http2incomparable p *http2clientConnPool done chan struct{} // closed when done err error @@ -876,12 +878,6 @@ func (c *http2addConnCall) run(t *http2Transport, key string, tc *tls.Conn) { close(c.done) } -func (p *http2clientConnPool) addConn(key string, cc *http2ClientConn) { - p.mu.Lock() - p.addConnLocked(key, cc) - p.mu.Unlock() -} - // p.mu must be held func (p *http2clientConnPool) addConnLocked(key string, cc *http2ClientConn) { for _, v := range p.conns[key] { @@ -1219,6 +1215,8 @@ var ( // flow is the flow control window's size. type http2flow struct { + _ http2incomparable + // n is the number of DATA bytes we're allowed to send. // A flow is kept both on a conn and a per-stream. n int32 @@ -3245,11 +3243,6 @@ func (s http2SettingID) String() string { return fmt.Sprintf("UNKNOWN_SETTING_%d", uint16(s)) } -var ( - http2errInvalidHeaderFieldName = errors.New("http2: invalid header field name") - http2errInvalidHeaderFieldValue = errors.New("http2: invalid header field value") -) - // validWireHeaderFieldName reports whether v is a valid header field // name (key). See httpguts.ValidHeaderName for the base rules. // @@ -3320,6 +3313,7 @@ func (cw http2closeWaiter) Wait() { // Its buffered writer is lazily allocated as needed, to minimize // idle memory usage with many connections. type http2bufferedWriter struct { + _ http2incomparable w io.Writer // immutable bw *bufio.Writer // non-nil when data is buffered } @@ -3392,6 +3386,7 @@ func http2bodyAllowedForStatus(status int) bool { } type http2httpError struct { + _ http2incomparable msg string timeout bool } @@ -3460,6 +3455,11 @@ func http2validPseudoPath(v string) bool { return (len(v) > 0 && v[0] == '/') || v == "*" } +// incomparable is a zero-width, non-comparable type. Adding it to a struct +// makes that struct also non-comparable, and generally doesn't add +// any size (as long as it's first). +type http2incomparable [0]func() + // pipe is a goroutine-safe io.Reader/io.Writer pair. It's like // io.Pipe except there are no PipeReader/PipeWriter halves, and the // underlying buffer is an interface. (io.Pipe is always unbuffered) @@ -4147,13 +4147,10 @@ type http2stream struct { cancelCtx func() // owned by serverConn's serve loop: - bodyBytes int64 // body bytes seen so far - declBodyBytes int64 // or -1 if undeclared - flow http2flow // limits writing from Handler to client - inflow http2flow // what the client is allowed to POST/etc to us - parent *http2stream // or nil - numTrailerValues int64 - weight uint8 + bodyBytes int64 // body bytes seen so far + declBodyBytes int64 // or -1 if undeclared + flow http2flow // limits writing from Handler to client + inflow http2flow // what the client is allowed to POST/etc to us state http2streamState resetQueued bool // RST_STREAM queued for write; set by sc.resetStream gotTrailerHeader bool // HEADER frame for trailers was seen @@ -4333,6 +4330,7 @@ func (sc *http2serverConn) readFrames() { // frameWriteResult is the message passed from writeFrameAsync to the serve goroutine. type http2frameWriteResult struct { + _ http2incomparable wr http2FrameWriteRequest // what was written (or attempted) err error // result of the writeFrame call } @@ -4343,7 +4341,7 @@ type http2frameWriteResult struct { // serverConn. func (sc *http2serverConn) writeFrameAsync(wr http2FrameWriteRequest) { err := wr.write.writeFrame(sc) - sc.wroteFrameCh <- http2frameWriteResult{wr, err} + sc.wroteFrameCh <- http2frameWriteResult{wr: wr, err: err} } func (sc *http2serverConn) closeAllStreamsOnConnClose() { @@ -4735,7 +4733,7 @@ func (sc *http2serverConn) startFrameWrite(wr http2FrameWriteRequest) { if wr.write.staysWithinBuffer(sc.bw.Available()) { sc.writingFrameAsync = false err := wr.write.writeFrame(sc) - sc.wroteFrame(http2frameWriteResult{wr, err}) + sc.wroteFrame(http2frameWriteResult{wr: wr, err: err}) } else { sc.writingFrameAsync = true go sc.writeFrameAsync(wr) @@ -5849,6 +5847,7 @@ func (sc *http2serverConn) sendWindowUpdate32(st *http2stream, n int32) { // requestBody is the Handler's Request.Body type. // Read and Close may be called concurrently. type http2requestBody struct { + _ http2incomparable stream *http2stream conn *http2serverConn closed bool // for use by Close only @@ -6592,7 +6591,7 @@ type http2Transport struct { // send in the initial settings frame. It is how many bytes // of response headers are allowed. Unlike the http2 spec, zero here // means to use a default limit (currently 10MB). If you actually - // want to advertise an ulimited value to the peer, Transport + // want to advertise an unlimited value to the peer, Transport // interprets the highest possible value here (0xffffffff or 1<<32-1) // to mean no limit. MaxHeaderListSize uint32 @@ -7416,7 +7415,7 @@ func http2commaSeparatedTrailers(req *Request) (string, error) { k = CanonicalHeaderKey(k) switch k { case "Transfer-Encoding", "Trailer", "Content-Length": - return "", &http2badStringError{"invalid Trailer key", k} + return "", fmt.Errorf("invalid Trailer key %q", k) } keys = append(keys, k) } @@ -7909,13 +7908,6 @@ func (cs *http2clientStream) awaitFlowControl(maxBytes int) (taken int32, err er } } -type http2badStringError struct { - what string - str string -} - -func (e *http2badStringError) Error() string { return fmt.Sprintf("%s %q", e.what, e.str) } - // requires cc.mu be held. func (cc *http2ClientConn) encodeHeaders(req *Request, addGzipHeader bool, trailers string, contentLength int64) ([]byte, error) { cc.hbuf.Reset() @@ -8131,6 +8123,7 @@ func (cc *http2ClientConn) writeHeader(name, value string) { } type http2resAndError struct { + _ http2incomparable res *Response err error } @@ -8178,6 +8171,7 @@ func (cc *http2ClientConn) streamByID(id uint32, andRemove bool) *http2clientStr // clientConnReadLoop is the state owned by the clientConn's frame-reading readLoop. type http2clientConnReadLoop struct { + _ http2incomparable cc *http2ClientConn closeWhenIdle bool } @@ -8407,7 +8401,9 @@ func (rl *http2clientConnReadLoop) handleResponse(cs *http2clientStream, f *http return nil, errors.New("malformed response from server: malformed non-numeric status pseudo header") } - header := make(Header) + regularFields := f.RegularFields() + strs := make([]string, len(regularFields)) + header := make(Header, len(regularFields)) res := &Response{ Proto: "HTTP/2.0", ProtoMajor: 2, @@ -8415,7 +8411,7 @@ func (rl *http2clientConnReadLoop) handleResponse(cs *http2clientStream, f *http StatusCode: statusCode, Status: status + " " + StatusText(statusCode), } - for _, hf := range f.RegularFields() { + for _, hf := range regularFields { key := CanonicalHeaderKey(hf.Name) if key == "Trailer" { t := res.Trailer @@ -8427,7 +8423,18 @@ func (rl *http2clientConnReadLoop) handleResponse(cs *http2clientStream, f *http t[CanonicalHeaderKey(v)] = nil }) } else { - header[key] = append(header[key], hf.Value) + vv := header[key] + if vv == nil && len(strs) > 0 { + // More than likely this will be a single-element key. + // Most headers aren't multi-valued. + // Set the capacity on strs[0] to 1, so any future append + // won't extend the slice into the other strings. + vv, strs = strs[:1:1], strs[1:] + vv[0] = hf.Value + header[key] = vv + } else { + header[key] = append(vv, hf.Value) + } } } @@ -8713,8 +8720,6 @@ func (rl *http2clientConnReadLoop) processData(f *http2DataFrame) error { return nil } -var http2errInvalidTrailers = errors.New("http2: invalid trailers") - func (rl *http2clientConnReadLoop) endStream(cs *http2clientStream) { // TODO: check that any declared content-length matches, like // server.go's (*stream).endStream method. @@ -8945,7 +8950,6 @@ func (cc *http2ClientConn) writeStreamReset(streamID uint32, code http2ErrCode, var ( http2errResponseHeaderListSize = errors.New("http2: response header list larger than advertised limit") http2errRequestHeaderListSize = errors.New("http2: request header list larger than peer's advertised limit") - http2errPseudoTrailers = errors.New("http2: invalid pseudo header in trailers") ) func (cc *http2ClientConn) logf(format string, args ...interface{}) { @@ -8984,6 +8988,7 @@ func (rt http2erringRoundTripper) RoundTrip(*Request) (*Response, error) { retur // gzipReader wraps a response body so it can lazily // call gzip.NewReader on the first call to Read type http2gzipReader struct { + _ http2incomparable body io.ReadCloser // underlying Response.Body zr *gzip.Reader // lazily-initialized gzip reader zerr error // sticky error diff --git a/libgo/go/net/http/http.go b/libgo/go/net/http/http.go index 89e86d80e8e..4c5054b3994 100644 --- a/libgo/go/net/http/http.go +++ b/libgo/go/net/http/http.go @@ -16,6 +16,11 @@ import ( "golang.org/x/net/http/httpguts" ) +// incomparable is a zero-width, non-comparable type. Adding it to a struct +// makes that struct also non-comparable, and generally doesn't add +// any size (as long as it's first). +type incomparable [0]func() + // maxInt64 is the effective "infinite" value for the Server and // Transport's byte-limiting readers. const maxInt64 = 1<<63 - 1 diff --git a/libgo/go/net/http/httptest/recorder.go b/libgo/go/net/http/httptest/recorder.go index d0bc0fade98..66e67e78b30 100644 --- a/libgo/go/net/http/httptest/recorder.go +++ b/libgo/go/net/http/httptest/recorder.go @@ -9,6 +9,7 @@ import ( "fmt" "io/ioutil" "net/http" + "net/textproto" "strconv" "strings" @@ -221,13 +222,13 @@ func (rw *ResponseRecorder) Result() *http.Response { // This a modified version of same function found in net/http/transfer.go. This // one just ignores an invalid header. func parseContentLength(cl string) int64 { - cl = strings.TrimSpace(cl) + cl = textproto.TrimString(cl) if cl == "" { return -1 } - n, err := strconv.ParseInt(cl, 10, 64) + n, err := strconv.ParseUint(cl, 10, 63) if err != nil { return -1 } - return n + return int64(n) } diff --git a/libgo/go/net/http/httptest/recorder_test.go b/libgo/go/net/http/httptest/recorder_test.go index 0986554aa88..e9534894b6c 100644 --- a/libgo/go/net/http/httptest/recorder_test.go +++ b/libgo/go/net/http/httptest/recorder_test.go @@ -310,3 +310,39 @@ func TestRecorder(t *testing.T) { }) } } + +// issue 39017 - disallow Content-Length values such as "+3" +func TestParseContentLength(t *testing.T) { + tests := []struct { + cl string + want int64 + }{ + { + cl: "3", + want: 3, + }, + { + cl: "+3", + want: -1, + }, + { + cl: "-3", + want: -1, + }, + { + // max int64, for safe conversion before returning + cl: "9223372036854775807", + want: 9223372036854775807, + }, + { + cl: "9223372036854775808", + want: -1, + }, + } + + for _, tt := range tests { + if got := parseContentLength(tt.cl); got != tt.want { + t.Errorf("%q:\n\tgot=%d\n\twant=%d", tt.cl, got, tt.want) + } + } +} diff --git a/libgo/go/net/http/httputil/reverseproxy.go b/libgo/go/net/http/httputil/reverseproxy.go index 4d6a085f60a..3f48fab544e 100644 --- a/libgo/go/net/http/httputil/reverseproxy.go +++ b/libgo/go/net/http/httputil/reverseproxy.go @@ -13,6 +13,7 @@ import ( "log" "net" "net/http" + "net/textproto" "net/url" "strings" "sync" @@ -25,10 +26,15 @@ import ( // sends it to another server, proxying the response back to the // client. // -// ReverseProxy automatically sets the client IP as the value of the +// ReverseProxy by default sets the client IP as the value of the // X-Forwarded-For header. +// // If an X-Forwarded-For header already exists, the client IP is -// appended to the existing values. +// appended to the existing values. As a special case, if the header +// exists in the Request.Header map but has a nil value (such as when +// set by the Director func), the X-Forwarded-For header is +// not modified. +// // To prevent IP spoofing, be sure to delete any pre-existing // X-Forwarded-For header coming from the client or // an untrusted proxy. @@ -105,6 +111,27 @@ func singleJoiningSlash(a, b string) string { return a + b } +func joinURLPath(a, b *url.URL) (path, rawpath string) { + if a.RawPath == "" && b.RawPath == "" { + return singleJoiningSlash(a.Path, b.Path), "" + } + // Same as singleJoiningSlash, but uses EscapedPath to determine + // whether a slash should be added + apath := a.EscapedPath() + bpath := b.EscapedPath() + + aslash := strings.HasSuffix(apath, "/") + bslash := strings.HasPrefix(bpath, "/") + + switch { + case aslash && bslash: + return a.Path + b.Path[1:], apath + bpath[1:] + case !aslash && !bslash: + return a.Path + "/" + b.Path, apath + "/" + bpath + } + return a.Path + b.Path, apath + bpath +} + // NewSingleHostReverseProxy returns a new ReverseProxy that routes // URLs to the scheme, host, and base path provided in target. If the // target's path is "/base" and the incoming request was for "/dir", @@ -117,7 +144,7 @@ func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy { director := func(req *http.Request) { req.URL.Scheme = target.Scheme req.URL.Host = target.Host - req.URL.Path = singleJoiningSlash(target.Path, req.URL.Path) + req.URL.Path, req.URL.RawPath = joinURLPath(target, req.URL) if targetQuery == "" || req.URL.RawQuery == "" { req.URL.RawQuery = targetQuery + req.URL.RawQuery } else { @@ -248,10 +275,14 @@ func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { // If we aren't the first proxy retain prior // X-Forwarded-For information as a comma+space // separated list and fold multiple headers into one. - if prior, ok := outreq.Header["X-Forwarded-For"]; ok { + prior, ok := outreq.Header["X-Forwarded-For"] + omit := ok && prior == nil // Issue 38079: nil now means don't populate the header + if len(prior) > 0 { clientIP = strings.Join(prior, ", ") + ", " + clientIP } - outreq.Header.Set("X-Forwarded-For", clientIP) + if !omit { + outreq.Header.Set("X-Forwarded-For", clientIP) + } } res, err := transport.RoundTrip(outreq) @@ -357,7 +388,7 @@ func shouldPanicOnCopyError(req *http.Request) bool { func removeConnectionHeaders(h http.Header) { for _, f := range h["Connection"] { for _, sf := range strings.Split(f, ",") { - if sf = strings.TrimSpace(sf); sf != "" { + if sf = textproto.TrimString(sf); sf != "" { h.Del(sf) } } @@ -526,7 +557,20 @@ func (p *ReverseProxy) handleUpgradeResponse(rw http.ResponseWriter, req *http.R p.getErrorHandler()(rw, req, fmt.Errorf("internal error: 101 switching protocols response with non-writable body")) return } - defer backConn.Close() + + backConnCloseCh := make(chan bool) + go func() { + // Ensure that the cancelation of a request closes the backend. + // See issue https://golang.org/issue/35559. + select { + case <-req.Context().Done(): + case <-backConnCloseCh: + } + backConn.Close() + }() + + defer close(backConnCloseCh) + conn, brw, err := hj.Hijack() if err != nil { p.getErrorHandler()(rw, req, fmt.Errorf("Hijack failed on protocol switch: %v", err)) diff --git a/libgo/go/net/http/httputil/reverseproxy_test.go b/libgo/go/net/http/httputil/reverseproxy_test.go index f58e08867f6..764939fb0f0 100644 --- a/libgo/go/net/http/httputil/reverseproxy_test.go +++ b/libgo/go/net/http/httputil/reverseproxy_test.go @@ -277,6 +277,39 @@ func TestXForwardedFor(t *testing.T) { } } +// Issue 38079: don't append to X-Forwarded-For if it's present but nil +func TestXForwardedFor_Omit(t *testing.T) { + backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if v := r.Header.Get("X-Forwarded-For"); v != "" { + t.Errorf("got X-Forwarded-For header: %q", v) + } + w.Write([]byte("hi")) + })) + defer backend.Close() + backendURL, err := url.Parse(backend.URL) + if err != nil { + t.Fatal(err) + } + proxyHandler := NewSingleHostReverseProxy(backendURL) + frontend := httptest.NewServer(proxyHandler) + defer frontend.Close() + + oldDirector := proxyHandler.Director + proxyHandler.Director = func(r *http.Request) { + r.Header["X-Forwarded-For"] = nil + oldDirector(r) + } + + getReq, _ := http.NewRequest("GET", frontend.URL, nil) + getReq.Host = "some-name" + getReq.Close = true + res, err := frontend.Client().Do(getReq) + if err != nil { + t.Fatalf("Get: %v", err) + } + res.Body.Close() +} + var proxyQueryTests = []struct { baseSuffix string // suffix to add to backend URL reqSuffix string // suffix to add to frontend's request URL @@ -386,7 +419,7 @@ func TestReverseProxyFlushIntervalHeaders(t *testing.T) { } } -func TestReverseProxyCancelation(t *testing.T) { +func TestReverseProxyCancellation(t *testing.T) { const backendResponse = "I am the backend" reqInFlight := make(chan struct{}) @@ -1158,6 +1191,137 @@ func TestReverseProxyWebSocket(t *testing.T) { } } +func TestReverseProxyWebSocketCancelation(t *testing.T) { + n := 5 + triggerCancelCh := make(chan bool, n) + nthResponse := func(i int) string { + return fmt.Sprintf("backend response #%d\n", i) + } + terminalMsg := "final message" + + cst := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if g, ws := upgradeType(r.Header), "websocket"; g != ws { + t.Errorf("Unexpected upgrade type %q, want %q", g, ws) + http.Error(w, "Unexpected request", 400) + return + } + conn, bufrw, err := w.(http.Hijacker).Hijack() + if err != nil { + t.Error(err) + return + } + defer conn.Close() + + upgradeMsg := "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nUpgrade: WebSocket\r\n\r\n" + if _, err := io.WriteString(conn, upgradeMsg); err != nil { + t.Error(err) + return + } + if _, _, err := bufrw.ReadLine(); err != nil { + t.Errorf("Failed to read line from client: %v", err) + return + } + + for i := 0; i < n; i++ { + if _, err := bufrw.WriteString(nthResponse(i)); err != nil { + select { + case <-triggerCancelCh: + default: + t.Errorf("Writing response #%d failed: %v", i, err) + } + return + } + bufrw.Flush() + time.Sleep(time.Second) + } + if _, err := bufrw.WriteString(terminalMsg); err != nil { + select { + case <-triggerCancelCh: + default: + t.Errorf("Failed to write terminal message: %v", err) + } + } + bufrw.Flush() + })) + defer cst.Close() + + backendURL, _ := url.Parse(cst.URL) + rproxy := NewSingleHostReverseProxy(backendURL) + rproxy.ErrorLog = log.New(ioutil.Discard, "", 0) // quiet for tests + rproxy.ModifyResponse = func(res *http.Response) error { + res.Header.Add("X-Modified", "true") + return nil + } + + handler := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + rw.Header().Set("X-Header", "X-Value") + ctx, cancel := context.WithCancel(req.Context()) + go func() { + <-triggerCancelCh + cancel() + }() + rproxy.ServeHTTP(rw, req.WithContext(ctx)) + }) + + frontendProxy := httptest.NewServer(handler) + defer frontendProxy.Close() + + req, _ := http.NewRequest("GET", frontendProxy.URL, nil) + req.Header.Set("Connection", "Upgrade") + req.Header.Set("Upgrade", "websocket") + + res, err := frontendProxy.Client().Do(req) + if err != nil { + t.Fatalf("Dialing to frontend proxy: %v", err) + } + defer res.Body.Close() + if g, w := res.StatusCode, 101; g != w { + t.Fatalf("Switching protocols failed, got: %d, want: %d", g, w) + } + + if g, w := res.Header.Get("X-Header"), "X-Value"; g != w { + t.Errorf("X-Header mismatch\n\tgot: %q\n\twant: %q", g, w) + } + + if g, w := upgradeType(res.Header), "websocket"; g != w { + t.Fatalf("Upgrade header mismatch\n\tgot: %q\n\twant: %q", g, w) + } + + rwc, ok := res.Body.(io.ReadWriteCloser) + if !ok { + t.Fatalf("Response body type mismatch, got %T, want io.ReadWriteCloser", res.Body) + } + + if got, want := res.Header.Get("X-Modified"), "true"; got != want { + t.Errorf("response X-Modified header = %q; want %q", got, want) + } + + if _, err := io.WriteString(rwc, "Hello\n"); err != nil { + t.Fatalf("Failed to write first message: %v", err) + } + + // Read loop. + + br := bufio.NewReader(rwc) + for { + line, err := br.ReadString('\n') + switch { + case line == terminalMsg: // this case before "err == io.EOF" + t.Fatalf("The websocket request was not canceled, unfortunately!") + + case err == io.EOF: + return + + case err != nil: + t.Fatalf("Unexpected error: %v", err) + + case line == nthResponse(0): // We've gotten the first response back + // Let's trigger a cancel. + close(triggerCancelCh) + } + } +} + func TestUnannouncedTrailer(t *testing.T) { backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) @@ -1202,7 +1366,7 @@ func TestSingleJoinSlash(t *testing.T) { } for _, tt := range tests { if got := singleJoiningSlash(tt.slasha, tt.slashb); got != tt.expected { - t.Errorf("singleJoiningSlash(%s,%s) want %s got %s", + t.Errorf("singleJoiningSlash(%q,%q) want %q got %q", tt.slasha, tt.slashb, tt.expected, @@ -1210,3 +1374,30 @@ func TestSingleJoinSlash(t *testing.T) { } } } + +func TestJoinURLPath(t *testing.T) { + tests := []struct { + a *url.URL + b *url.URL + wantPath string + wantRaw string + }{ + {&url.URL{Path: "/a/b"}, &url.URL{Path: "/c"}, "/a/b/c", ""}, + {&url.URL{Path: "/a/b", RawPath: "badpath"}, &url.URL{Path: "c"}, "/a/b/c", "/a/b/c"}, + {&url.URL{Path: "/a/b", RawPath: "/a%2Fb"}, &url.URL{Path: "/c"}, "/a/b/c", "/a%2Fb/c"}, + {&url.URL{Path: "/a/b", RawPath: "/a%2Fb"}, &url.URL{Path: "/c"}, "/a/b/c", "/a%2Fb/c"}, + {&url.URL{Path: "/a/b/", RawPath: "/a%2Fb%2F"}, &url.URL{Path: "c"}, "/a/b//c", "/a%2Fb%2F/c"}, + {&url.URL{Path: "/a/b/", RawPath: "/a%2Fb/"}, &url.URL{Path: "/c/d", RawPath: "/c%2Fd"}, "/a/b/c/d", "/a%2Fb/c%2Fd"}, + } + + for _, tt := range tests { + p, rp := joinURLPath(tt.a, tt.b) + if p != tt.wantPath || rp != tt.wantRaw { + t.Errorf("joinURLPath(URL(%q,%q),URL(%q,%q)) want (%q,%q) got (%q,%q)", + tt.a.Path, tt.a.RawPath, + tt.b.Path, tt.b.RawPath, + tt.wantPath, tt.wantRaw, + p, rp) + } + } +} diff --git a/libgo/go/net/http/omithttp2.go b/libgo/go/net/http/omithttp2.go index 307d93a3b14..7e2f4925798 100644 --- a/libgo/go/net/http/omithttp2.go +++ b/libgo/go/net/http/omithttp2.go @@ -32,7 +32,7 @@ type http2Transport struct { func (*http2Transport) RoundTrip(*Request) (*Response, error) { panic(noHTTP2) } func (*http2Transport) CloseIdleConnections() {} -type http2erringRoundTripper struct{} +type http2erringRoundTripper struct{ err error } func (http2erringRoundTripper) RoundTrip(*Request) (*Response, error) { panic(noHTTP2) } diff --git a/libgo/go/net/http/pprof/pprof.go b/libgo/go/net/http/pprof/pprof.go index a237f58609c..81df0448e94 100644 --- a/libgo/go/net/http/pprof/pprof.go +++ b/libgo/go/net/http/pprof/pprof.go @@ -36,15 +36,17 @@ // // go tool pprof http://localhost:6060/debug/pprof/block // -// Or to collect a 5-second execution trace: -// -// wget http://localhost:6060/debug/pprof/trace?seconds=5 -// // Or to look at the holders of contended mutexes, after calling // runtime.SetMutexProfileFraction in your program: // // go tool pprof http://localhost:6060/debug/pprof/mutex // +// The package also exports a handler that serves execution trace data +// for the "go tool trace" command. To collect a 5-second execution trace: +// +// wget -O trace.out http://localhost:6060/debug/pprof/trace?seconds=5 +// go tool trace trace.out +// // To view all available profiles, open http://localhost:6060/debug/pprof/ // in your browser. // @@ -57,8 +59,10 @@ package pprof import ( "bufio" "bytes" + "context" "fmt" "html/template" + "internal/profile" "io" "log" "net/http" @@ -234,6 +238,10 @@ func (name handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { serveError(w, http.StatusNotFound, "Unknown profile") return } + if sec := r.FormValue("seconds"); sec != "" { + name.serveDeltaProfile(w, r, p, sec) + return + } gc, _ := strconv.Atoi(r.FormValue("gc")) if name == "heap" && gc > 0 { runtime.GC() @@ -248,6 +256,94 @@ func (name handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { p.WriteTo(w, debug) } +func (name handler) serveDeltaProfile(w http.ResponseWriter, r *http.Request, p *pprof.Profile, secStr string) { + sec, err := strconv.ParseInt(secStr, 10, 64) + if err != nil || sec <= 0 { + serveError(w, http.StatusBadRequest, `invalid value for "seconds" - must be a positive integer`) + return + } + if !profileSupportsDelta[name] { + serveError(w, http.StatusBadRequest, `"seconds" parameter is not supported for this profile type`) + return + } + // 'name' should be a key in profileSupportsDelta. + if durationExceedsWriteTimeout(r, float64(sec)) { + serveError(w, http.StatusBadRequest, "profile duration exceeds server's WriteTimeout") + return + } + debug, _ := strconv.Atoi(r.FormValue("debug")) + if debug != 0 { + serveError(w, http.StatusBadRequest, "seconds and debug params are incompatible") + return + } + p0, err := collectProfile(p) + if err != nil { + serveError(w, http.StatusInternalServerError, "failed to collect profile") + return + } + + t := time.NewTimer(time.Duration(sec) * time.Second) + defer t.Stop() + + select { + case <-r.Context().Done(): + err := r.Context().Err() + if err == context.DeadlineExceeded { + serveError(w, http.StatusRequestTimeout, err.Error()) + } else { // TODO: what's a good status code for cancelled requests? 400? + serveError(w, http.StatusInternalServerError, err.Error()) + } + return + case <-t.C: + } + + p1, err := collectProfile(p) + if err != nil { + serveError(w, http.StatusInternalServerError, "failed to collect profile") + return + } + ts := p1.TimeNanos + dur := p1.TimeNanos - p0.TimeNanos + + p0.Scale(-1) + + p1, err = profile.Merge([]*profile.Profile{p0, p1}) + if err != nil { + serveError(w, http.StatusInternalServerError, "failed to compute delta") + return + } + + p1.TimeNanos = ts // set since we don't know what profile.Merge set for TimeNanos. + p1.DurationNanos = dur + + w.Header().Set("Content-Type", "application/octet-stream") + w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s-delta"`, name)) + p1.Write(w) +} + +func collectProfile(p *pprof.Profile) (*profile.Profile, error) { + var buf bytes.Buffer + if err := p.WriteTo(&buf, 0); err != nil { + return nil, err + } + ts := time.Now().UnixNano() + p0, err := profile.Parse(&buf) + if err != nil { + return nil, err + } + p0.TimeNanos = ts + return p0, nil +} + +var profileSupportsDelta = map[handler]bool{ + "allocs": true, + "block": true, + "goroutine": true, + "heap": true, + "mutex": true, + "threadcreate": true, +} + var profileDescriptions = map[string]string{ "allocs": "A sampling of all past memory allocations", "block": "Stack traces that led to blocking on synchronization primitives", @@ -273,6 +369,9 @@ func Index(w http.ResponseWriter, r *http.Request) { } } + w.Header().Set("X-Content-Type-Options", "nosniff") + w.Header().Set("Content-Type", "text/html; charset=utf-8") + type profile struct { Name string Href string diff --git a/libgo/go/net/http/pprof/pprof_test.go b/libgo/go/net/http/pprof/pprof_test.go index dbb6fef1592..f6f9ef5b041 100644 --- a/libgo/go/net/http/pprof/pprof_test.go +++ b/libgo/go/net/http/pprof/pprof_test.go @@ -6,11 +6,18 @@ package pprof import ( "bytes" + "fmt" + "internal/profile" "io/ioutil" "net/http" "net/http/httptest" + "runtime" "runtime/pprof" + "strings" + "sync" + "sync/atomic" "testing" + "time" ) // TestDescriptions checks that the profile names under runtime/pprof package @@ -40,6 +47,10 @@ func TestHandlers(t *testing.T) { {"/debug/pprof/profile?seconds=1", Profile, http.StatusOK, "application/octet-stream", `attachment; filename="profile"`, nil}, {"/debug/pprof/symbol", Symbol, http.StatusOK, "text/plain; charset=utf-8", "", nil}, {"/debug/pprof/trace", Trace, http.StatusOK, "application/octet-stream", `attachment; filename="trace"`, nil}, + {"/debug/pprof/mutex", Index, http.StatusOK, "application/octet-stream", `attachment; filename="mutex"`, nil}, + {"/debug/pprof/block?seconds=1", Index, http.StatusOK, "application/octet-stream", `attachment; filename="block-delta"`, nil}, + {"/debug/pprof/goroutine?seconds=1", Index, http.StatusOK, "application/octet-stream", `attachment; filename="goroutine-delta"`, nil}, + {"/debug/pprof/", Index, http.StatusOK, "text/html; charset=utf-8", "", []byte("Types of profiles available:")}, } for _, tc := range testCases { t.Run(tc.path, func(t *testing.T) { @@ -77,5 +88,171 @@ func TestHandlers(t *testing.T) { } }) } +} + +var Sink uint32 + +func mutexHog1(mu1, mu2 *sync.Mutex, start time.Time, dt time.Duration) { + atomic.AddUint32(&Sink, 1) + for time.Since(start) < dt { + // When using gccgo the loop of mutex operations is + // not preemptible. This can cause the loop to block a GC, + // causing the time limits in TestDeltaContentionz to fail. + // Since this loop is not very realistic, when using + // gccgo add preemption points 100 times a second. + t1 := time.Now() + for time.Since(start) < dt && time.Since(t1) < 10*time.Millisecond { + mu1.Lock() + mu2.Lock() + mu1.Unlock() + mu2.Unlock() + } + if runtime.Compiler == "gccgo" { + runtime.Gosched() + } + } +} + +// mutexHog2 is almost identical to mutexHog but we keep them separate +// in order to distinguish them with function names in the stack trace. +// We make them slightly different, using Sink, because otherwise +// gccgo -c opt will merge them. +func mutexHog2(mu1, mu2 *sync.Mutex, start time.Time, dt time.Duration) { + atomic.AddUint32(&Sink, 2) + for time.Since(start) < dt { + // See comment in mutexHog. + t1 := time.Now() + for time.Since(start) < dt && time.Since(t1) < 10*time.Millisecond { + mu1.Lock() + mu2.Lock() + mu1.Unlock() + mu2.Unlock() + } + if runtime.Compiler == "gccgo" { + runtime.Gosched() + } + } +} +// mutexHog starts multiple goroutines that runs the given hogger function for the specified duration. +// The hogger function will be given two mutexes to lock & unlock. +func mutexHog(duration time.Duration, hogger func(mu1, mu2 *sync.Mutex, start time.Time, dt time.Duration)) { + start := time.Now() + mu1 := new(sync.Mutex) + mu2 := new(sync.Mutex) + var wg sync.WaitGroup + wg.Add(10) + for i := 0; i < 10; i++ { + go func() { + defer wg.Done() + hogger(mu1, mu2, start, duration) + }() + } + wg.Wait() +} + +func TestDeltaProfile(t *testing.T) { + rate := runtime.SetMutexProfileFraction(1) + defer func() { + runtime.SetMutexProfileFraction(rate) + }() + + // mutexHog1 will appear in non-delta mutex profile + // if the mutex profile works. + mutexHog(20*time.Millisecond, mutexHog1) + + // If mutexHog1 does not appear in the mutex profile, + // skip this test. Mutex profile is likely not working, + // so is the delta profile. + + p, err := query("/debug/pprof/mutex") + if err != nil { + t.Skipf("mutex profile is unsupported: %v", err) + } + + if !seen(p, "mutexHog1") { + t.Skipf("mutex profile is not working: %v", p) + } + + // causes mutexHog2 call stacks to appear in the mutex profile. + done := make(chan bool) + go func() { + for { + mutexHog(20*time.Millisecond, mutexHog2) + select { + case <-done: + done <- true + return + default: + time.Sleep(10 * time.Millisecond) + } + } + }() + defer func() { // cleanup the above goroutine. + done <- true + <-done // wait for the goroutine to exit. + }() + + for _, d := range []int{1, 4, 16, 32} { + endpoint := fmt.Sprintf("/debug/pprof/mutex?seconds=%d", d) + p, err := query(endpoint) + if err != nil { + t.Fatalf("failed to query %q: %v", endpoint, err) + } + if !seen(p, "mutexHog1") && seen(p, "mutexHog2") && p.DurationNanos > 0 { + break // pass + } + if d == 32 { + t.Errorf("want mutexHog2 but no mutexHog1 in the profile, and non-zero p.DurationNanos, got %v", p) + } + } + p, err = query("/debug/pprof/mutex") + if err != nil { + t.Fatalf("failed to query mutex profile: %v", err) + } + if !seen(p, "mutexHog1") || !seen(p, "mutexHog2") { + t.Errorf("want both mutexHog1 and mutexHog2 in the profile, got %v", p) + } +} + +var srv = httptest.NewServer(nil) + +func query(endpoint string) (*profile.Profile, error) { + url := srv.URL + endpoint + r, err := http.Get(url) + if err != nil { + return nil, fmt.Errorf("failed to fetch %q: %v", url, err) + } + if r.StatusCode != http.StatusOK { + return nil, fmt.Errorf("failed to fetch %q: %v", url, r.Status) + } + + b, err := ioutil.ReadAll(r.Body) + r.Body.Close() + if err != nil { + return nil, fmt.Errorf("failed to read and parse the result from %q: %v", url, err) + } + return profile.Parse(bytes.NewBuffer(b)) +} + +// seen returns true if the profile includes samples whose stacks include +// the specified function name (fname). +func seen(p *profile.Profile, fname string) bool { + locIDs := map[*profile.Location]bool{} + for _, loc := range p.Location { + for _, l := range loc.Line { + if strings.Contains(l.Function.Name, fname) { + locIDs[loc] = true + break + } + } + } + for _, sample := range p.Sample { + for _, loc := range sample.Location { + if locIDs[loc] { + return true + } + } + } + return false } diff --git a/libgo/go/net/http/proxy_test.go b/libgo/go/net/http/proxy_test.go index feb7047a58e..0dd57b41253 100644 --- a/libgo/go/net/http/proxy_test.go +++ b/libgo/go/net/http/proxy_test.go @@ -35,7 +35,7 @@ func TestCacheKeys(t *testing.T) { } proxy = u } - cm := connectMethod{proxy, tt.scheme, tt.addr, false} + cm := connectMethod{proxyURL: proxy, targetScheme: tt.scheme, targetAddr: tt.addr} if got := cm.key().String(); got != tt.key { t.Fatalf("{%q, %q, %q} cache key = %q; want %q", tt.proxy, tt.scheme, tt.addr, got, tt.key) } diff --git a/libgo/go/net/http/request.go b/libgo/go/net/http/request.go index 88fa0939f24..fe6b60982cd 100644 --- a/libgo/go/net/http/request.go +++ b/libgo/go/net/http/request.go @@ -83,12 +83,7 @@ var ( ErrMissingContentLength = &ProtocolError{"missing ContentLength in HEAD response"} ) -type badStringError struct { - what string - str string -} - -func (e *badStringError) Error() string { return fmt.Sprintf("%s %q", e.what, e.str) } +func badStringError(what, val string) error { return fmt.Errorf("%s %q", what, val) } // Headers that Request.Write handles itself and should be skipped. var reqWriteExcludeHeader = map[string]bool{ @@ -430,6 +425,8 @@ func (r *Request) Cookie(name string) (*Cookie, error) { // AddCookie does not attach more than one Cookie header field. That // means all cookies, if any, are written into the same line, // separated by semicolon. +// AddCookie only sanitizes c's name and value, and does not sanitize +// a Cookie header already present in the request. func (r *Request) AddCookie(c *Cookie) { s := fmt.Sprintf("%s=%s", sanitizeCookieName(c.Name), sanitizeCookieValue(c.Value)) if c := r.Header.Get("Cookie"); c != "" { @@ -506,7 +503,7 @@ func valueOrDefault(value, def string) string { // NOTE: This is not intended to reflect the actual Go version being used. // It was changed at the time of Go 1.1 release because the former User-Agent -// had ended up on a blacklist for some intrusion detection systems. +// had ended up blocked by some intrusion detection systems. // See https://codereview.appspot.com/7532043. const defaultUserAgent = "Go-http-client/1.1" @@ -1025,14 +1022,14 @@ func readRequest(b *bufio.Reader, deleteHostHeader bool) (req *Request, err erro var ok bool req.Method, req.RequestURI, req.Proto, ok = parseRequestLine(s) if !ok { - return nil, &badStringError{"malformed HTTP request", s} + return nil, badStringError("malformed HTTP request", s) } if !validMethod(req.Method) { - return nil, &badStringError{"invalid method", req.Method} + return nil, badStringError("invalid method", req.Method) } rawurl := req.RequestURI if req.ProtoMajor, req.ProtoMinor, ok = ParseHTTPVersion(req.Proto); !ok { - return nil, &badStringError{"malformed HTTP version", req.Proto} + return nil, badStringError("malformed HTTP version", req.Proto) } // CONNECT requests are used two different ways, and neither uses a full URL: diff --git a/libgo/go/net/http/response.go b/libgo/go/net/http/response.go index cd9d796c264..72812f06429 100644 --- a/libgo/go/net/http/response.go +++ b/libgo/go/net/http/response.go @@ -166,7 +166,7 @@ func ReadResponse(r *bufio.Reader, req *Request) (*Response, error) { return nil, err } if i := strings.IndexByte(line, ' '); i == -1 { - return nil, &badStringError{"malformed HTTP response", line} + return nil, badStringError("malformed HTTP response", line) } else { resp.Proto = line[:i] resp.Status = strings.TrimLeft(line[i+1:], " ") @@ -176,15 +176,15 @@ func ReadResponse(r *bufio.Reader, req *Request) (*Response, error) { statusCode = resp.Status[:i] } if len(statusCode) != 3 { - return nil, &badStringError{"malformed HTTP status code", statusCode} + return nil, badStringError("malformed HTTP status code", statusCode) } resp.StatusCode, err = strconv.Atoi(statusCode) if err != nil || resp.StatusCode < 0 { - return nil, &badStringError{"malformed HTTP status code", statusCode} + return nil, badStringError("malformed HTTP status code", statusCode) } var ok bool if resp.ProtoMajor, resp.ProtoMinor, ok = ParseHTTPVersion(resp.Proto); !ok { - return nil, &badStringError{"malformed HTTP version", resp.Proto} + return nil, badStringError("malformed HTTP version", resp.Proto) } // Parse the response headers. diff --git a/libgo/go/net/http/response_test.go b/libgo/go/net/http/response_test.go index 0c78df6f3fd..ce872606b14 100644 --- a/libgo/go/net/http/response_test.go +++ b/libgo/go/net/http/response_test.go @@ -734,6 +734,7 @@ func TestReadResponseCloseInMiddle(t *testing.T) { } func diff(t *testing.T, prefix string, have, want interface{}) { + t.Helper() hv := reflect.ValueOf(have).Elem() wv := reflect.ValueOf(want).Elem() if hv.Type() != wv.Type() { diff --git a/libgo/go/net/http/roundtrip_js.go b/libgo/go/net/http/roundtrip_js.go index 4dd99651a7b..509d229aada 100644 --- a/libgo/go/net/http/roundtrip_js.go +++ b/libgo/go/net/http/roundtrip_js.go @@ -102,12 +102,17 @@ func (t *Transport) RoundTrip(req *Request) (*Response, error) { js.CopyBytesToJS(buf, body) opt.Set("body", buf) } - respPromise := js.Global().Call("fetch", req.URL.String(), opt) + + fetchPromise := js.Global().Call("fetch", req.URL.String(), opt) var ( - respCh = make(chan *Response, 1) - errCh = make(chan error, 1) + respCh = make(chan *Response, 1) + errCh = make(chan error, 1) + success, failure js.Func ) - success := js.FuncOf(func(this js.Value, args []js.Value) interface{} { + success = js.FuncOf(func(this js.Value, args []js.Value) interface{} { + success.Release() + failure.Release() + result := args[0] header := Header{} // https://developer.mozilla.org/en-US/docs/Web/API/Headers/entries @@ -141,35 +146,29 @@ func (t *Transport) RoundTrip(req *Request) (*Response, error) { } code := result.Get("status").Int() - select { - case respCh <- &Response{ + respCh <- &Response{ Status: fmt.Sprintf("%d %s", code, StatusText(code)), StatusCode: code, Header: header, ContentLength: contentLength, Body: body, Request: req, - }: - case <-req.Context().Done(): } return nil }) - defer success.Release() - failure := js.FuncOf(func(this js.Value, args []js.Value) interface{} { - err := fmt.Errorf("net/http: fetch() failed: %s", args[0].String()) - select { - case errCh <- err: - case <-req.Context().Done(): - } + failure = js.FuncOf(func(this js.Value, args []js.Value) interface{} { + success.Release() + failure.Release() + errCh <- fmt.Errorf("net/http: fetch() failed: %s", args[0].Get("message").String()) return nil }) - defer failure.Release() - respPromise.Call("then", success, failure) + + fetchPromise.Call("then", success, failure) select { case <-req.Context().Done(): if !ac.IsUndefined() { - // Abort the Fetch request + // Abort the Fetch request. ac.Call("abort") } return nil, req.Context().Err() diff --git a/libgo/go/net/http/serve_test.go b/libgo/go/net/http/serve_test.go index 29b937993e0..5f569327782 100644 --- a/libgo/go/net/http/serve_test.go +++ b/libgo/go/net/http/serve_test.go @@ -947,7 +947,7 @@ func TestOnlyWriteTimeout(t *testing.T) { c := ts.Client() - errc := make(chan error) + errc := make(chan error, 1) go func() { res, err := c.Get(ts.URL) if err != nil { @@ -1057,16 +1057,13 @@ func TestIdentityResponse(t *testing.T) { t.Fatalf("error writing: %v", err) } - // The ReadAll will hang for a failing test, so use a Timer to - // fail explicitly. - goTimeout(t, 2*time.Second, func() { - got, _ := ioutil.ReadAll(conn) - expectedSuffix := "\r\n\r\ntoo short" - if !strings.HasSuffix(string(got), expectedSuffix) { - t.Errorf("Expected output to end with %q; got response body %q", - expectedSuffix, string(got)) - } - }) + // The ReadAll will hang for a failing test. + got, _ := ioutil.ReadAll(conn) + expectedSuffix := "\r\n\r\ntoo short" + if !strings.HasSuffix(string(got), expectedSuffix) { + t.Errorf("Expected output to end with %q; got response body %q", + expectedSuffix, string(got)) + } } func testTCPConnectionCloses(t *testing.T, req string, h Handler) { @@ -1350,37 +1347,6 @@ func TestServerAllowsBlockingRemoteAddr(t *testing.T) { } } -func TestIdentityResponseHeaders(t *testing.T) { - // Not parallel; changes log output. - defer afterTest(t) - log.SetOutput(ioutil.Discard) // is noisy otherwise - defer log.SetOutput(os.Stderr) - - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - w.Header().Set("Transfer-Encoding", "identity") - w.(Flusher).Flush() - fmt.Fprintf(w, "I am an identity response.") - })) - defer ts.Close() - - c := ts.Client() - res, err := c.Get(ts.URL) - if err != nil { - t.Fatalf("Get error: %v", err) - } - defer res.Body.Close() - - if g, e := res.TransferEncoding, []string(nil); !reflect.DeepEqual(g, e) { - t.Errorf("expected TransferEncoding of %v; got %v", e, g) - } - if _, haveCL := res.Header["Content-Length"]; haveCL { - t.Errorf("Unexpected Content-Length") - } - if !res.Close { - t.Errorf("expected Connection: close; got %v", res.Close) - } -} - // TestHeadResponses verifies that all MIME type sniffing and Content-Length // counting of GET requests also happens on HEAD requests. func TestHeadResponses_h1(t *testing.T) { testHeadResponses(t, h1Mode) } @@ -1438,13 +1404,13 @@ func TestTLSHandshakeTimeout(t *testing.T) { t.Fatalf("Dial: %v", err) } defer conn.Close() - goTimeout(t, 10*time.Second, func() { - var buf [1]byte - n, err := conn.Read(buf[:]) - if err == nil || n != 0 { - t.Errorf("Read = %d, %v; want an error and no bytes", n, err) - } - }) + + var buf [1]byte + n, err := conn.Read(buf[:]) + if err == nil || n != 0 { + t.Errorf("Read = %d, %v; want an error and no bytes", n, err) + } + select { case v := <-errc: if !strings.Contains(v, "timeout") && !strings.Contains(v, "TLS handshake") { @@ -1479,30 +1445,29 @@ func TestTLSServer(t *testing.T) { t.Fatalf("Dial: %v", err) } defer idleConn.Close() - goTimeout(t, 10*time.Second, func() { - if !strings.HasPrefix(ts.URL, "https://") { - t.Errorf("expected test TLS server to start with https://, got %q", ts.URL) - return - } - client := ts.Client() - res, err := client.Get(ts.URL) - if err != nil { - t.Error(err) - return - } - if res == nil { - t.Errorf("got nil Response") - return - } - defer res.Body.Close() - if res.Header.Get("X-TLS-Set") != "true" { - t.Errorf("expected X-TLS-Set response header") - return - } - if res.Header.Get("X-TLS-HandshakeComplete") != "true" { - t.Errorf("expected X-TLS-HandshakeComplete header") - } - }) + + if !strings.HasPrefix(ts.URL, "https://") { + t.Errorf("expected test TLS server to start with https://, got %q", ts.URL) + return + } + client := ts.Client() + res, err := client.Get(ts.URL) + if err != nil { + t.Error(err) + return + } + if res == nil { + t.Errorf("got nil Response") + return + } + defer res.Body.Close() + if res.Header.Get("X-TLS-Set") != "true" { + t.Errorf("expected X-TLS-Set response header") + return + } + if res.Header.Get("X-TLS-HandshakeComplete") != "true" { + t.Errorf("expected X-TLS-HandshakeComplete header") + } } func TestServeTLS(t *testing.T) { @@ -3629,21 +3594,6 @@ func TestHeaderToWire(t *testing.T) { } } -// goTimeout runs f, failing t if f takes more than ns to complete. -func goTimeout(t *testing.T, d time.Duration, f func()) { - ch := make(chan bool, 2) - timer := time.AfterFunc(d, func() { - t.Errorf("Timeout expired after %v", d) - ch <- true - }) - defer timer.Stop() - go func() { - defer func() { ch <- true }() - f() - }() - <-ch -} - type errorListener struct { errs []error } @@ -4135,10 +4085,19 @@ func TestServerConnState(t *testing.T) { doRequests() - timer := time.NewTimer(5 * time.Second) + stateDelay := 5 * time.Second + if deadline, ok := t.Deadline(); ok { + // Allow an arbitrarily long delay. + // This test was observed to be flaky on the darwin-arm64-corellium builder, + // so we're increasing the deadline to see if it starts passing. + // See https://golang.org/issue/37322. + const arbitraryCleanupMargin = 1 * time.Second + stateDelay = time.Until(deadline) - arbitraryCleanupMargin + } + timer := time.NewTimer(stateDelay) select { case <-timer.C: - t.Errorf("Timed out waiting for connection to change state.") + t.Errorf("Timed out after %v waiting for connection to change state.", stateDelay) case <-complete: timer.Stop() } @@ -5167,8 +5126,14 @@ func BenchmarkClient(b *testing.B) { } done := make(chan error) + stop := make(chan struct{}) + defer close(stop) go func() { - done <- cmd.Wait() + select { + case <-stop: + return + case done <- cmd.Wait(): + } }() // Do b.N requests to the server. @@ -5984,8 +5949,11 @@ type countCloseListener struct { } func (p *countCloseListener) Close() error { - atomic.AddInt32(&p.closes, 1) - return nil + var err error + if n := atomic.AddInt32(&p.closes, 1); n == 1 && p.Listener != nil { + err = p.Listener.Close() + } + return err } // Issue 24803: don't call Listener.Close on Server.Shutdown. diff --git a/libgo/go/net/http/server.go b/libgo/go/net/http/server.go index 6e6514dbddb..6f7a2594f70 100644 --- a/libgo/go/net/http/server.go +++ b/libgo/go/net/http/server.go @@ -640,6 +640,7 @@ func (srv *Server) newConn(rwc net.Conn) *conn { } type readResult struct { + _ incomparable n int err error b byte // byte read, if n == 1 @@ -1730,9 +1731,9 @@ func (c *conn) closeWriteAndWait() { time.Sleep(rstAvoidanceDelay) } -// validNextProto reports whether the proto is not a blacklisted ALPN -// protocol name. Empty and built-in protocol types are blacklisted -// and can't be overridden with alternate implementations. +// validNextProto reports whether the proto is a valid ALPN protocol name. +// Everything is valid except the empty string and built-in protocol types, +// so that those can't be overridden with alternate implementations. func validNextProto(proto string) bool { switch proto { case "", "http/1.1", "http/1.0": @@ -2611,8 +2612,9 @@ type Server struct { // value. ConnContext func(ctx context.Context, c net.Conn) context.Context + inShutdown atomicBool // true when when server is in shutdown + disableKeepAlives int32 // accessed atomically. - inShutdown int32 // accessed atomically (non-zero means we're in Shutdown) nextProtoOnce sync.Once // guards setupHTTP2_* init nextProtoErr error // result of http2.ConfigureServer if used @@ -2658,7 +2660,7 @@ func (s *Server) closeDoneChanLocked() { // Close returns any error returned from closing the Server's // underlying Listener(s). func (srv *Server) Close() error { - atomic.StoreInt32(&srv.inShutdown, 1) + srv.inShutdown.setTrue() srv.mu.Lock() defer srv.mu.Unlock() srv.closeDoneChanLocked() @@ -2700,7 +2702,7 @@ var shutdownPollInterval = 500 * time.Millisecond // Once Shutdown has been called on a server, it may not be reused; // future calls to methods such as Serve will return ErrServerClosed. func (srv *Server) Shutdown(ctx context.Context) error { - atomic.StoreInt32(&srv.inShutdown, 1) + srv.inShutdown.setTrue() srv.mu.Lock() lnerr := srv.closeListenersLocked() @@ -2713,7 +2715,7 @@ func (srv *Server) Shutdown(ctx context.Context) error { ticker := time.NewTicker(shutdownPollInterval) defer ticker.Stop() for { - if srv.closeIdleConns() { + if srv.closeIdleConns() && srv.numListeners() == 0 { return lnerr } select { @@ -2735,6 +2737,12 @@ func (srv *Server) RegisterOnShutdown(f func()) { srv.mu.Unlock() } +func (s *Server) numListeners() int { + s.mu.Lock() + defer s.mu.Unlock() + return len(s.listeners) +} + // closeIdleConns closes all idle connections and reports whether the // server is quiescent. func (s *Server) closeIdleConns() bool { @@ -2767,7 +2775,6 @@ func (s *Server) closeListenersLocked() error { if cerr := (*ln).Close(); cerr != nil && err == nil { err = cerr } - delete(s.listeners, ln) } return err } @@ -3066,9 +3073,7 @@ func (s *Server) doKeepAlives() bool { } func (s *Server) shuttingDown() bool { - // TODO: replace inShutdown with the existing atomicBool type; - // see https://github.com/golang/go/issues/20239#issuecomment-381434582 - return atomic.LoadInt32(&s.inShutdown) != 0 + return s.inShutdown.isSet() } // SetKeepAlivesEnabled controls whether HTTP keep-alives are enabled. diff --git a/libgo/go/net/http/transfer.go b/libgo/go/net/http/transfer.go index 2e01a07f84f..50d434b1fb0 100644 --- a/libgo/go/net/http/transfer.go +++ b/libgo/go/net/http/transfer.go @@ -310,7 +310,7 @@ func (t *transferWriter) writeHeader(w io.Writer, trace *httptrace.ClientTrace) k = CanonicalHeaderKey(k) switch k { case "Transfer-Encoding", "Trailer", "Content-Length": - return &badStringError{"invalid Trailer key", k} + return badStringError("invalid Trailer key", k) } keys = append(keys, k) } @@ -335,7 +335,7 @@ func (t *transferWriter) writeBody(w io.Writer) error { var ncopy int64 // Write body. We "unwrap" the body first if it was wrapped in a - // nopCloser. This is to ensure that we can take advantage of + // nopCloser or readTrackingBody. This is to ensure that we can take advantage of // OS-level optimizations in the event that the body is an // *os.File. if t.Body != nil { @@ -413,7 +413,10 @@ func (t *transferWriter) unwrapBody() io.Reader { if reflect.TypeOf(t.Body) == nopCloserType { return reflect.ValueOf(t.Body).Field(0).Interface().(io.Reader) } - + if r, ok := t.Body.(*readTrackingBody); ok { + r.didRead = true + return r.ReadCloser + } return t.Body } @@ -425,11 +428,11 @@ type transferReader struct { ProtoMajor int ProtoMinor int // Output - Body io.ReadCloser - ContentLength int64 - TransferEncoding []string - Close bool - Trailer Header + Body io.ReadCloser + ContentLength int64 + Chunked bool + Close bool + Trailer Header } func (t *transferReader) protoAtLeast(m, n int) bool { @@ -501,13 +504,12 @@ func readTransfer(msg interface{}, r *bufio.Reader) (err error) { t.ProtoMajor, t.ProtoMinor = 1, 1 } - // Transfer encoding, content length - err = t.fixTransferEncoding() - if err != nil { + // Transfer-Encoding: chunked, and overriding Content-Length. + if err := t.parseTransferEncoding(); err != nil { return err } - realLength, err := fixLength(isResponse, t.StatusCode, t.RequestMethod, t.Header, t.TransferEncoding) + realLength, err := fixLength(isResponse, t.StatusCode, t.RequestMethod, t.Header, t.Chunked) if err != nil { return err } @@ -522,7 +524,7 @@ func readTransfer(msg interface{}, r *bufio.Reader) (err error) { } // Trailer - t.Trailer, err = fixTrailer(t.Header, t.TransferEncoding) + t.Trailer, err = fixTrailer(t.Header, t.Chunked) if err != nil { return err } @@ -532,9 +534,7 @@ func readTransfer(msg interface{}, r *bufio.Reader) (err error) { // See RFC 7230, section 3.3. switch msg.(type) { case *Response: - if realLength == -1 && - !chunked(t.TransferEncoding) && - bodyAllowedForStatus(t.StatusCode) { + if realLength == -1 && !t.Chunked && bodyAllowedForStatus(t.StatusCode) { // Unbounded body. t.Close = true } @@ -543,7 +543,7 @@ func readTransfer(msg interface{}, r *bufio.Reader) (err error) { // Prepare body reader. ContentLength < 0 means chunked encoding // or close connection when finished, since multipart is not supported yet switch { - case chunked(t.TransferEncoding): + case t.Chunked: if noResponseBodyExpected(t.RequestMethod) || !bodyAllowedForStatus(t.StatusCode) { t.Body = NoBody } else { @@ -569,13 +569,17 @@ func readTransfer(msg interface{}, r *bufio.Reader) (err error) { case *Request: rr.Body = t.Body rr.ContentLength = t.ContentLength - rr.TransferEncoding = t.TransferEncoding + if t.Chunked { + rr.TransferEncoding = []string{"chunked"} + } rr.Close = t.Close rr.Trailer = t.Trailer case *Response: rr.Body = t.Body rr.ContentLength = t.ContentLength - rr.TransferEncoding = t.TransferEncoding + if t.Chunked { + rr.TransferEncoding = []string{"chunked"} + } rr.Close = t.Close rr.Trailer = t.Trailer } @@ -605,8 +609,8 @@ func isUnsupportedTEError(err error) bool { return ok } -// fixTransferEncoding sanitizes t.TransferEncoding, if needed. -func (t *transferReader) fixTransferEncoding() error { +// parseTransferEncoding sets t.Chunked based on the Transfer-Encoding header. +func (t *transferReader) parseTransferEncoding() error { raw, present := t.Header["Transfer-Encoding"] if !present { return nil @@ -618,56 +622,38 @@ func (t *transferReader) fixTransferEncoding() error { return nil } - encodings := strings.Split(raw[0], ",") - te := make([]string, 0, len(encodings)) - // TODO: Even though we only support "identity" and "chunked" - // encodings, the loop below is designed with foresight. One - // invariant that must be maintained is that, if present, - // chunked encoding must always come first. - for _, encoding := range encodings { - encoding = strings.ToLower(strings.TrimSpace(encoding)) - // "identity" encoding is not recorded - if encoding == "identity" { - break - } - if encoding != "chunked" { - return &unsupportedTEError{fmt.Sprintf("unsupported transfer encoding: %q", encoding)} - } - te = te[0 : len(te)+1] - te[len(te)-1] = encoding - } - if len(te) > 1 { - return &badStringError{"too many transfer encodings", strings.Join(te, ",")} - } - if len(te) > 0 { - // RFC 7230 3.3.2 says "A sender MUST NOT send a - // Content-Length header field in any message that - // contains a Transfer-Encoding header field." - // - // but also: - // "If a message is received with both a - // Transfer-Encoding and a Content-Length header - // field, the Transfer-Encoding overrides the - // Content-Length. Such a message might indicate an - // attempt to perform request smuggling (Section 9.5) - // or response splitting (Section 9.4) and ought to be - // handled as an error. A sender MUST remove the - // received Content-Length field prior to forwarding - // such a message downstream." - // - // Reportedly, these appear in the wild. - delete(t.Header, "Content-Length") - t.TransferEncoding = te - return nil + // Like nginx, we only support a single Transfer-Encoding header field, and + // only if set to "chunked". This is one of the most security sensitive + // surfaces in HTTP/1.1 due to the risk of request smuggling, so we keep it + // strict and simple. + if len(raw) != 1 { + return &unsupportedTEError{fmt.Sprintf("too many transfer encodings: %q", raw)} } + if strings.ToLower(textproto.TrimString(raw[0])) != "chunked" { + return &unsupportedTEError{fmt.Sprintf("unsupported transfer encoding: %q", raw[0])} + } + + // RFC 7230 3.3.2 says "A sender MUST NOT send a Content-Length header field + // in any message that contains a Transfer-Encoding header field." + // + // but also: "If a message is received with both a Transfer-Encoding and a + // Content-Length header field, the Transfer-Encoding overrides the + // Content-Length. Such a message might indicate an attempt to perform + // request smuggling (Section 9.5) or response splitting (Section 9.4) and + // ought to be handled as an error. A sender MUST remove the received + // Content-Length field prior to forwarding such a message downstream." + // + // Reportedly, these appear in the wild. + delete(t.Header, "Content-Length") + t.Chunked = true return nil } // Determine the expected body length, using RFC 7230 Section 3.3. This // function is not a method, because ultimately it should be shared by // ReadResponse and ReadRequest. -func fixLength(isResponse bool, status int, requestMethod string, header Header, te []string) (int64, error) { +func fixLength(isResponse bool, status int, requestMethod string, header Header, chunked bool) (int64, error) { isRequest := !isResponse contentLens := header["Content-Length"] @@ -677,9 +663,9 @@ func fixLength(isResponse bool, status int, requestMethod string, header Header, // Content-Length headers if they differ in value. // If there are dups of the value, remove the dups. // See Issue 16490. - first := strings.TrimSpace(contentLens[0]) + first := textproto.TrimString(contentLens[0]) for _, ct := range contentLens[1:] { - if first != strings.TrimSpace(ct) { + if first != textproto.TrimString(ct) { return 0, fmt.Errorf("http: message cannot contain multiple Content-Length headers; got %q", contentLens) } } @@ -711,14 +697,14 @@ func fixLength(isResponse bool, status int, requestMethod string, header Header, } // Logic based on Transfer-Encoding - if chunked(te) { + if chunked { return -1, nil } // Logic based on Content-Length var cl string if len(contentLens) == 1 { - cl = strings.TrimSpace(contentLens[0]) + cl = textproto.TrimString(contentLens[0]) } if cl != "" { n, err := parseContentLength(cl) @@ -766,12 +752,12 @@ func shouldClose(major, minor int, header Header, removeCloseHeader bool) bool { } // Parse the trailer header -func fixTrailer(header Header, te []string) (Header, error) { +func fixTrailer(header Header, chunked bool) (Header, error) { vv, ok := header["Trailer"] if !ok { return nil, nil } - if !chunked(te) { + if !chunked { // Trailer and no chunking: // this is an invalid use case for trailer header. // Nevertheless, no error will be returned and we @@ -791,7 +777,7 @@ func fixTrailer(header Header, te []string) (Header, error) { switch key { case "Transfer-Encoding", "Trailer", "Content-Length": if err == nil { - err = &badStringError{"bad trailer key", key} + err = badStringError("bad trailer key", key) return } } @@ -1049,15 +1035,15 @@ func (bl bodyLocked) Read(p []byte) (n int, err error) { // parseContentLength trims whitespace from s and returns -1 if no value // is set, or the value if it's >= 0. func parseContentLength(cl string) (int64, error) { - cl = strings.TrimSpace(cl) + cl = textproto.TrimString(cl) if cl == "" { return -1, nil } - n, err := strconv.ParseInt(cl, 10, 64) - if err != nil || n < 0 { - return 0, &badStringError{"bad Content-Length", cl} + n, err := strconv.ParseUint(cl, 10, 63) + if err != nil { + return 0, badStringError("bad Content-Length", cl) } - return n, nil + return int64(n), nil } @@ -1092,6 +1078,9 @@ func isKnownInMemoryReader(r io.Reader) bool { if reflect.TypeOf(r) == nopCloserType { return isKnownInMemoryReader(reflect.ValueOf(r).Field(0).Interface().(io.Reader)) } + if r, ok := r.(*readTrackingBody); ok { + return isKnownInMemoryReader(r.ReadCloser) + } return false } diff --git a/libgo/go/net/http/transfer_test.go b/libgo/go/net/http/transfer_test.go index 65009ee8bf7..185225fa931 100644 --- a/libgo/go/net/http/transfer_test.go +++ b/libgo/go/net/http/transfer_test.go @@ -279,7 +279,7 @@ func TestTransferWriterWriteBodyReaderTypes(t *testing.T) { } } -func TestFixTransferEncoding(t *testing.T) { +func TestParseTransferEncoding(t *testing.T) { tests := []struct { hdr Header wantErr error @@ -290,7 +290,23 @@ func TestFixTransferEncoding(t *testing.T) { }, { hdr: Header{"Transfer-Encoding": {"chunked, chunked", "identity", "chunked"}}, - wantErr: &badStringError{"too many transfer encodings", "chunked,chunked"}, + wantErr: &unsupportedTEError{`too many transfer encodings: ["chunked, chunked" "identity" "chunked"]`}, + }, + { + hdr: Header{"Transfer-Encoding": {""}}, + wantErr: &unsupportedTEError{`unsupported transfer encoding: ""`}, + }, + { + hdr: Header{"Transfer-Encoding": {"chunked, identity"}}, + wantErr: &unsupportedTEError{`unsupported transfer encoding: "chunked, identity"`}, + }, + { + hdr: Header{"Transfer-Encoding": {"chunked", "identity"}}, + wantErr: &unsupportedTEError{`too many transfer encodings: ["chunked" "identity"]`}, + }, + { + hdr: Header{"Transfer-Encoding": {"\x0bchunked"}}, + wantErr: &unsupportedTEError{`unsupported transfer encoding: "\vchunked"`}, }, { hdr: Header{"Transfer-Encoding": {"chunked"}}, @@ -304,9 +320,45 @@ func TestFixTransferEncoding(t *testing.T) { ProtoMajor: 1, ProtoMinor: 1, } - gotErr := tr.fixTransferEncoding() + gotErr := tr.parseTransferEncoding() if !reflect.DeepEqual(gotErr, tt.wantErr) { t.Errorf("%d.\ngot error:\n%v\nwant error:\n%v\n\n", i, gotErr, tt.wantErr) } } } + +// issue 39017 - disallow Content-Length values such as "+3" +func TestParseContentLength(t *testing.T) { + tests := []struct { + cl string + wantErr error + }{ + { + cl: "3", + wantErr: nil, + }, + { + cl: "+3", + wantErr: badStringError("bad Content-Length", "+3"), + }, + { + cl: "-3", + wantErr: badStringError("bad Content-Length", "-3"), + }, + { + // max int64, for safe conversion before returning + cl: "9223372036854775807", + wantErr: nil, + }, + { + cl: "9223372036854775808", + wantErr: badStringError("bad Content-Length", "9223372036854775808"), + }, + } + + for _, tt := range tests { + if _, gotErr := parseContentLength(tt.cl); !reflect.DeepEqual(gotErr, tt.wantErr) { + t.Errorf("%q:\n\tgot=%v\n\twant=%v", tt.cl, gotErr, tt.wantErr) + } + } +} diff --git a/libgo/go/net/http/transport.go b/libgo/go/net/http/transport.go index d0bfdb412cb..a41e732d983 100644 --- a/libgo/go/net/http/transport.go +++ b/libgo/go/net/http/transport.go @@ -511,14 +511,22 @@ func (t *Transport) roundTrip(req *Request) (*Response, error) { } } + origReq := req + req = setupRewindBody(req) + if altRT := t.alternateRoundTripper(req); altRT != nil { if resp, err := altRT.RoundTrip(req); err != ErrSkipAltProtocol { return resp, err } + var err error + req, err = rewindBody(req) + if err != nil { + return nil, err + } } if !isHTTP { req.closeBody() - return nil, &badStringError{"unsupported protocol scheme", scheme} + return nil, badStringError("unsupported protocol scheme", scheme) } if req.Method != "" && !validMethod(req.Method) { req.closeBody() @@ -565,18 +573,16 @@ func (t *Transport) roundTrip(req *Request) (*Response, error) { resp, err = pconn.roundTrip(treq) } if err == nil { + resp.Request = origReq return resp, nil } // Failed. Clean up and determine whether to retry. - - _, isH2DialError := pconn.alt.(http2erringRoundTripper) - if http2isNoCachedConnError(err) || isH2DialError { + if http2isNoCachedConnError(err) { if t.removeIdleConn(pconn) { t.decConnsPerHost(pconn.cacheKey) } - } - if !pconn.shouldRetryRequest(req, err) { + } else if !pconn.shouldRetryRequest(req, err) { // Issue 16465: return underlying net.Conn.Read error from peek, // as we've historically done. if e, ok := err.(transportReadFromServerError); ok { @@ -587,18 +593,59 @@ func (t *Transport) roundTrip(req *Request) (*Response, error) { testHookRoundTripRetried() // Rewind the body if we're able to. - if req.GetBody != nil { - newReq := *req - var err error - newReq.Body, err = req.GetBody() - if err != nil { - return nil, err - } - req = &newReq + req, err = rewindBody(req) + if err != nil { + return nil, err } } } +var errCannotRewind = errors.New("net/http: cannot rewind body after connection loss") + +type readTrackingBody struct { + io.ReadCloser + didRead bool +} + +func (r *readTrackingBody) Read(data []byte) (int, error) { + r.didRead = true + return r.ReadCloser.Read(data) +} + +// setupRewindBody returns a new request with a custom body wrapper +// that can report whether the body needs rewinding. +// This lets rewindBody avoid an error result when the request +// does not have GetBody but the body hasn't been read at all yet. +func setupRewindBody(req *Request) *Request { + if req.Body == nil || req.Body == NoBody { + return req + } + newReq := *req + newReq.Body = &readTrackingBody{ReadCloser: req.Body} + return &newReq +} + +// rewindBody returns a new request with the body rewound. +// It returns req unmodified if the body does not need rewinding. +// rewindBody takes care of closing req.Body when appropriate +// (in all cases except when rewindBody returns req unmodified). +func rewindBody(req *Request) (rewound *Request, err error) { + if req.Body == nil || req.Body == NoBody || !req.Body.(*readTrackingBody).didRead { + return req, nil // nothing to rewind + } + req.closeBody() + if req.GetBody == nil { + return nil, errCannotRewind + } + body, err := req.GetBody() + if err != nil { + return nil, err + } + newReq := *req + newReq.Body = &readTrackingBody{ReadCloser: body} + return &newReq, nil +} + // shouldRetryRequest reports whether we should retry sending a failed // HTTP request on a new connection. The non-nil input error is the // error from roundTrip. @@ -846,7 +893,7 @@ func (t *Transport) tryPutIdleConn(pconn *persistConn) error { // Deliver pconn to goroutine waiting for idle connection, if any. // (They may be actively dialing, but this conn is ready first. // Chrome calls this socket late binding. - // See https://insouciant.org/tech/connection-management-in-chromium/.) + // See https://www.chromium.org/developers/design-documents/network-stack#TOC-Connection-Management.) key := pconn.cacheKey if q, ok := t.idleConnWait[key]; ok { done := false @@ -1637,7 +1684,12 @@ func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (pconn *pers if s := pconn.tlsState; s != nil && s.NegotiatedProtocolIsMutual && s.NegotiatedProtocol != "" { if next, ok := t.TLSNextProto[s.NegotiatedProtocol]; ok { - return &persistConn{t: t, cacheKey: pconn.cacheKey, alt: next(cm.targetAddr, pconn.conn.(*tls.Conn))}, nil + alt := next(cm.targetAddr, pconn.conn.(*tls.Conn)) + if e, ok := alt.(http2erringRoundTripper); ok { + // pconn.conn was closed by next (http2configureTransport.upgradeFn). + return nil, e.err + } + return &persistConn{t: t, cacheKey: pconn.cacheKey, alt: alt}, nil } } @@ -1694,6 +1746,7 @@ var _ io.ReaderFrom = (*persistConnWriter)(nil) // https://proxy.com|http https to proxy, http to anywhere after that // type connectMethod struct { + _ incomparable proxyURL *url.URL // nil for no proxy, else full proxy URL targetScheme string // "http" or "https" // If proxyURL specifies an http or https proxy, and targetScheme is http (not https), @@ -2248,6 +2301,7 @@ func newReadWriteCloserBody(br *bufio.Reader, rwc io.ReadWriteCloser) io.ReadWri // the concrete type for a Response.Body on the 101 Switching // Protocols response, as used by WebSockets, h2c, etc. type readWriteCloserBody struct { + _ incomparable br *bufio.Reader // used until empty io.ReadWriteCloser } @@ -2348,11 +2402,13 @@ func (pc *persistConn) wroteRequest() bool { // responseAndError is how the goroutine reading from an HTTP/1 server // communicates with the goroutine doing the RoundTrip. type responseAndError struct { + _ incomparable res *Response // else use this response (see res method) err error } type requestAndChan struct { + _ incomparable req *Request ch chan responseAndError // unbuffered; always send in select on callerGone @@ -2685,6 +2741,7 @@ func (es *bodyEOFSignal) condfn(err error) error { // gzipReader wraps a response body so it can lazily // call gzip.NewReader on the first call to Read type gzipReader struct { + _ incomparable body *bodyEOFSignal // underlying HTTP/1 response body framing zr *gzip.Reader // lazily-initialized gzip reader zerr error // any error from gzip.NewReader; sticky diff --git a/libgo/go/net/http/transport_test.go b/libgo/go/net/http/transport_test.go index 1e0334d2eb2..7153e3c7397 100644 --- a/libgo/go/net/http/transport_test.go +++ b/libgo/go/net/http/transport_test.go @@ -451,14 +451,23 @@ func TestTransportReadToEndReusesConn(t *testing.T) { func TestTransportMaxPerHostIdleConns(t *testing.T) { defer afterTest(t) + stop := make(chan struct{}) // stop marks the exit of main Test goroutine + defer close(stop) + resch := make(chan string) gotReq := make(chan bool) ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { gotReq <- true - msg := <-resch + var msg string + select { + case <-stop: + return + case msg = <-resch: + } _, err := w.Write([]byte(msg)) if err != nil { - t.Fatalf("Write: %v", err) + t.Errorf("Write: %v", err) + return } })) defer ts.Close() @@ -472,6 +481,13 @@ func TestTransportMaxPerHostIdleConns(t *testing.T) { // Their responses will hang until we write to resch, though. donech := make(chan bool) doReq := func() { + defer func() { + select { + case <-stop: + return + case donech <- t.Failed(): + } + }() resp, err := c.Get(ts.URL) if err != nil { t.Error(err) @@ -481,7 +497,6 @@ func TestTransportMaxPerHostIdleConns(t *testing.T) { t.Errorf("ReadAll: %v", err) return } - donech <- true } go doReq() <-gotReq @@ -842,7 +857,9 @@ func TestStressSurpriseServerCloses(t *testing.T) { // where we won the race. res.Body.Close() } - activityc <- true + if !<-activityc { // Receives false when close(activityc) is executed + return + } } }() } @@ -850,8 +867,9 @@ func TestStressSurpriseServerCloses(t *testing.T) { // Make sure all the request come back, one way or another. for i := 0; i < numClients*reqsPerClient; i++ { select { - case <-activityc: + case activityc <- true: case <-time.After(5 * time.Second): + close(activityc) t.Fatalf("presumed deadlock; no HTTP client activity seen in awhile") } } @@ -2365,7 +2383,9 @@ func TestTransportCancelRequestInDial(t *testing.T) { tr := &Transport{ Dial: func(network, addr string) (net.Conn, error) { eventLog.Println("dial: blocking") - inDial <- true + if !<-inDial { + return nil, errors.New("main Test goroutine exited") + } <-unblockDial return nil, errors.New("nope") }, @@ -2380,8 +2400,9 @@ func TestTransportCancelRequestInDial(t *testing.T) { }() select { - case <-inDial: + case inDial <- true: case <-time.After(5 * time.Second): + close(inDial) t.Fatal("timeout; never saw blocking dial") } @@ -3494,7 +3515,8 @@ func TestRetryRequestsOnError(t *testing.T) { for i := 0; i < 3; i++ { t0 := time.Now() - res, err := c.Do(tc.req()) + req := tc.req() + res, err := c.Do(req) if err != nil { if time.Since(t0) < MaxWriteWaitBeforeConnReuse/2 { mu.Lock() @@ -3505,6 +3527,9 @@ func TestRetryRequestsOnError(t *testing.T) { t.Skipf("connection likely wasn't recycled within %d, interfering with actual test; skipping", MaxWriteWaitBeforeConnReuse) } res.Body.Close() + if res.Request != req { + t.Errorf("Response.Request != original request; want identical Request") + } } mu.Lock() @@ -6179,3 +6204,48 @@ func (timeoutProto) RoundTrip(req *Request) (*Response, error) { return nil, errors.New("request was not canceled") } } + +type roundTripFunc func(r *Request) (*Response, error) + +func (f roundTripFunc) RoundTrip(r *Request) (*Response, error) { return f(r) } + +// Issue 32441: body is not reset after ErrSkipAltProtocol +func TestIssue32441(t *testing.T) { + defer afterTest(t) + ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { + if n, _ := io.Copy(ioutil.Discard, r.Body); n == 0 { + t.Error("body length is zero") + } + })) + defer ts.Close() + c := ts.Client() + c.Transport.(*Transport).RegisterProtocol("http", roundTripFunc(func(r *Request) (*Response, error) { + // Draining body to trigger failure condition on actual request to server. + if n, _ := io.Copy(ioutil.Discard, r.Body); n == 0 { + t.Error("body length is zero during round trip") + } + return nil, ErrSkipAltProtocol + })) + if _, err := c.Post(ts.URL, "application/octet-stream", bytes.NewBufferString("data")); err != nil { + t.Error(err) + } +} + +// Issue 39017. Ensure that HTTP/1 transports reject Content-Length headers +// that contain a sign (eg. "+3"), per RFC 2616, Section 14.13. +func TestTransportRejectsSignInContentLength(t *testing.T) { + cst := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { + w.Header().Set("Content-Length", "+3") + w.Write([]byte("abc")) + })) + defer cst.Close() + + c := cst.Client() + res, err := c.Get(cst.URL) + if err == nil || res != nil { + t.Fatal("Expected a non-nil error and a nil http.Response") + } + if got, want := err.Error(), `bad Content-Length "+3"`; !strings.Contains(got, want) { + t.Fatalf("Error mismatch\nGot: %q\nWanted substring: %q", got, want) + } +} diff --git a/libgo/go/net/interface_plan9.go b/libgo/go/net/interface_plan9.go index 1295017a1b9..31bbaca4675 100644 --- a/libgo/go/net/interface_plan9.go +++ b/libgo/go/net/interface_plan9.go @@ -68,8 +68,8 @@ func readInterface(i int) (*Interface, error) { } ifc.MTU = mtu - // Not a loopback device - if device != "/dev/null" { + // Not a loopback device ("/dev/null") or packet interface (e.g. "pkt2") + if stringsHasPrefix(device, netdir+"/") { deviceaddrf, err := open(device + "/addr") if err != nil { return nil, err diff --git a/libgo/go/net/interface_windows.go b/libgo/go/net/interface_windows.go index 544943278dc..30e90b83c19 100644 --- a/libgo/go/net/interface_windows.go +++ b/libgo/go/net/interface_windows.go @@ -58,7 +58,7 @@ func interfaceTable(ifindex int) ([]Interface, error) { if ifindex == 0 || ifindex == int(index) { ifi := Interface{ Index: int(index), - Name: windows.UTF16PtrToString(aa.FriendlyName, 10000), + Name: windows.UTF16PtrToString(aa.FriendlyName), } if aa.OperStatus == windows.IfOperStatusUp { ifi.Flags |= FlagUp diff --git a/libgo/go/net/ip.go b/libgo/go/net/ip.go index 9d1223e705e..c00fe8ed3cc 100644 --- a/libgo/go/net/ip.go +++ b/libgo/go/net/ip.go @@ -671,8 +671,8 @@ func parseIPv6(s string) (ip IP) { } // ParseIP parses s as an IP address, returning the result. -// The string s can be in dotted decimal ("192.0.2.1") -// or IPv6 ("2001:db8::68") form. +// The string s can be in IPv4 dotted decimal ("192.0.2.1"), IPv6 +// ("2001:db8::68"), or IPv4-mapped IPv6 ("::ffff:192.0.2.1") form. // If s is not a valid textual representation of an IP address, // ParseIP returns nil. func ParseIP(s string) IP { diff --git a/libgo/go/net/ipsock_plan9.go b/libgo/go/net/ipsock_plan9.go index 93f0f4eec36..23082366aac 100644 --- a/libgo/go/net/ipsock_plan9.go +++ b/libgo/go/net/ipsock_plan9.go @@ -57,17 +57,17 @@ func parsePlan9Addr(s string) (ip IP, iport int, err error) { return nil, 0, &ParseError{Type: "IP address", Text: s} } } - p, _, ok := dtoi(s[i+1:]) + p, plen, ok := dtoi(s[i+1:]) if !ok { return nil, 0, &ParseError{Type: "port", Text: s} } if p < 0 || p > 0xFFFF { - return nil, 0, &AddrError{Err: "invalid port", Addr: string(p)} + return nil, 0, &AddrError{Err: "invalid port", Addr: s[i+1 : i+1+plen]} } return addr, p, nil } -func readPlan9Addr(proto, filename string) (addr Addr, err error) { +func readPlan9Addr(net, filename string) (addr Addr, err error) { var buf [128]byte f, err := os.Open(filename) @@ -83,13 +83,19 @@ func readPlan9Addr(proto, filename string) (addr Addr, err error) { if err != nil { return } - switch proto { - case "tcp": + switch net { + case "tcp4", "udp4": + if ip.Equal(IPv6zero) { + ip = ip[:IPv4len] + } + } + switch net { + case "tcp", "tcp4", "tcp6": addr = &TCPAddr{IP: ip, Port: port} - case "udp": + case "udp", "udp4", "udp6": addr = &UDPAddr{IP: ip, Port: port} default: - return nil, UnknownNetworkError(proto) + return nil, UnknownNetworkError(net) } return addr, nil } @@ -199,7 +205,11 @@ func dialPlan9Blocking(ctx context.Context, net string, laddr, raddr Addr) (fd * if err != nil { return nil, err } - _, err = f.WriteString("connect " + dest) + if la := plan9LocalAddr(laddr); la == "" { + err = hangupCtlWrite(ctx, proto, f, "connect "+dest) + } else { + err = hangupCtlWrite(ctx, proto, f, "connect "+dest+" "+la) + } if err != nil { f.Close() return nil, err @@ -209,7 +219,7 @@ func dialPlan9Blocking(ctx context.Context, net string, laddr, raddr Addr) (fd * f.Close() return nil, err } - laddr, err = readPlan9Addr(proto, netdir+"/"+proto+"/"+name+"/local") + laddr, err = readPlan9Addr(net, netdir+"/"+proto+"/"+name+"/local") if err != nil { data.Close() f.Close() @@ -229,7 +239,7 @@ func listenPlan9(ctx context.Context, net string, laddr Addr) (fd *netFD, err er f.Close() return nil, &OpError{Op: "announce", Net: net, Source: laddr, Addr: nil, Err: err} } - laddr, err = readPlan9Addr(proto, netdir+"/"+proto+"/"+name+"/local") + laddr, err = readPlan9Addr(net, netdir+"/"+proto+"/"+name+"/local") if err != nil { f.Close() return nil, err @@ -303,3 +313,53 @@ func toLocal(a Addr, net string) Addr { } return a } + +// plan9LocalAddr returns a Plan 9 local address string. +// See setladdrport at https://9p.io/sources/plan9/sys/src/9/ip/devip.c. +func plan9LocalAddr(addr Addr) string { + var ip IP + port := 0 + switch a := addr.(type) { + case *TCPAddr: + if a != nil { + ip = a.IP + port = a.Port + } + case *UDPAddr: + if a != nil { + ip = a.IP + port = a.Port + } + } + if len(ip) == 0 || ip.IsUnspecified() { + if port == 0 { + return "" + } + return itoa(port) + } + return ip.String() + "!" + itoa(port) +} + +func hangupCtlWrite(ctx context.Context, proto string, ctl *os.File, msg string) error { + if proto != "tcp" { + _, err := ctl.WriteString(msg) + return err + } + written := make(chan struct{}) + errc := make(chan error) + go func() { + select { + case <-ctx.Done(): + ctl.WriteString("hangup") + errc <- mapErr(ctx.Err()) + case <-written: + errc <- nil + } + }() + _, err := ctl.WriteString(msg) + close(written) + if e := <-errc; err == nil && e != nil { // we hung up + return e + } + return err +} diff --git a/libgo/go/net/ipsock_plan9_test.go b/libgo/go/net/ipsock_plan9_test.go new file mode 100644 index 00000000000..e5fb9ff965d --- /dev/null +++ b/libgo/go/net/ipsock_plan9_test.go @@ -0,0 +1,29 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package net + +import "testing" + +func TestTCP4ListenZero(t *testing.T) { + l, err := Listen("tcp4", "0.0.0.0:0") + if err != nil { + t.Fatal(err) + } + defer l.Close() + if a := l.Addr(); isNotIPv4(a) { + t.Errorf("address does not contain IPv4: %v", a) + } +} + +func TestUDP4ListenZero(t *testing.T) { + c, err := ListenPacket("udp4", "0.0.0.0:0") + if err != nil { + t.Fatal(err) + } + defer c.Close() + if a := c.LocalAddr(); isNotIPv4(a) { + t.Errorf("address does not contain IPv4: %v", a) + } +} diff --git a/libgo/go/net/lookup.go b/libgo/go/net/lookup.go index 9cebd10c87a..5f7119872a4 100644 --- a/libgo/go/net/lookup.go +++ b/libgo/go/net/lookup.go @@ -204,6 +204,31 @@ func (r *Resolver) LookupIPAddr(ctx context.Context, host string) ([]IPAddr, err return r.lookupIPAddr(ctx, "ip", host) } +// LookupIP looks up host for the given network using the local resolver. +// It returns a slice of that host's IP addresses of the type specified by +// network. +// network must be one of "ip", "ip4" or "ip6". +func (r *Resolver) LookupIP(ctx context.Context, network, host string) ([]IP, error) { + afnet, _, err := parseNetwork(ctx, network, false) + if err != nil { + return nil, err + } + switch afnet { + case "ip", "ip4", "ip6": + default: + return nil, UnknownNetworkError(network) + } + addrs, err := r.internetAddrList(ctx, afnet, host) + if err != nil { + return nil, err + } + ips := make([]IP, 0, len(addrs)) + for _, addr := range addrs { + ips = append(ips, addr.(*IPAddr).IP) + } + return ips, nil +} + // onlyValuesCtx is a context that uses an underlying context // for value lookup if the underlying context hasn't yet expired. type onlyValuesCtx struct { diff --git a/libgo/go/net/lookup_test.go b/libgo/go/net/lookup_test.go index 2bc5592d5ad..68bffcab8fb 100644 --- a/libgo/go/net/lookup_test.go +++ b/libgo/go/net/lookup_test.go @@ -74,7 +74,7 @@ func TestLookupGoogleSRV(t *testing.T) { t.Parallel() mustHaveExternalNetwork(t) - if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { + if iOS() { t.Skip("no resolv.conf on iOS") } @@ -123,7 +123,7 @@ func TestLookupGmailMX(t *testing.T) { t.Parallel() mustHaveExternalNetwork(t) - if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { + if iOS() { t.Skip("no resolv.conf on iOS") } @@ -169,7 +169,7 @@ func TestLookupGmailNS(t *testing.T) { t.Parallel() mustHaveExternalNetwork(t) - if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { + if iOS() { t.Skip("no resolv.conf on iOS") } @@ -218,7 +218,7 @@ func TestLookupGmailTXT(t *testing.T) { t.Parallel() mustHaveExternalNetwork(t) - if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { + if iOS() { t.Skip("no resolv.conf on iOS") } @@ -637,7 +637,7 @@ func TestLookupDotsWithRemoteSource(t *testing.T) { t.Skip("IPv4 is required") } - if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { + if iOS() { t.Skip("no resolv.conf on iOS") } @@ -913,6 +913,7 @@ func TestNilResolverLookup(t *testing.T) { r.LookupCNAME(ctx, "google.com") r.LookupHost(ctx, "google.com") r.LookupIPAddr(ctx, "google.com") + r.LookupIP(ctx, "ip", "google.com") r.LookupMX(ctx, "gmail.com") r.LookupNS(ctx, "google.com") r.LookupPort(ctx, "tcp", "smtp") @@ -1185,3 +1186,83 @@ func TestLookupNullByte(t *testing.T) { testenv.SkipFlakyNet(t) LookupHost("foo\x00bar") // check that it doesn't panic; it used to on Windows } + +func TestResolverLookupIP(t *testing.T) { + testenv.MustHaveExternalNetwork(t) + + v4Ok := supportsIPv4() && *testIPv4 + v6Ok := supportsIPv6() && *testIPv6 + + defer dnsWaitGroup.Wait() + + for _, impl := range []struct { + name string + fn func() func() + }{ + {"go", forceGoDNS}, + {"cgo", forceCgoDNS}, + } { + t.Run("implementation: "+impl.name, func(t *testing.T) { + fixup := impl.fn() + if fixup == nil { + t.Skip("not supported") + } + defer fixup() + + for _, network := range []string{"ip", "ip4", "ip6"} { + t.Run("network: "+network, func(t *testing.T) { + switch { + case network == "ip4" && !v4Ok: + t.Skip("IPv4 is not supported") + case network == "ip6" && !v6Ok: + t.Skip("IPv6 is not supported") + } + + // google.com has both A and AAAA records. + const host = "google.com" + ips, err := DefaultResolver.LookupIP(context.Background(), network, host) + if err != nil { + testenv.SkipFlakyNet(t) + t.Fatalf("DefaultResolver.LookupIP(%q, %q): failed with unexpected error: %v", network, host, err) + } + + var v4Addrs []IP + var v6Addrs []IP + for _, ip := range ips { + switch { + case ip.To4() != nil: + // We need to skip the test below because To16 will + // convent an IPv4 address to an IPv4-mapped IPv6 + // address. + v4Addrs = append(v4Addrs, ip) + case ip.To16() != nil: + v6Addrs = append(v6Addrs, ip) + default: + t.Fatalf("IP=%q is neither IPv4 nor IPv6", ip) + } + } + + // Check that we got the expected addresses. + if network == "ip4" || network == "ip" && v4Ok { + if len(v4Addrs) == 0 { + t.Errorf("DefaultResolver.LookupIP(%q, %q): no IPv4 addresses", network, host) + } + } + if network == "ip6" || network == "ip" && v6Ok { + if len(v6Addrs) == 0 { + t.Errorf("DefaultResolver.LookupIP(%q, %q): no IPv6 addresses", network, host) + } + } + + // Check that we didn't get any unexpected addresses. + if network == "ip6" && len(v4Addrs) > 0 { + t.Errorf("DefaultResolver.LookupIP(%q, %q): unexpected IPv4 addresses: %v", network, host, v4Addrs) + } + if network == "ip4" && len(v6Addrs) > 0 { + t.Errorf("DefaultResolver.LookupIP(%q, %q): unexpected IPv6 addresses: %v", network, host, v6Addrs) + } + }) + } + }) + } +} diff --git a/libgo/go/net/lookup_windows.go b/libgo/go/net/lookup_windows.go index 7d5c9419566..bb34a081336 100644 --- a/libgo/go/net/lookup_windows.go +++ b/libgo/go/net/lookup_windows.go @@ -234,7 +234,7 @@ func (*Resolver) lookupCNAME(ctx context.Context, name string) (string, error) { defer syscall.DnsRecordListFree(r, 1) resolved := resolveCNAME(syscall.StringToUTF16Ptr(name), r) - cname := windows.UTF16PtrToString(resolved, 256) + cname := windows.UTF16PtrToString(resolved) return absDomainName([]byte(cname)), nil } @@ -278,7 +278,7 @@ func (*Resolver) lookupMX(ctx context.Context, name string) ([]*MX, error) { mxs := make([]*MX, 0, 10) for _, p := range validRecs(r, syscall.DNS_TYPE_MX, name) { v := (*syscall.DNSMXData)(unsafe.Pointer(&p.Data[0])) - mxs = append(mxs, &MX{absDomainName([]byte(windows.UTF16PtrToString(v.NameExchange, 256))), v.Preference}) + mxs = append(mxs, &MX{absDomainName([]byte(windows.UTF16PtrToString(v.NameExchange))), v.Preference}) } byPref(mxs).sort() return mxs, nil @@ -319,7 +319,7 @@ func (*Resolver) lookupTXT(ctx context.Context, name string) ([]string, error) { d := (*syscall.DNSTXTData)(unsafe.Pointer(&p.Data[0])) s := "" for _, v := range (*[1 << 10]*uint16)(unsafe.Pointer(&(d.StringArray[0])))[:d.StringCount:d.StringCount] { - s += windows.UTF16PtrToString(v, 1<<20) + s += windows.UTF16PtrToString(v) } txts = append(txts, s) } @@ -344,7 +344,7 @@ func (*Resolver) lookupAddr(ctx context.Context, addr string) ([]string, error) ptrs := make([]string, 0, 10) for _, p := range validRecs(r, syscall.DNS_TYPE_PTR, arpa) { v := (*syscall.DNSPTRData)(unsafe.Pointer(&p.Data[0])) - ptrs = append(ptrs, absDomainName([]byte(windows.UTF16PtrToString(v.Host, 256)))) + ptrs = append(ptrs, absDomainName([]byte(windows.UTF16PtrToString(v.Host)))) } return ptrs, nil } diff --git a/libgo/go/net/mail/message.go b/libgo/go/net/mail/message.go index 0781310ed3f..6833cfaec11 100644 --- a/libgo/go/net/mail/message.go +++ b/libgo/go/net/mail/message.go @@ -274,6 +274,15 @@ func (p *addrParser) parseAddressList() ([]*Address, error) { var list []*Address for { p.skipSpace() + + // allow skipping empty entries (RFC5322 obs-addr-list) + if p.consume(',') { + continue + } + if p.empty() { + break + } + addrs, err := p.parseAddress(true) if err != nil { return nil, err diff --git a/libgo/go/net/mail/message_test.go b/libgo/go/net/mail/message_test.go index acab538e18b..75db7675473 100644 --- a/libgo/go/net/mail/message_test.go +++ b/libgo/go/net/mail/message_test.go @@ -431,6 +431,20 @@ func TestAddressParsing(t *testing.T) { }, }, }, + // RFC5322 4.4 obs-addr-list + { + ` , joe@where.test,,John ,`, + []*Address{ + { + Name: "", + Address: "joe@where.test", + }, + { + Name: "John", + Address: "jdoe@one.test", + }, + }, + }, { `Group1: ;, Group 2: addr2@example.com;, John `, []*Address{ diff --git a/libgo/go/net/net.go b/libgo/go/net/net.go index 1d7e5e7f652..2e61a7c02e0 100644 --- a/libgo/go/net/net.go +++ b/libgo/go/net/net.go @@ -81,7 +81,6 @@ package net import ( "context" "errors" - "internal/poll" "io" "os" "sync" @@ -112,13 +111,13 @@ type Addr interface { // Multiple goroutines may invoke methods on a Conn simultaneously. type Conn interface { // Read reads data from the connection. - // Read can be made to time out and return an Error with Timeout() == true - // after a fixed time limit; see SetDeadline and SetReadDeadline. + // Read can be made to time out and return an error after a fixed + // time limit; see SetDeadline and SetReadDeadline. Read(b []byte) (n int, err error) // Write writes data to the connection. - // Write can be made to time out and return an Error with Timeout() == true - // after a fixed time limit; see SetDeadline and SetWriteDeadline. + // Write can be made to time out and return an error after a fixed + // time limit; see SetDeadline and SetWriteDeadline. Write(b []byte) (n int, err error) // Close closes the connection. @@ -136,23 +135,22 @@ type Conn interface { // SetReadDeadline and SetWriteDeadline. // // A deadline is an absolute time after which I/O operations - // fail with a timeout (see type Error) instead of - // blocking. The deadline applies to all future and pending - // I/O, not just the immediately following call to Read or - // Write. After a deadline has been exceeded, the connection - // can be refreshed by setting a deadline in the future. + // fail instead of blocking. The deadline applies to all future + // and pending I/O, not just the immediately following call to + // Read or Write. After a deadline has been exceeded, the + // connection can be refreshed by setting a deadline in the future. + // + // If the deadline is exceeded a call to Read or Write or to other + // I/O methods will return an error that wraps os.ErrDeadlineExceeded. + // This can be tested using errors.Is(err, os.ErrDeadlineExceeded). + // The error's Timeout method will return true, but note that there + // are other possible errors for which the Timeout method will + // return true even if the deadline has not been exceeded. // // An idle timeout can be implemented by repeatedly extending // the deadline after successful Read or Write calls. // // A zero value for t means I/O operations will not time out. - // - // Note that if a TCP connection has keep-alive turned on, - // which is the default unless overridden by Dialer.KeepAlive - // or ListenConfig.KeepAlive, then a keep-alive failure may - // also return a timeout error. On Unix systems a keep-alive - // failure on I/O can be detected using - // errors.Is(err, syscall.ETIMEDOUT). SetDeadline(t time.Time) error // SetReadDeadline sets the deadline for future Read calls @@ -315,15 +313,13 @@ type PacketConn interface { // It returns the number of bytes read (0 <= n <= len(p)) // and any error encountered. Callers should always process // the n > 0 bytes returned before considering the error err. - // ReadFrom can be made to time out and return - // an Error with Timeout() == true after a fixed time limit; - // see SetDeadline and SetReadDeadline. + // ReadFrom can be made to time out and return an error after a + // fixed time limit; see SetDeadline and SetReadDeadline. ReadFrom(p []byte) (n int, addr Addr, err error) // WriteTo writes a packet with payload p to addr. - // WriteTo can be made to time out and return - // an Error with Timeout() == true after a fixed time limit; - // see SetDeadline and SetWriteDeadline. + // WriteTo can be made to time out and return an Error after a + // fixed time limit; see SetDeadline and SetWriteDeadline. // On packet-oriented connections, write timeouts are rare. WriteTo(p []byte, addr Addr) (n int, err error) @@ -339,11 +335,17 @@ type PacketConn interface { // SetReadDeadline and SetWriteDeadline. // // A deadline is an absolute time after which I/O operations - // fail with a timeout (see type Error) instead of - // blocking. The deadline applies to all future and pending - // I/O, not just the immediately following call to ReadFrom or - // WriteTo. After a deadline has been exceeded, the connection - // can be refreshed by setting a deadline in the future. + // fail instead of blocking. The deadline applies to all future + // and pending I/O, not just the immediately following call to + // Read or Write. After a deadline has been exceeded, the + // connection can be refreshed by setting a deadline in the future. + // + // If the deadline is exceeded a call to Read or Write or to other + // I/O methods will return an error that wraps os.ErrDeadlineExceeded. + // This can be tested using errors.Is(err, os.ErrDeadlineExceeded). + // The error's Timeout method will return true, but note that there + // are other possible errors for which the Timeout method will + // return true even if the deadline has not been exceeded. // // An idle timeout can be implemented by repeatedly extending // the deadline after successful ReadFrom or WriteTo calls. @@ -420,7 +422,7 @@ func mapErr(err error) error { case context.Canceled: return errCanceled case context.DeadlineExceeded: - return poll.ErrTimeout + return errTimeout default: return err } @@ -567,6 +569,21 @@ func (e InvalidAddrError) Error() string { return string(e) } func (e InvalidAddrError) Timeout() bool { return false } func (e InvalidAddrError) Temporary() bool { return false } +// errTimeout exists to return the historical "i/o timeout" string +// for context.DeadlineExceeded. See mapErr. +// It is also used when Dialer.Deadline is exceeded. +// +// TODO(iant): We could consider changing this to os.ErrDeadlineExceeded +// in the future, but note that that would conflict with the TODO +// at mapErr that suggests changing it to context.DeadlineExceeded. +var errTimeout error = &timeoutError{} + +type timeoutError struct{} + +func (e *timeoutError) Error() string { return "i/o timeout" } +func (e *timeoutError) Timeout() bool { return true } +func (e *timeoutError) Temporary() bool { return true } + // DNSConfigError represents an error reading the machine's DNS configuration. // (No longer used; kept for compatibility.) type DNSConfigError struct { diff --git a/libgo/go/net/net_test.go b/libgo/go/net/net_test.go index a7406740f52..409e1400af9 100644 --- a/libgo/go/net/net_test.go +++ b/libgo/go/net/net_test.go @@ -23,50 +23,54 @@ func TestCloseRead(t *testing.T) { case "plan9": t.Skipf("not supported on %s", runtime.GOOS) } + t.Parallel() for _, network := range []string{"tcp", "unix", "unixpacket"} { - if !testableNetwork(network) { - t.Logf("skipping %s test", network) - continue - } + network := network + t.Run(network, func(t *testing.T) { + if !testableNetwork(network) { + t.Skipf("network %s is not testable on the current platform", network) + } + t.Parallel() - ln, err := newLocalListener(network) - if err != nil { - t.Fatal(err) - } - switch network { - case "unix", "unixpacket": - defer os.Remove(ln.Addr().String()) - } - defer ln.Close() + ln, err := newLocalListener(network) + if err != nil { + t.Fatal(err) + } + switch network { + case "unix", "unixpacket": + defer os.Remove(ln.Addr().String()) + } + defer ln.Close() - c, err := Dial(ln.Addr().Network(), ln.Addr().String()) - if err != nil { - t.Fatal(err) - } - switch network { - case "unix", "unixpacket": - defer os.Remove(c.LocalAddr().String()) - } - defer c.Close() + c, err := Dial(ln.Addr().Network(), ln.Addr().String()) + if err != nil { + t.Fatal(err) + } + switch network { + case "unix", "unixpacket": + defer os.Remove(c.LocalAddr().String()) + } + defer c.Close() - switch c := c.(type) { - case *TCPConn: - err = c.CloseRead() - case *UnixConn: - err = c.CloseRead() - } - if err != nil { - if perr := parseCloseError(err, true); perr != nil { - t.Error(perr) + switch c := c.(type) { + case *TCPConn: + err = c.CloseRead() + case *UnixConn: + err = c.CloseRead() } - t.Fatal(err) - } - var b [1]byte - n, err := c.Read(b[:]) - if n != 0 || err == nil { - t.Fatalf("got (%d, %v); want (0, error)", n, err) - } + if err != nil { + if perr := parseCloseError(err, true); perr != nil { + t.Error(perr) + } + t.Fatal(err) + } + var b [1]byte + n, err := c.Read(b[:]) + if n != 0 || err == nil { + t.Fatalf("got (%d, %v); want (0, error)", n, err) + } + }) } } @@ -76,212 +80,240 @@ func TestCloseWrite(t *testing.T) { t.Skipf("not supported on %s", runtime.GOOS) } - handler := func(ls *localServer, ln Listener) { - c, err := ln.Accept() - if err != nil { - t.Error(err) - return - } - defer c.Close() - - var b [1]byte - n, err := c.Read(b[:]) - if n != 0 || err != io.EOF { - t.Errorf("got (%d, %v); want (0, io.EOF)", n, err) - return - } - switch c := c.(type) { - case *TCPConn: - err = c.CloseWrite() - case *UnixConn: - err = c.CloseWrite() - } - if err != nil { - if perr := parseCloseError(err, true); perr != nil { - t.Error(perr) - } - t.Error(err) - return - } - n, err = c.Write(b[:]) - if err == nil { - t.Errorf("got (%d, %v); want (any, error)", n, err) - return - } + t.Parallel() + deadline, _ := t.Deadline() + if !deadline.IsZero() { + // Leave 10% headroom on the deadline to report errors and clean up. + deadline = deadline.Add(-time.Until(deadline) / 10) } for _, network := range []string{"tcp", "unix", "unixpacket"} { - if !testableNetwork(network) { - t.Logf("skipping %s test", network) - continue - } + network := network + t.Run(network, func(t *testing.T) { + if !testableNetwork(network) { + t.Skipf("network %s is not testable on the current platform", network) + } + t.Parallel() + + handler := func(ls *localServer, ln Listener) { + c, err := ln.Accept() + if err != nil { + t.Error(err) + return + } + if !deadline.IsZero() { + c.SetDeadline(deadline) + } + defer c.Close() + + var b [1]byte + n, err := c.Read(b[:]) + if n != 0 || err != io.EOF { + t.Errorf("got (%d, %v); want (0, io.EOF)", n, err) + return + } + switch c := c.(type) { + case *TCPConn: + err = c.CloseWrite() + case *UnixConn: + err = c.CloseWrite() + } + if err != nil { + if perr := parseCloseError(err, true); perr != nil { + t.Error(perr) + } + t.Error(err) + return + } + n, err = c.Write(b[:]) + if err == nil { + t.Errorf("got (%d, %v); want (any, error)", n, err) + return + } + } - ls, err := newLocalServer(network) - if err != nil { - t.Fatal(err) - } - defer ls.teardown() - if err := ls.buildup(handler); err != nil { - t.Fatal(err) - } + ls, err := newLocalServer(network) + if err != nil { + t.Fatal(err) + } + defer ls.teardown() + if err := ls.buildup(handler); err != nil { + t.Fatal(err) + } - c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String()) - if err != nil { - t.Fatal(err) - } - switch network { - case "unix", "unixpacket": - defer os.Remove(c.LocalAddr().String()) - } - defer c.Close() + c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String()) + if err != nil { + t.Fatal(err) + } + if !deadline.IsZero() { + c.SetDeadline(deadline) + } + switch network { + case "unix", "unixpacket": + defer os.Remove(c.LocalAddr().String()) + } + defer c.Close() - switch c := c.(type) { - case *TCPConn: - err = c.CloseWrite() - case *UnixConn: - err = c.CloseWrite() - } - if err != nil { - if perr := parseCloseError(err, true); perr != nil { - t.Error(perr) + switch c := c.(type) { + case *TCPConn: + err = c.CloseWrite() + case *UnixConn: + err = c.CloseWrite() } - t.Fatal(err) - } - var b [1]byte - n, err := c.Read(b[:]) - if n != 0 || err != io.EOF { - t.Fatalf("got (%d, %v); want (0, io.EOF)", n, err) - } - n, err = c.Write(b[:]) - if err == nil { - t.Fatalf("got (%d, %v); want (any, error)", n, err) - } + if err != nil { + if perr := parseCloseError(err, true); perr != nil { + t.Error(perr) + } + t.Fatal(err) + } + var b [1]byte + n, err := c.Read(b[:]) + if n != 0 || err != io.EOF { + t.Fatalf("got (%d, %v); want (0, io.EOF)", n, err) + } + n, err = c.Write(b[:]) + if err == nil { + t.Fatalf("got (%d, %v); want (any, error)", n, err) + } + }) } } func TestConnClose(t *testing.T) { + t.Parallel() for _, network := range []string{"tcp", "unix", "unixpacket"} { - if !testableNetwork(network) { - t.Logf("skipping %s test", network) - continue - } + network := network + t.Run(network, func(t *testing.T) { + if !testableNetwork(network) { + t.Skipf("network %s is not testable on the current platform", network) + } + t.Parallel() - ln, err := newLocalListener(network) - if err != nil { - t.Fatal(err) - } - switch network { - case "unix", "unixpacket": - defer os.Remove(ln.Addr().String()) - } - defer ln.Close() + ln, err := newLocalListener(network) + if err != nil { + t.Fatal(err) + } + switch network { + case "unix", "unixpacket": + defer os.Remove(ln.Addr().String()) + } + defer ln.Close() - c, err := Dial(ln.Addr().Network(), ln.Addr().String()) - if err != nil { - t.Fatal(err) - } - switch network { - case "unix", "unixpacket": - defer os.Remove(c.LocalAddr().String()) - } - defer c.Close() + c, err := Dial(ln.Addr().Network(), ln.Addr().String()) + if err != nil { + t.Fatal(err) + } + switch network { + case "unix", "unixpacket": + defer os.Remove(c.LocalAddr().String()) + } + defer c.Close() - if err := c.Close(); err != nil { - if perr := parseCloseError(err, false); perr != nil { - t.Error(perr) + if err := c.Close(); err != nil { + if perr := parseCloseError(err, false); perr != nil { + t.Error(perr) + } + t.Fatal(err) } - t.Fatal(err) - } - var b [1]byte - n, err := c.Read(b[:]) - if n != 0 || err == nil { - t.Fatalf("got (%d, %v); want (0, error)", n, err) - } + var b [1]byte + n, err := c.Read(b[:]) + if n != 0 || err == nil { + t.Fatalf("got (%d, %v); want (0, error)", n, err) + } + }) } } func TestListenerClose(t *testing.T) { + t.Parallel() for _, network := range []string{"tcp", "unix", "unixpacket"} { - if !testableNetwork(network) { - t.Logf("skipping %s test", network) - continue - } - - ln, err := newLocalListener(network) - if err != nil { - t.Fatal(err) - } - switch network { - case "unix", "unixpacket": - defer os.Remove(ln.Addr().String()) - } + network := network + t.Run(network, func(t *testing.T) { + if !testableNetwork(network) { + t.Skipf("network %s is not testable on the current platform", network) + } + t.Parallel() - dst := ln.Addr().String() - if err := ln.Close(); err != nil { - if perr := parseCloseError(err, false); perr != nil { - t.Error(perr) + ln, err := newLocalListener(network) + if err != nil { + t.Fatal(err) + } + switch network { + case "unix", "unixpacket": + defer os.Remove(ln.Addr().String()) } - t.Fatal(err) - } - c, err := ln.Accept() - if err == nil { - c.Close() - t.Fatal("should fail") - } - if network == "tcp" { - // We will have two TCP FSMs inside the - // kernel here. There's no guarantee that a - // signal comes from the far end FSM will be - // delivered immediately to the near end FSM, - // especially on the platforms that allow - // multiple consumer threads to pull pending - // established connections at the same time by - // enabling SO_REUSEPORT option such as Linux, - // DragonFly BSD. So we need to give some time - // quantum to the kernel. - // - // Note that net.inet.tcp.reuseport_ext=1 by - // default on DragonFly BSD. - time.Sleep(time.Millisecond) - - cc, err := Dial("tcp", dst) + dst := ln.Addr().String() + if err := ln.Close(); err != nil { + if perr := parseCloseError(err, false); perr != nil { + t.Error(perr) + } + t.Fatal(err) + } + c, err := ln.Accept() if err == nil { - t.Error("Dial to closed TCP listener succeeded.") - cc.Close() + c.Close() + t.Fatal("should fail") } - } + + if network == "tcp" { + // We will have two TCP FSMs inside the + // kernel here. There's no guarantee that a + // signal comes from the far end FSM will be + // delivered immediately to the near end FSM, + // especially on the platforms that allow + // multiple consumer threads to pull pending + // established connections at the same time by + // enabling SO_REUSEPORT option such as Linux, + // DragonFly BSD. So we need to give some time + // quantum to the kernel. + // + // Note that net.inet.tcp.reuseport_ext=1 by + // default on DragonFly BSD. + time.Sleep(time.Millisecond) + + cc, err := Dial("tcp", dst) + if err == nil { + t.Error("Dial to closed TCP listener succeeded.") + cc.Close() + } + } + }) } } func TestPacketConnClose(t *testing.T) { + t.Parallel() for _, network := range []string{"udp", "unixgram"} { - if !testableNetwork(network) { - t.Logf("skipping %s test", network) - continue - } + network := network + t.Run(network, func(t *testing.T) { + if !testableNetwork(network) { + t.Skipf("network %s is not testable on the current platform", network) + } + t.Parallel() - c, err := newLocalPacketListener(network) - if err != nil { - t.Fatal(err) - } - switch network { - case "unixgram": - defer os.Remove(c.LocalAddr().String()) - } - defer c.Close() + c, err := newLocalPacketListener(network) + if err != nil { + t.Fatal(err) + } + switch network { + case "unixgram": + defer os.Remove(c.LocalAddr().String()) + } + defer c.Close() - if err := c.Close(); err != nil { - if perr := parseCloseError(err, false); perr != nil { - t.Error(perr) + if err := c.Close(); err != nil { + if perr := parseCloseError(err, false); perr != nil { + t.Error(perr) + } + t.Fatal(err) } - t.Fatal(err) - } - var b [1]byte - n, _, err := c.ReadFrom(b[:]) - if n != 0 || err == nil { - t.Fatalf("got (%d, %v); want (0, error)", n, err) - } + var b [1]byte + n, _, err := c.ReadFrom(b[:]) + if n != 0 || err == nil { + t.Fatalf("got (%d, %v); want (0, error)", n, err) + } + }) } } @@ -366,56 +398,60 @@ func TestAcceptIgnoreAbortedConnRequest(t *testing.T) { } func TestZeroByteRead(t *testing.T) { + t.Parallel() for _, network := range []string{"tcp", "unix", "unixpacket"} { - if !testableNetwork(network) { - t.Logf("skipping %s test", network) - continue - } + network := network + t.Run(network, func(t *testing.T) { + if !testableNetwork(network) { + t.Skipf("network %s is not testable on the current platform", network) + } + t.Parallel() - ln, err := newLocalListener(network) - if err != nil { - t.Fatal(err) - } - connc := make(chan Conn, 1) - go func() { - defer ln.Close() - c, err := ln.Accept() + ln, err := newLocalListener(network) if err != nil { - t.Error(err) + t.Fatal(err) } - connc <- c // might be nil - }() - c, err := Dial(network, ln.Addr().String()) - if err != nil { - t.Fatal(err) - } - defer c.Close() - sc := <-connc - if sc == nil { - continue - } - defer sc.Close() + connc := make(chan Conn, 1) + go func() { + defer ln.Close() + c, err := ln.Accept() + if err != nil { + t.Error(err) + } + connc <- c // might be nil + }() + c, err := Dial(network, ln.Addr().String()) + if err != nil { + t.Fatal(err) + } + defer c.Close() + sc := <-connc + if sc == nil { + return + } + defer sc.Close() - if runtime.GOOS == "windows" { - // A zero byte read on Windows caused a wait for readability first. - // Rather than change that behavior, satisfy it in this test. - // See Issue 15735. - go io.WriteString(sc, "a") - } + if runtime.GOOS == "windows" { + // A zero byte read on Windows caused a wait for readability first. + // Rather than change that behavior, satisfy it in this test. + // See Issue 15735. + go io.WriteString(sc, "a") + } - n, err := c.Read(nil) - if n != 0 || err != nil { - t.Errorf("%s: zero byte client read = %v, %v; want 0, nil", network, n, err) - } + n, err := c.Read(nil) + if n != 0 || err != nil { + t.Errorf("%s: zero byte client read = %v, %v; want 0, nil", network, n, err) + } - if runtime.GOOS == "windows" { - // Same as comment above. - go io.WriteString(c, "a") - } - n, err = sc.Read(nil) - if n != 0 || err != nil { - t.Errorf("%s: zero byte server read = %v, %v; want 0, nil", network, n, err) - } + if runtime.GOOS == "windows" { + // Same as comment above. + go io.WriteString(c, "a") + } + n, err = sc.Read(nil) + if n != 0 || err != nil { + t.Errorf("%s: zero byte server read = %v, %v; want 0, nil", network, n, err) + } + }) } } diff --git a/libgo/go/net/pipe.go b/libgo/go/net/pipe.go index 9177fc40364..f1741938b0b 100644 --- a/libgo/go/net/pipe.go +++ b/libgo/go/net/pipe.go @@ -6,6 +6,7 @@ package net import ( "io" + "os" "sync" "time" ) @@ -78,12 +79,6 @@ func isClosedChan(c <-chan struct{}) bool { } } -type timeoutError struct{} - -func (timeoutError) Error() string { return "deadline exceeded" } -func (timeoutError) Timeout() bool { return true } -func (timeoutError) Temporary() bool { return true } - type pipeAddr struct{} func (pipeAddr) Network() string { return "pipe" } @@ -158,7 +153,7 @@ func (p *pipe) read(b []byte) (n int, err error) { case isClosedChan(p.remoteDone): return 0, io.EOF case isClosedChan(p.readDeadline.wait()): - return 0, timeoutError{} + return 0, os.ErrDeadlineExceeded } select { @@ -171,7 +166,7 @@ func (p *pipe) read(b []byte) (n int, err error) { case <-p.remoteDone: return 0, io.EOF case <-p.readDeadline.wait(): - return 0, timeoutError{} + return 0, os.ErrDeadlineExceeded } } @@ -190,7 +185,7 @@ func (p *pipe) write(b []byte) (n int, err error) { case isClosedChan(p.remoteDone): return 0, io.ErrClosedPipe case isClosedChan(p.writeDeadline.wait()): - return 0, timeoutError{} + return 0, os.ErrDeadlineExceeded } p.wrMu.Lock() // Ensure entirety of b is written together @@ -206,7 +201,7 @@ func (p *pipe) write(b []byte) (n int, err error) { case <-p.remoteDone: return n, io.ErrClosedPipe case <-p.writeDeadline.wait(): - return n, timeoutError{} + return n, os.ErrDeadlineExceeded } } return n, nil diff --git a/libgo/go/net/platform_test.go b/libgo/go/net/platform_test.go index d35dfaade3e..d3bb918edbf 100644 --- a/libgo/go/net/platform_test.go +++ b/libgo/go/net/platform_test.go @@ -54,7 +54,7 @@ func testableNetwork(network string) bool { return unixEnabledOnAIX } // iOS does not support unix, unixgram. - if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { + if iOS() { return false } case "unixpacket": @@ -81,6 +81,10 @@ func testableNetwork(network string) bool { return true } +func iOS() bool { + return runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" +} + // testableAddress reports whether address of network is testable on // the current platform configuration. func testableAddress(network, address string) bool { diff --git a/libgo/go/net/rawconn_test.go b/libgo/go/net/rawconn_test.go index 9a82f8f78e0..a08ff89d1af 100644 --- a/libgo/go/net/rawconn_test.go +++ b/libgo/go/net/rawconn_test.go @@ -130,7 +130,7 @@ func TestRawConnReadWrite(t *testing.T) { if perr := parseWriteError(err); perr != nil { t.Error(perr) } - if nerr, ok := err.(Error); !ok || !nerr.Timeout() { + if !isDeadlineExceeded(err) { t.Errorf("got %v; want timeout", err) } if _, err = readRawConn(cc, b[:]); err == nil { @@ -139,7 +139,7 @@ func TestRawConnReadWrite(t *testing.T) { if perr := parseReadError(err); perr != nil { t.Error(perr) } - if nerr, ok := err.(Error); !ok || !nerr.Timeout() { + if !isDeadlineExceeded(err) { t.Errorf("got %v; want timeout", err) } @@ -153,7 +153,7 @@ func TestRawConnReadWrite(t *testing.T) { if perr := parseReadError(err); perr != nil { t.Error(perr) } - if nerr, ok := err.(Error); !ok || !nerr.Timeout() { + if !isDeadlineExceeded(err) { t.Errorf("got %v; want timeout", err) } @@ -167,7 +167,7 @@ func TestRawConnReadWrite(t *testing.T) { if perr := parseWriteError(err); perr != nil { t.Error(perr) } - if nerr, ok := err.(Error); !ok || !nerr.Timeout() { + if !isDeadlineExceeded(err) { t.Errorf("got %v; want timeout", err) } }) diff --git a/libgo/go/net/rpc/client.go b/libgo/go/net/rpc/client.go index cad2d45e7f8..25f2a004e44 100644 --- a/libgo/go/net/rpc/client.go +++ b/libgo/go/net/rpc/client.go @@ -31,7 +31,7 @@ type Call struct { Args interface{} // The argument to the function (*struct). Reply interface{} // The reply from the function (*struct). Error error // After completion, the error status. - Done chan *Call // Strobes when call is complete. + Done chan *Call // Receives *Call when Go is complete. } // Client represents an RPC Client. diff --git a/libgo/go/net/rpc/jsonrpc/all_test.go b/libgo/go/net/rpc/jsonrpc/all_test.go index bbb8eb02918..4e73edc70b1 100644 --- a/libgo/go/net/rpc/jsonrpc/all_test.go +++ b/libgo/go/net/rpc/jsonrpc/all_test.go @@ -127,8 +127,8 @@ func TestServer(t *testing.T) { if resp.Error != nil { t.Fatalf("resp.Error: %s", resp.Error) } - if resp.Id.(string) != string(i) { - t.Fatalf("resp: bad id %q want %q", resp.Id.(string), string(i)) + if resp.Id.(string) != string(rune(i)) { + t.Fatalf("resp: bad id %q want %q", resp.Id.(string), string(rune(i))) } if resp.Result.C != 2*i+1 { t.Fatalf("resp: bad result: %d+%d=%d", i, i+1, resp.Result.C) diff --git a/libgo/go/net/sockopt_aix.go b/libgo/go/net/sockopt_aix.go index b49c4d5c7c7..7729a4470b6 100644 --- a/libgo/go/net/sockopt_aix.go +++ b/libgo/go/net/sockopt_aix.go @@ -16,8 +16,11 @@ func setDefaultSockopts(s, family, sotype int, ipv6only bool) error { // never admit this option. syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, boolint(ipv6only)) } - // Allow broadcast. - return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)) + if (sotype == syscall.SOCK_DGRAM || sotype == syscall.SOCK_RAW) && family != syscall.AF_UNIX { + // Allow broadcast. + return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)) + } + return nil } func setDefaultListenerSockopts(s int) error { diff --git a/libgo/go/net/sockopt_bsd.go b/libgo/go/net/sockopt_bsd.go index 1aae88a3e8d..7b8b8d9654c 100644 --- a/libgo/go/net/sockopt_bsd.go +++ b/libgo/go/net/sockopt_bsd.go @@ -31,8 +31,11 @@ func setDefaultSockopts(s, family, sotype int, ipv6only bool) error { // never admit this option. syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, boolint(ipv6only)) } - // Allow broadcast. - return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)) + if (sotype == syscall.SOCK_DGRAM || sotype == syscall.SOCK_RAW) && family != syscall.AF_UNIX { + // Allow broadcast. + return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)) + } + return nil } func setDefaultListenerSockopts(s int) error { diff --git a/libgo/go/net/sockopt_linux.go b/libgo/go/net/sockopt_linux.go index 0f70b12407b..3d544299acf 100644 --- a/libgo/go/net/sockopt_linux.go +++ b/libgo/go/net/sockopt_linux.go @@ -16,8 +16,11 @@ func setDefaultSockopts(s, family, sotype int, ipv6only bool) error { // never admit this option. syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, boolint(ipv6only)) } - // Allow broadcast. - return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)) + if (sotype == syscall.SOCK_DGRAM || sotype == syscall.SOCK_RAW) && family != syscall.AF_UNIX { + // Allow broadcast. + return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)) + } + return nil } func setDefaultListenerSockopts(s int) error { diff --git a/libgo/go/net/sockopt_solaris.go b/libgo/go/net/sockopt_solaris.go index 0f70b12407b..3d544299acf 100644 --- a/libgo/go/net/sockopt_solaris.go +++ b/libgo/go/net/sockopt_solaris.go @@ -16,8 +16,11 @@ func setDefaultSockopts(s, family, sotype int, ipv6only bool) error { // never admit this option. syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, boolint(ipv6only)) } - // Allow broadcast. - return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)) + if (sotype == syscall.SOCK_DGRAM || sotype == syscall.SOCK_RAW) && family != syscall.AF_UNIX { + // Allow broadcast. + return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)) + } + return nil } func setDefaultListenerSockopts(s int) error { diff --git a/libgo/go/net/sockopt_windows.go b/libgo/go/net/sockopt_windows.go index 80174265212..8afaf34514d 100644 --- a/libgo/go/net/sockopt_windows.go +++ b/libgo/go/net/sockopt_windows.go @@ -16,8 +16,10 @@ func setDefaultSockopts(s syscall.Handle, family, sotype int, ipv6only bool) err // never admit this option. syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, boolint(ipv6only)) } - // Allow broadcast. - syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1) + if (sotype == syscall.SOCK_DGRAM || sotype == syscall.SOCK_RAW) && family != syscall.AF_UNIX && family != syscall.AF_INET6 { + // Allow broadcast. + return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)) + } return nil } diff --git a/libgo/go/net/textproto/pipeline.go b/libgo/go/net/textproto/pipeline.go index 2e283218b50..1928a306bf7 100644 --- a/libgo/go/net/textproto/pipeline.go +++ b/libgo/go/net/textproto/pipeline.go @@ -72,7 +72,7 @@ func (p *Pipeline) EndResponse(id uint) { type sequencer struct { mu sync.Mutex id uint - wait map[uint]chan uint + wait map[uint]chan struct{} } // Start waits until it is time for the event numbered id to begin. @@ -84,9 +84,9 @@ func (s *sequencer) Start(id uint) { s.mu.Unlock() return } - c := make(chan uint) + c := make(chan struct{}) if s.wait == nil { - s.wait = make(map[uint]chan uint) + s.wait = make(map[uint]chan struct{}) } s.wait[id] = c s.mu.Unlock() @@ -99,12 +99,13 @@ func (s *sequencer) Start(id uint) { func (s *sequencer) End(id uint) { s.mu.Lock() if s.id != id { + s.mu.Unlock() panic("out of sync") } id++ s.id = id if s.wait == nil { - s.wait = make(map[uint]chan uint) + s.wait = make(map[uint]chan struct{}) } c, ok := s.wait[id] if ok { @@ -112,6 +113,6 @@ func (s *sequencer) End(id uint) { } s.mu.Unlock() if ok { - c <- 1 + close(c) } } diff --git a/libgo/go/net/textproto/reader.go b/libgo/go/net/textproto/reader.go index a505da985c2..a00fd2395fb 100644 --- a/libgo/go/net/textproto/reader.go +++ b/libgo/go/net/textproto/reader.go @@ -88,7 +88,7 @@ func (r *Reader) readLineSlice() ([]byte, error) { // The first call to ReadContinuedLine will return "Line 1 continued..." // and the second will return "Line 2". // -// A line consisting of only white space is never continued. +// Empty lines are never continued. // func (r *Reader) ReadContinuedLine() (string, error) { line, err := r.readContinuedLineSlice(noValidation) @@ -557,7 +557,7 @@ func noValidation(_ []byte) error { return nil } // contain a colon. func mustHaveFieldNameColon(line []byte) error { if bytes.IndexByte(line, ':') < 0 { - return ProtocolError(fmt.Sprintf("malformed MIME header: missing colon: %q" + string(line))) + return ProtocolError(fmt.Sprintf("malformed MIME header: missing colon: %q", line)) } return nil } diff --git a/libgo/go/net/timeout_test.go b/libgo/go/net/timeout_test.go index f54c9564f9e..ad14cd79ac4 100644 --- a/libgo/go/net/timeout_test.go +++ b/libgo/go/net/timeout_test.go @@ -7,12 +7,13 @@ package net import ( + "errors" "fmt" - "internal/poll" "internal/testenv" "io" "io/ioutil" "net/internal/socktest" + "os" "runtime" "sync" "testing" @@ -148,9 +149,9 @@ var acceptTimeoutTests = []struct { }{ // Tests that accept deadlines in the past work, even if // there's incoming connections available. - {-5 * time.Second, [2]error{poll.ErrTimeout, poll.ErrTimeout}}, + {-5 * time.Second, [2]error{os.ErrDeadlineExceeded, os.ErrDeadlineExceeded}}, - {50 * time.Millisecond, [2]error{nil, poll.ErrTimeout}}, + {50 * time.Millisecond, [2]error{nil, os.ErrDeadlineExceeded}}, } func TestAcceptTimeout(t *testing.T) { @@ -194,7 +195,7 @@ func TestAcceptTimeout(t *testing.T) { if perr := parseAcceptError(err); perr != nil { t.Errorf("#%d/%d: %v", i, j, perr) } - if nerr, ok := err.(Error); !ok || !nerr.Timeout() { + if !isDeadlineExceeded(err) { t.Fatalf("#%d/%d: %v", i, j, err) } } @@ -250,7 +251,7 @@ func TestAcceptTimeoutMustReturn(t *testing.T) { if perr := parseAcceptError(err); perr != nil { t.Error(perr) } - if nerr, ok := err.(Error); !ok || !nerr.Timeout() { + if !isDeadlineExceeded(err) { t.Fatal(err) } } @@ -302,9 +303,9 @@ var readTimeoutTests = []struct { }{ // Tests that read deadlines work, even if there's data ready // to be read. - {-5 * time.Second, [2]error{poll.ErrTimeout, poll.ErrTimeout}}, + {-5 * time.Second, [2]error{os.ErrDeadlineExceeded, os.ErrDeadlineExceeded}}, - {50 * time.Millisecond, [2]error{nil, poll.ErrTimeout}}, + {50 * time.Millisecond, [2]error{nil, os.ErrDeadlineExceeded}}, } func TestReadTimeout(t *testing.T) { @@ -344,7 +345,7 @@ func TestReadTimeout(t *testing.T) { if perr := parseReadError(err); perr != nil { t.Errorf("#%d/%d: %v", i, j, perr) } - if nerr, ok := err.(Error); !ok || !nerr.Timeout() { + if !isDeadlineExceeded(err) { t.Fatalf("#%d/%d: %v", i, j, err) } } @@ -423,9 +424,9 @@ var readFromTimeoutTests = []struct { }{ // Tests that read deadlines work, even if there's data ready // to be read. - {-5 * time.Second, [2]error{poll.ErrTimeout, poll.ErrTimeout}}, + {-5 * time.Second, [2]error{os.ErrDeadlineExceeded, os.ErrDeadlineExceeded}}, - {50 * time.Millisecond, [2]error{nil, poll.ErrTimeout}}, + {50 * time.Millisecond, [2]error{nil, os.ErrDeadlineExceeded}}, } func TestReadFromTimeout(t *testing.T) { @@ -468,7 +469,7 @@ func TestReadFromTimeout(t *testing.T) { if perr := parseReadError(err); perr != nil { t.Errorf("#%d/%d: %v", i, j, perr) } - if nerr, ok := err.(Error); !ok || !nerr.Timeout() { + if !isDeadlineExceeded(err) { t.Fatalf("#%d/%d: %v", i, j, err) } } @@ -491,9 +492,9 @@ var writeTimeoutTests = []struct { }{ // Tests that write deadlines work, even if there's buffer // space available to write. - {-5 * time.Second, [2]error{poll.ErrTimeout, poll.ErrTimeout}}, + {-5 * time.Second, [2]error{os.ErrDeadlineExceeded, os.ErrDeadlineExceeded}}, - {10 * time.Millisecond, [2]error{nil, poll.ErrTimeout}}, + {10 * time.Millisecond, [2]error{nil, os.ErrDeadlineExceeded}}, } func TestWriteTimeout(t *testing.T) { @@ -522,7 +523,7 @@ func TestWriteTimeout(t *testing.T) { if perr := parseWriteError(err); perr != nil { t.Errorf("#%d/%d: %v", i, j, perr) } - if nerr, ok := err.(Error); !ok || !nerr.Timeout() { + if !isDeadlineExceeded(err) { t.Fatalf("#%d/%d: %v", i, j, err) } } @@ -605,9 +606,9 @@ var writeToTimeoutTests = []struct { }{ // Tests that write deadlines work, even if there's buffer // space available to write. - {-5 * time.Second, [2]error{poll.ErrTimeout, poll.ErrTimeout}}, + {-5 * time.Second, [2]error{os.ErrDeadlineExceeded, os.ErrDeadlineExceeded}}, - {10 * time.Millisecond, [2]error{nil, poll.ErrTimeout}}, + {10 * time.Millisecond, [2]error{nil, os.ErrDeadlineExceeded}}, } func TestWriteToTimeout(t *testing.T) { @@ -641,7 +642,7 @@ func TestWriteToTimeout(t *testing.T) { if perr := parseWriteError(err); perr != nil { t.Errorf("#%d/%d: %v", i, j, perr) } - if nerr, ok := err.(Error); !ok || !nerr.Timeout() { + if !isDeadlineExceeded(err) { t.Fatalf("#%d/%d: %v", i, j, err) } } @@ -685,7 +686,7 @@ func TestReadTimeoutFluctuation(t *testing.T) { if perr := parseReadError(err); perr != nil { t.Error(perr) } - if nerr, ok := err.(Error); !ok || !nerr.Timeout() { + if !isDeadlineExceeded(err) { t.Fatal(err) } } @@ -718,7 +719,7 @@ func TestReadFromTimeoutFluctuation(t *testing.T) { if perr := parseReadError(err); perr != nil { t.Error(perr) } - if nerr, ok := err.(Error); !ok || !nerr.Timeout() { + if !isDeadlineExceeded(err) { t.Fatal(err) } } @@ -745,7 +746,7 @@ func TestWriteTimeoutFluctuation(t *testing.T) { defer c.Close() d := time.Second - if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { + if iOS() { d = 3 * time.Second // see golang.org/issue/10775 } max := time.NewTimer(d) @@ -760,7 +761,7 @@ func TestWriteTimeoutFluctuation(t *testing.T) { if perr := parseWriteError(err); perr != nil { t.Error(perr) } - if nerr, ok := err.(Error); !ok || !nerr.Timeout() { + if !isDeadlineExceeded(err) { t.Fatal(err) } } @@ -1073,3 +1074,20 @@ func TestConcurrentSetDeadline(t *testing.T) { } wg.Wait() } + +// isDeadlineExceeded reports whether err is or wraps os.ErrDeadlineExceeded. +// We also check that the error implements net.Error, and that the +// Timeout method returns true. +func isDeadlineExceeded(err error) bool { + nerr, ok := err.(Error) + if !ok { + return false + } + if !nerr.Timeout() { + return false + } + if !errors.Is(err, os.ErrDeadlineExceeded) { + return false + } + return true +} diff --git a/libgo/go/net/unixsock_test.go b/libgo/go/net/unixsock_test.go index 80cccf21e3d..4b2cfc4d628 100644 --- a/libgo/go/net/unixsock_test.go +++ b/libgo/go/net/unixsock_test.go @@ -113,7 +113,7 @@ func TestUnixgramZeroBytePayload(t *testing.T) { t.Fatalf("unexpected peer address: %v", peer) } default: // Read may timeout, it depends on the platform - if nerr, ok := err.(Error); !ok || !nerr.Timeout() { + if !isDeadlineExceeded(err) { t.Fatal(err) } } @@ -163,7 +163,7 @@ func TestUnixgramZeroByteBuffer(t *testing.T) { t.Fatalf("unexpected peer address: %v", peer) } default: // Read may timeout, it depends on the platform - if nerr, ok := err.(Error); !ok || !nerr.Timeout() { + if !isDeadlineExceeded(err) { t.Fatal(err) } } diff --git a/libgo/go/net/url/url.go b/libgo/go/net/url/url.go index 2880e820c30..c93def0bd77 100644 --- a/libgo/go/net/url/url.go +++ b/libgo/go/net/url/url.go @@ -356,15 +356,16 @@ func escape(s string, mode encoding) string { // URL's String method uses the EscapedPath method to obtain the path. See the // EscapedPath method for more details. type URL struct { - Scheme string - Opaque string // encoded opaque data - User *Userinfo // username and password information - Host string // host or host:port - Path string // path (relative paths may omit leading slash) - RawPath string // encoded path hint (see EscapedPath method) - ForceQuery bool // append a query ('?') even if RawQuery is empty - RawQuery string // encoded query values, without '?' - Fragment string // fragment for references, without '#' + Scheme string + Opaque string // encoded opaque data + User *Userinfo // username and password information + Host string // host or host:port + Path string // path (relative paths may omit leading slash) + RawPath string // encoded path hint (see EscapedPath method) + ForceQuery bool // append a query ('?') even if RawQuery is empty + RawQuery string // encoded query values, without '?' + Fragment string // fragment for references, without '#' + RawFragment string // encoded fragment hint (see EscapedFragment method) } // User returns a Userinfo containing the provided username @@ -481,7 +482,7 @@ func Parse(rawurl string) (*URL, error) { if frag == "" { return url, nil } - if url.Fragment, err = unescape(frag, encodeFragment); err != nil { + if err = url.setFragment(frag); err != nil { return nil, &Error{"parse", rawurl, err} } return url, nil @@ -697,7 +698,7 @@ func (u *URL) setPath(p string) error { // In general, code should call EscapedPath instead of // reading u.RawPath directly. func (u *URL) EscapedPath() string { - if u.RawPath != "" && validEncodedPath(u.RawPath) { + if u.RawPath != "" && validEncoded(u.RawPath, encodePath) { p, err := unescape(u.RawPath, encodePath) if err == nil && p == u.Path { return u.RawPath @@ -709,9 +710,10 @@ func (u *URL) EscapedPath() string { return escape(u.Path, encodePath) } -// validEncodedPath reports whether s is a valid encoded path. -// It must not contain any bytes that require escaping during path encoding. -func validEncodedPath(s string) bool { +// validEncoded reports whether s is a valid encoded path or fragment, +// according to mode. +// It must not contain any bytes that require escaping during encoding. +func validEncoded(s string, mode encoding) bool { for i := 0; i < len(s); i++ { // RFC 3986, Appendix A. // pchar = unreserved / pct-encoded / sub-delims / ":" / "@". @@ -726,7 +728,7 @@ func validEncodedPath(s string) bool { case '%': // ok - percent encoded, will decode default: - if shouldEscape(s[i], encodePath) { + if shouldEscape(s[i], mode) { return false } } @@ -734,6 +736,40 @@ func validEncodedPath(s string) bool { return true } +// setFragment is like setPath but for Fragment/RawFragment. +func (u *URL) setFragment(f string) error { + frag, err := unescape(f, encodeFragment) + if err != nil { + return err + } + u.Fragment = frag + if escf := escape(frag, encodeFragment); f == escf { + // Default encoding is fine. + u.RawFragment = "" + } else { + u.RawFragment = f + } + return nil +} + +// EscapedFragment returns the escaped form of u.Fragment. +// In general there are multiple possible escaped forms of any fragment. +// EscapedFragment returns u.RawFragment when it is a valid escaping of u.Fragment. +// Otherwise EscapedFragment ignores u.RawFragment and computes an escaped +// form on its own. +// The String method uses EscapedFragment to construct its result. +// In general, code should call EscapedFragment instead of +// reading u.RawFragment directly. +func (u *URL) EscapedFragment() string { + if u.RawFragment != "" && validEncoded(u.RawFragment, encodeFragment) { + f, err := unescape(u.RawFragment, encodeFragment) + if err == nil && f == u.Fragment { + return u.RawFragment + } + } + return escape(u.Fragment, encodeFragment) +} + // validOptionalPort reports whether port is either an empty string // or matches /^:\d*$/ func validOptionalPort(port string) bool { @@ -816,11 +852,25 @@ func (u *URL) String() string { } if u.Fragment != "" { buf.WriteByte('#') - buf.WriteString(escape(u.Fragment, encodeFragment)) + buf.WriteString(u.EscapedFragment()) } return buf.String() } +// Redacted is like String but replaces any password with "xxxxx". +// Only the password in u.URL is redacted. +func (u *URL) Redacted() string { + if u == nil { + return "" + } + + ru := *u + if _, has := ru.User.Password(); has { + ru.User = UserPassword(ru.User.Username(), "xxxxx") + } + return ru.String() +} + // Values maps a string key to a list of values. // It is typically used for query parameters and form values. // Unlike in the http.Header map, the keys in a Values map @@ -1016,6 +1066,7 @@ func (u *URL) ResolveReference(ref *URL) *URL { url.RawQuery = u.RawQuery if ref.Fragment == "" { url.Fragment = u.Fragment + url.RawFragment = u.RawFragment } } // The "abs_path" or "rel_path" cases. diff --git a/libgo/go/net/url/url_test.go b/libgo/go/net/url/url_test.go index 79fd3d5c79f..92b15afad4d 100644 --- a/libgo/go/net/url/url_test.go +++ b/libgo/go/net/url/url_test.go @@ -19,7 +19,7 @@ import ( type URLTest struct { in string - out *URL // expected parse; RawPath="" means same as Path + out *URL // expected parse roundtrip string // expected result of reserializing the URL; empty means same as "in". } @@ -54,6 +54,18 @@ var urltests = []URLTest{ }, "", }, + // fragment with hex escaping + { + "http://www.google.com/#file%20one%26two", + &URL{ + Scheme: "http", + Host: "www.google.com", + Path: "/", + Fragment: "file one&two", + RawFragment: "file%20one%26two", + }, + "", + }, // user { "ftp://webmaster@www.google.com/", @@ -261,7 +273,7 @@ var urltests = []URLTest{ "", }, { - "http://www.google.com/?q=go+language#foo%26bar", + "http://www.google.com/?q=go+language#foo&bar", &URL{ Scheme: "http", Host: "www.google.com", @@ -271,6 +283,18 @@ var urltests = []URLTest{ }, "http://www.google.com/?q=go+language#foo&bar", }, + { + "http://www.google.com/?q=go+language#foo%26bar", + &URL{ + Scheme: "http", + Host: "www.google.com", + Path: "/", + RawQuery: "q=go+language", + Fragment: "foo&bar", + RawFragment: "foo%26bar", + }, + "http://www.google.com/?q=go+language#foo%26bar", + }, { "file:///home/adg/rabbits", &URL{ @@ -601,8 +625,8 @@ func ufmt(u *URL) string { pass = p } } - return fmt.Sprintf("opaque=%q, scheme=%q, user=%#v, pass=%#v, host=%q, path=%q, rawpath=%q, rawq=%q, frag=%q, forcequery=%v", - u.Opaque, u.Scheme, user, pass, u.Host, u.Path, u.RawPath, u.RawQuery, u.Fragment, u.ForceQuery) + return fmt.Sprintf("opaque=%q, scheme=%q, user=%#v, pass=%#v, host=%q, path=%q, rawpath=%q, rawq=%q, frag=%q, rawfrag=%q, forcequery=%v", + u.Opaque, u.Scheme, user, pass, u.Host, u.Path, u.RawPath, u.RawQuery, u.Fragment, u.RawFragment, u.ForceQuery) } func BenchmarkString(b *testing.B) { @@ -765,6 +789,73 @@ func TestURLString(t *testing.T) { } } +func TestURLRedacted(t *testing.T) { + cases := []struct { + name string + url *URL + want string + }{ + { + name: "non-blank Password", + url: &URL{ + Scheme: "http", + Host: "host.tld", + Path: "this:that", + User: UserPassword("user", "password"), + }, + want: "http://user:xxxxx@host.tld/this:that", + }, + { + name: "blank Password", + url: &URL{ + Scheme: "http", + Host: "host.tld", + Path: "this:that", + User: User("user"), + }, + want: "http://user@host.tld/this:that", + }, + { + name: "nil User", + url: &URL{ + Scheme: "http", + Host: "host.tld", + Path: "this:that", + User: UserPassword("", "password"), + }, + want: "http://:xxxxx@host.tld/this:that", + }, + { + name: "blank Username, blank Password", + url: &URL{ + Scheme: "http", + Host: "host.tld", + Path: "this:that", + }, + want: "http://host.tld/this:that", + }, + { + name: "empty URL", + url: &URL{}, + want: "", + }, + { + name: "nil URL", + url: nil, + want: "", + }, + } + + for _, tt := range cases { + t := t + t.Run(tt.name, func(t *testing.T) { + if g, w := tt.url.Redacted(), tt.want; g != w { + t.Fatalf("got: %q\nwant: %q", g, w) + } + }) + } +} + type EscapeTest struct { in string out string diff --git a/libgo/go/os/error.go b/libgo/go/os/error.go index 26bfe4cab53..875cc9711f8 100644 --- a/libgo/go/os/error.go +++ b/libgo/go/os/error.go @@ -18,11 +18,12 @@ var ( // Methods on File will return this error when the receiver is nil. ErrInvalid = errInvalid() // "invalid argument" - ErrPermission = errPermission() // "permission denied" - ErrExist = errExist() // "file already exists" - ErrNotExist = errNotExist() // "file does not exist" - ErrClosed = errClosed() // "file already closed" - ErrNoDeadline = errNoDeadline() // "file type does not support deadline" + ErrPermission = errPermission() // "permission denied" + ErrExist = errExist() // "file already exists" + ErrNotExist = errNotExist() // "file does not exist" + ErrClosed = errClosed() // "file already closed" + ErrNoDeadline = errNoDeadline() // "file type does not support deadline" + ErrDeadlineExceeded = errDeadlineExceeded() // "i/o timeout" ) func errInvalid() error { return oserror.ErrInvalid } @@ -32,6 +33,15 @@ func errNotExist() error { return oserror.ErrNotExist } func errClosed() error { return oserror.ErrClosed } func errNoDeadline() error { return poll.ErrNoDeadline } +// errDeadlineExceeded returns the value for os.ErrDeadlineExceeded. +// This error comes from the internal/poll package, which is also +// used by package net. Doing this this way ensures that the net +// package will return os.ErrDeadlineExceeded for an exceeded deadline, +// as documented by net.Conn.SetDeadline, without requiring any extra +// work in the net package and without requiring the internal/poll +// package to import os (which it can't, because that would be circular). +func errDeadlineExceeded() error { return poll.ErrDeadlineExceeded } + type timeout interface { Timeout() bool } diff --git a/libgo/go/os/exec/exec_linux_test.go b/libgo/go/os/exec/exec_linux_test.go new file mode 100644 index 00000000000..6f850204d60 --- /dev/null +++ b/libgo/go/os/exec/exec_linux_test.go @@ -0,0 +1,45 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build linux,cgo + +// On systems that use glibc, calling malloc can create a new arena, +// and creating a new arena can read /sys/devices/system/cpu/online. +// If we are using cgo, we will call malloc when creating a new thread. +// That can break TestExtraFiles if we create a new thread that creates +// a new arena and opens the /sys file while we are checking for open +// file descriptors. Work around the problem by creating threads up front. +// See issue 25628. + +package exec_test + +import ( + "os" + "sync" + "syscall" + "time" +) + +func init() { + if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" { + return + } + + // Start some threads. 10 is arbitrary but intended to be enough + // to ensure that the code won't have to create any threads itself. + // In particular this should be more than the number of threads + // the garbage collector might create. + const threads = 10 + + var wg sync.WaitGroup + wg.Add(threads) + ts := syscall.NsecToTimespec((100 * time.Microsecond).Nanoseconds()) + for i := 0; i < threads; i++ { + go func() { + defer wg.Done() + syscall.Nanosleep(&ts, nil) + }() + } + wg.Wait() +} diff --git a/libgo/go/os/exec/exec_test.go b/libgo/go/os/exec/exec_test.go index dce66c5c2e1..dafbc64a17c 100644 --- a/libgo/go/os/exec/exec_test.go +++ b/libgo/go/os/exec/exec_test.go @@ -488,25 +488,6 @@ func numOpenFDsAndroid(t *testing.T) (n int, lsof []byte) { return bytes.Count(lsof, []byte("\n")), lsof } -// basefds returns the number of expected file descriptors -// to be present in a process at start. -// stdin, stdout, stderr, epoll/kqueue, epoll/kqueue pipe, maybe testlog -func basefds() uintptr { - n := os.Stderr.Fd() + 1 - // The poll (epoll/kqueue) descriptor can be numerically - // either between stderr and the testlog-fd, or after - // testlog-fd. - for poll.IsPollDescriptor(n) { - n++ - } - for _, arg := range os.Args { - if strings.HasPrefix(arg, "-test.testlogfile=") { - n++ - } - } - return n -} - func TestExtraFilesFDShuffle(t *testing.T) { t.Skip("flaky test; see https://golang.org/issue/5780") switch runtime.GOOS { @@ -622,6 +603,7 @@ func TestExtraFiles(t *testing.T) { } testenv.MustHaveExec(t) + testenv.MustHaveGoBuild(t) if runtime.GOOS == "windows" { t.Skipf("skipping test on %q", runtime.GOOS) @@ -676,7 +658,31 @@ func TestExtraFiles(t *testing.T) { t.Fatalf("Seek: %v", err) } - c := helperCommand(t, "read3") + tempdir := t.TempDir() + exe := filepath.Join(tempdir, "read3.exe") + + c := exec.Command(testenv.GoToolPath(t), "build", "-o", exe, "read3.go") + // Build the test without cgo, so that C library functions don't + // open descriptors unexpectedly. See issue 25628. + c.Env = append(os.Environ(), "CGO_ENABLED=0") + if output, err := c.CombinedOutput(); err != nil { + t.Logf("go build -o %s read3.go\n%s", exe, output) + t.Fatalf("go build failed: %v", err) + } + + // Use a deadline to try to get some output even if the program hangs. + ctx := context.Background() + if deadline, ok := t.Deadline(); ok { + // Leave a 20% grace period to flush output, which may be large on the + // linux/386 builders because we're running the subprocess under strace. + deadline = deadline.Add(-time.Until(deadline) / 5) + + var cancel context.CancelFunc + ctx, cancel = context.WithDeadline(ctx, deadline) + defer cancel() + } + + c = exec.CommandContext(ctx, exe) var stdout, stderr bytes.Buffer c.Stdout = &stdout c.Stderr = &stderr @@ -757,17 +763,6 @@ func TestHelperProcess(*testing.T) { } defer os.Exit(0) - // Determine which command to use to display open files. - ofcmd := "lsof" - switch runtime.GOOS { - case "dragonfly", "freebsd", "netbsd", "openbsd": - ofcmd = "fstat" - case "plan9": - ofcmd = "/bin/cat" - case "aix": - ofcmd = "procfiles" - } - args := os.Args for len(args) > 0 { if args[0] == "--" { @@ -841,55 +836,6 @@ func TestHelperProcess(*testing.T) { os.Exit(1) } os.Exit(0) - case "read3": // read fd 3 - fd3 := os.NewFile(3, "fd3") - bs, err := ioutil.ReadAll(fd3) - if err != nil { - fmt.Printf("ReadAll from fd 3: %v", err) - os.Exit(1) - } - // Now verify that there are no other open fds. - var files []*os.File - for wantfd := basefds() + 1; wantfd <= 100; wantfd++ { - if poll.IsPollDescriptor(wantfd) { - continue - } - f, err := os.Open(os.Args[0]) - if err != nil { - fmt.Printf("error opening file with expected fd %d: %v", wantfd, err) - os.Exit(1) - } - if got := f.Fd(); got != wantfd { - fmt.Printf("leaked parent file. fd = %d; want %d\n", got, wantfd) - var args []string - switch runtime.GOOS { - case "plan9": - args = []string{fmt.Sprintf("/proc/%d/fd", os.Getpid())} - case "aix": - args = []string{fmt.Sprint(os.Getpid())} - default: - args = []string{"-p", fmt.Sprint(os.Getpid())} - } - cmd := exec.Command(ofcmd, args...) - out, err := cmd.CombinedOutput() - if err != nil { - fmt.Fprintf(os.Stderr, "%s failed: %v\n", strings.Join(cmd.Args, " "), err) - } - fmt.Printf("%s", out) - os.Exit(1) - } - files = append(files, f) - } - for _, f := range files { - f.Close() - } - // Referring to fd3 here ensures that it is not - // garbage collected, and therefore closed, while - // executing the wantfd loop above. It doesn't matter - // what we do with fd3 as long as we refer to it; - // closing it is the easy choice. - fd3.Close() - os.Stdout.Write(bs) case "exit": n, _ := strconv.Atoi(args[0]) os.Exit(n) diff --git a/libgo/go/os/exec/read3.go b/libgo/go/os/exec/read3.go new file mode 100644 index 00000000000..25d732a991d --- /dev/null +++ b/libgo/go/os/exec/read3.go @@ -0,0 +1,99 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +// This is a test program that verifies that it can read from +// descriptor 3 and that no other descriptors are open. +// This is not done via TestHelperProcess and GO_WANT_HELPER_PROCESS +// because we want to ensure that this program does not use cgo, +// because C libraries can open file descriptors behind our backs +// and confuse the test. See issue 25628. +package main + +import ( + "fmt" + "internal/poll" + "io/ioutil" + "os" + "os/exec" + "runtime" + "strings" +) + +func main() { + fd3 := os.NewFile(3, "fd3") + bs, err := ioutil.ReadAll(fd3) + if err != nil { + fmt.Printf("ReadAll from fd 3: %v\n", err) + os.Exit(1) + } + + // Now verify that there are no other open fds. + // stdin == 0 + // stdout == 1 + // stderr == 2 + // descriptor from parent == 3 + // All descriptors 4 and up should be available, + // except for any used by the network poller. + var files []*os.File + for wantfd := uintptr(4); wantfd <= 100; wantfd++ { + if poll.IsPollDescriptor(wantfd) { + continue + } + f, err := os.Open(os.Args[0]) + if err != nil { + fmt.Printf("error opening file with expected fd %d: %v", wantfd, err) + os.Exit(1) + } + if got := f.Fd(); got != wantfd { + fmt.Printf("leaked parent file. fd = %d; want %d\n", got, wantfd) + fdfile := fmt.Sprintf("/proc/self/fd/%d", wantfd) + link, err := os.Readlink(fdfile) + fmt.Printf("readlink(%q) = %q, %v\n", fdfile, link, err) + var args []string + switch runtime.GOOS { + case "plan9": + args = []string{fmt.Sprintf("/proc/%d/fd", os.Getpid())} + case "aix": + args = []string{fmt.Sprint(os.Getpid())} + default: + args = []string{"-p", fmt.Sprint(os.Getpid())} + } + + // Determine which command to use to display open files. + ofcmd := "lsof" + switch runtime.GOOS { + case "dragonfly", "freebsd", "netbsd", "openbsd": + ofcmd = "fstat" + case "plan9": + ofcmd = "/bin/cat" + case "aix": + ofcmd = "procfiles" + } + + cmd := exec.Command(ofcmd, args...) + out, err := cmd.CombinedOutput() + if err != nil { + fmt.Fprintf(os.Stderr, "%s failed: %v\n", strings.Join(cmd.Args, " "), err) + } + fmt.Printf("%s", out) + os.Exit(1) + } + files = append(files, f) + } + + for _, f := range files { + f.Close() + } + + // Referring to fd3 here ensures that it is not + // garbage collected, and therefore closed, while + // executing the wantfd loop above. It doesn't matter + // what we do with fd3 as long as we refer to it; + // closing it is the easy choice. + fd3.Close() + + os.Stdout.Write(bs) +} diff --git a/libgo/go/os/exec_unix.go b/libgo/go/os/exec_unix.go index 238d7555c7a..a99b45d3b34 100644 --- a/libgo/go/os/exec_unix.go +++ b/libgo/go/os/exec_unix.go @@ -33,9 +33,18 @@ func (p *Process) wait() (ps *ProcessState, err error) { p.sigMu.Unlock() } - var status syscall.WaitStatus - var rusage syscall.Rusage - pid1, e := syscall.Wait4(p.Pid, &status, 0, &rusage) + var ( + status syscall.WaitStatus + rusage syscall.Rusage + pid1 int + e error + ) + for { + pid1, e = syscall.Wait4(p.Pid, &status, 0, &rusage) + if e != syscall.EINTR { + break + } + } if e != nil { return nil, NewSyscallError("wait", e) } diff --git a/libgo/go/os/exec_windows.go b/libgo/go/os/exec_windows.go index 10503c595ff..24ddf89bb6a 100644 --- a/libgo/go/os/exec_windows.go +++ b/libgo/go/os/exec_windows.go @@ -98,7 +98,7 @@ func findProcess(pid int) (p *Process, err error) { } func init() { - cmd := windows.UTF16PtrToString(syscall.GetCommandLine(), 0xffff) + cmd := windows.UTF16PtrToString(syscall.GetCommandLine()) if len(cmd) == 0 { arg0, _ := Executable() Args = []string{arg0} diff --git a/libgo/go/os/export_linux_test.go b/libgo/go/os/export_linux_test.go new file mode 100644 index 00000000000..d947d05df07 --- /dev/null +++ b/libgo/go/os/export_linux_test.go @@ -0,0 +1,7 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package os + +var PollCopyFileRangeP = &pollCopyFileRange diff --git a/libgo/go/os/file.go b/libgo/go/os/file.go index 9f8c82718bb..a2b71cb61a5 100644 --- a/libgo/go/os/file.go +++ b/libgo/go/os/file.go @@ -143,6 +143,26 @@ func (f *File) ReadAt(b []byte, off int64) (n int, err error) { return } +// ReadFrom implements io.ReaderFrom. +func (f *File) ReadFrom(r io.Reader) (n int64, err error) { + if err := f.checkValid("write"); err != nil { + return 0, err + } + n, handled, e := f.readFrom(r) + if !handled { + return genericReadFrom(f, r) // without wrapping + } + return n, f.wrapErr("write", e) +} + +func genericReadFrom(f *File, r io.Reader) (int64, error) { + return io.Copy(onlyWriter{f}, r) +} + +type onlyWriter struct { + io.Writer +} + // Write writes len(b) bytes to the File. // It returns the number of bytes written and an error, if any. // Write returns a non-nil error when n != len(b). @@ -364,7 +384,7 @@ func TempDir() string { // within this one and use that. // // On Unix systems, it returns $XDG_CACHE_HOME as specified by -// https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html if +// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html if // non-empty, else $HOME/.cache. // On Darwin, it returns $HOME/Library/Caches. // On Windows, it returns %LocalAppData%. @@ -482,7 +502,7 @@ func UserHomeDir() (string, error) { case "android": return "/sdcard", nil case "darwin": - if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" { + if runtime.GOARCH == "arm64" { return "/", nil } } @@ -526,10 +546,12 @@ func (f *File) Chmod(mode FileMode) error { return f.chmod(mode) } // After a deadline has been exceeded, the connection can be refreshed // by setting a deadline in the future. // -// An error returned after a timeout fails will implement the -// Timeout method, and calling the Timeout method will return true. -// The PathError and SyscallError types implement the Timeout method. -// In general, call IsTimeout to test whether an error indicates a timeout. +// If the deadline is exceeded a call to Read or Write or to other I/O +// methods will return an error that wraps ErrDeadlineExceeded. +// This can be tested using errors.Is(err, os.ErrDeadlineExceeded). +// That error implements the Timeout method, and calling the Timeout +// method will return true, but there are other possible errors for which +// the Timeout will return true even if the deadline has not been exceeded. // // An idle timeout can be implemented by repeatedly extending // the deadline after successful Read or Write calls. diff --git a/libgo/go/os/file_plan9.go b/libgo/go/os/file_plan9.go index 48bf5f5076a..eb158905ab1 100644 --- a/libgo/go/os/file_plan9.go +++ b/libgo/go/os/file_plan9.go @@ -112,10 +112,9 @@ func openFileNolog(name string, flag int, perm FileMode) (*File, error) { } else { fd, e = syscall.Open(name, flag) if IsNotExist(e) && create { - var e1 error - fd, e1 = syscall.Create(name, flag, syscallMode(perm)) - if e1 == nil { - e = nil + fd, e = syscall.Create(name, flag, syscallMode(perm)) + if e != nil { + return nil, &PathError{"create", name, e} } } } @@ -234,10 +233,10 @@ func (f *File) Sync() error { var buf [syscall.STATFIXLEN]byte n, err := d.Marshal(buf[:]) if err != nil { - return NewSyscallError("fsync", err) + return &PathError{"sync", f.name, err} } if err = syscall.Fwstat(f.fd, buf[:n]); err != nil { - return NewSyscallError("fsync", err) + return &PathError{"sync", f.name, err} } return nil } @@ -290,6 +289,11 @@ func (f *File) pwrite(b []byte, off int64) (n int, err error) { // relative to the current offset, and 2 means relative to the end. // It returns the new offset and an error, if any. func (f *File) seek(offset int64, whence int) (ret int64, err error) { + if f.dirinfo != nil { + // Free cached dirinfo, so we allocate a new one if we + // access this file as a directory again. See #35767 and #37161. + f.dirinfo = nil + } return syscall.Seek(f.fd, offset, whence) } diff --git a/libgo/go/os/file_posix.go b/libgo/go/os/file_posix.go index f59d1378fc1..ee0728b4a34 100644 --- a/libgo/go/os/file_posix.go +++ b/libgo/go/os/file_posix.go @@ -7,12 +7,57 @@ package os import ( + "runtime" "syscall" "time" ) func sigpipe() // implemented in package runtime +// Close closes the File, rendering it unusable for I/O. +// On files that support SetDeadline, any pending I/O operations will +// be canceled and return immediately with an error. +// Close will return an error if it has already been called. +func (f *File) Close() error { + if f == nil { + return ErrInvalid + } + return f.file.close() +} + +// read reads up to len(b) bytes from the File. +// It returns the number of bytes read and an error, if any. +func (f *File) read(b []byte) (n int, err error) { + n, err = f.pfd.Read(b) + runtime.KeepAlive(f) + return n, err +} + +// pread reads len(b) bytes from the File starting at byte offset off. +// It returns the number of bytes read and the error, if any. +// EOF is signaled by a zero count with err set to nil. +func (f *File) pread(b []byte, off int64) (n int, err error) { + n, err = f.pfd.Pread(b, off) + runtime.KeepAlive(f) + return n, err +} + +// write writes len(b) bytes to the File. +// It returns the number of bytes written and an error, if any. +func (f *File) write(b []byte) (n int, err error) { + n, err = f.pfd.Write(b) + runtime.KeepAlive(f) + return n, err +} + +// pwrite writes len(b) bytes to the File starting at byte offset off. +// It returns the number of bytes written and an error, if any. +func (f *File) pwrite(b []byte, off int64) (n int, err error) { + n, err = f.pfd.Pwrite(b, off) + runtime.KeepAlive(f) + return n, err +} + // syscallMode returns the syscall-specific mode bits from Go's portable mode bits. func syscallMode(i FileMode) (o uint32) { o |= uint32(i.Perm()) diff --git a/libgo/go/os/file_unix.go b/libgo/go/os/file_unix.go index 2fc63188e48..aed77133e53 100644 --- a/libgo/go/os/file_unix.go +++ b/libgo/go/os/file_unix.go @@ -177,6 +177,15 @@ type dirInfo struct { dir *syscall.DIR // from opendir } +func (d *dirInfo) close() { + if d.dir != nil { + syscall.Entersyscall() + libc_closedir(d.dir) + syscall.Exitsyscall() + d.dir = nil + } +} + // epipecheck raises SIGPIPE if we get an EPIPE error on standard // output or standard error. See the SIGPIPE docs in os/signal, and // issue 11845. @@ -208,10 +217,8 @@ func openFileNolog(name string, flag int, perm FileMode) (*File, error) { break } - // On OS X, sigaction(2) doesn't guarantee that SA_RESTART will cause - // open(2) to be restarted for regular files. This is easy to reproduce on - // fuse file systems (see https://golang.org/issue/11180). - if runtime.GOOS == "darwin" && e == syscall.EINTR { + // We have to check EINTR here, per issues 11180 and 39237. + if e == syscall.EINTR { continue } @@ -232,31 +239,13 @@ func openFileNolog(name string, flag int, perm FileMode) (*File, error) { return newFile(uintptr(r), name, kindOpenFile), nil } -// Close closes the File, rendering it unusable for I/O. -// On files that support SetDeadline, any pending I/O operations will -// be canceled and return immediately with an error. -// Close will return an error if it has already been called. -func (f *File) Close() error { - if f == nil { - return ErrInvalid - } - return f.file.close() -} - func (file *file) close() error { if file == nil { return syscall.EINVAL } var err error if file.dirinfo != nil { - syscall.Entersyscall() - i := libc_closedir(file.dirinfo.dir) - errno := syscall.GetErrno() - syscall.Exitsyscall() - file.dirinfo = nil - if i < 0 && errno != 0 { - err = &PathError{"closedir", file.name, errno} - } + file.dirinfo.close() } if e := file.pfd.Close(); e != nil { if e == poll.ErrFileClosing { @@ -270,45 +259,17 @@ func (file *file) close() error { return err } -// read reads up to len(b) bytes from the File. -// It returns the number of bytes read and an error, if any. -func (f *File) read(b []byte) (n int, err error) { - n, err = f.pfd.Read(b) - runtime.KeepAlive(f) - return n, err -} - -// pread reads len(b) bytes from the File starting at byte offset off. -// It returns the number of bytes read and the error, if any. -// EOF is signaled by a zero count with err set to nil. -func (f *File) pread(b []byte, off int64) (n int, err error) { - n, err = f.pfd.Pread(b, off) - runtime.KeepAlive(f) - return n, err -} - -// write writes len(b) bytes to the File. -// It returns the number of bytes written and an error, if any. -func (f *File) write(b []byte) (n int, err error) { - n, err = f.pfd.Write(b) - runtime.KeepAlive(f) - return n, err -} - -// pwrite writes len(b) bytes to the File starting at byte offset off. -// It returns the number of bytes written and an error, if any. -func (f *File) pwrite(b []byte, off int64) (n int, err error) { - n, err = f.pfd.Pwrite(b, off) - runtime.KeepAlive(f) - return n, err -} - // seek sets the offset for the next Read or Write on file to offset, interpreted // according to whence: 0 means relative to the origin of the file, 1 means // relative to the current offset, and 2 means relative to the end. // It returns the new offset and an error, if any. func (f *File) seek(offset int64, whence int) (ret int64, err error) { - f.seekInvalidate() + if f.dirinfo != nil { + // Free cached dirinfo, so we allocate a new one if we + // access this file as a directory again. See #35767 and #37161. + f.dirinfo.close() + f.dirinfo = nil + } ret, err = f.pfd.Seek(offset, whence) runtime.KeepAlive(f) return ret, err diff --git a/libgo/go/os/issue37161/a b/libgo/go/os/issue37161/a new file mode 100644 index 00000000000..78981922613 --- /dev/null +++ b/libgo/go/os/issue37161/a @@ -0,0 +1 @@ +a diff --git a/libgo/go/os/issue37161/b b/libgo/go/os/issue37161/b new file mode 100644 index 00000000000..61780798228 --- /dev/null +++ b/libgo/go/os/issue37161/b @@ -0,0 +1 @@ +b diff --git a/libgo/go/os/issue37161/c b/libgo/go/os/issue37161/c new file mode 100644 index 00000000000..f2ad6c76f01 --- /dev/null +++ b/libgo/go/os/issue37161/c @@ -0,0 +1 @@ +c diff --git a/libgo/go/os/os_test.go b/libgo/go/os/os_test.go index 8ec6de7c078..8a2f917558a 100644 --- a/libgo/go/os/os_test.go +++ b/libgo/go/os/os_test.go @@ -52,7 +52,7 @@ var sysdir = func() *sysDir { } case "darwin": switch runtime.GOARCH { - case "arm", "arm64": + case "arm64": wd, err := syscall.Getwd() if err != nil { wd = err.Error() @@ -144,7 +144,7 @@ func localTmp() string { return TempDir() case "darwin": switch runtime.GOARCH { - case "arm", "arm64": + case "arm64": return TempDir() } } @@ -481,7 +481,7 @@ func TestReaddirnamesOneAtATime(t *testing.T) { dir = "/system/bin" case "darwin": switch runtime.GOARCH { - case "arm", "arm64": + case "arm64": wd, err := Getwd() if err != nil { t.Fatal(err) @@ -1240,6 +1240,41 @@ func testChtimes(t *testing.T, name string) { } } +func TestFileChdir(t *testing.T) { + // TODO(brainman): file.Chdir() is not implemented on windows. + if runtime.GOOS == "windows" { + return + } + + wd, err := Getwd() + if err != nil { + t.Fatalf("Getwd: %s", err) + } + defer Chdir(wd) + + fd, err := Open(".") + if err != nil { + t.Fatalf("Open .: %s", err) + } + defer fd.Close() + + if err := Chdir("/"); err != nil { + t.Fatalf("Chdir /: %s", err) + } + + if err := fd.Chdir(); err != nil { + t.Fatalf("fd.Chdir: %s", err) + } + + wdNew, err := Getwd() + if err != nil { + t.Fatalf("Getwd: %s", err) + } + if wdNew != wd { + t.Fatalf("fd.Chdir failed, got %s, want %s", wdNew, wd) + } +} + func TestChdirAndGetwd(t *testing.T) { // TODO(brainman): file.Chdir() is not implemented on windows. if runtime.GOOS == "windows" { @@ -1260,7 +1295,7 @@ func TestChdirAndGetwd(t *testing.T) { dirs = []string{"/", "/usr"} case "darwin": switch runtime.GOARCH { - case "arm", "arm64": + case "arm64": dirs = nil for _, d := range []string{"d1", "d2"} { dir, err := ioutil.TempDir("", d) @@ -1323,8 +1358,9 @@ func TestChdirAndGetwd(t *testing.T) { // Test that Chdir+Getwd is program-wide. func TestProgWideChdir(t *testing.T) { const N = 10 + const ErrPwd = "Error!" c := make(chan bool) - cpwd := make(chan string) + cpwd := make(chan string, N) for i := 0; i < N; i++ { go func(i int) { // Lock half the goroutines in their own operating system @@ -1337,10 +1373,15 @@ func TestProgWideChdir(t *testing.T) { // See issue 9428. runtime.LockOSThread() } - <-c + hasErr, closed := <-c + if !closed && hasErr { + cpwd <- ErrPwd + return + } pwd, err := Getwd() if err != nil { t.Errorf("Getwd on goroutine %d: %v", i, err) + cpwd <- ErrPwd return } cpwd <- pwd @@ -1348,10 +1389,12 @@ func TestProgWideChdir(t *testing.T) { } oldwd, err := Getwd() if err != nil { + c <- true t.Fatalf("Getwd: %v", err) } d, err := ioutil.TempDir("", "test") if err != nil { + c <- true t.Fatalf("TempDir: %v", err) } defer func() { @@ -1361,17 +1404,22 @@ func TestProgWideChdir(t *testing.T) { RemoveAll(d) }() if err := Chdir(d); err != nil { + c <- true t.Fatalf("Chdir: %v", err) } // OS X sets TMPDIR to a symbolic link. // So we resolve our working directory again before the test. d, err = Getwd() if err != nil { + c <- true t.Fatalf("Getwd: %v", err) } close(c) for i := 0; i < N; i++ { pwd := <-cpwd + if pwd == ErrPwd { + t.FailNow() + } if pwd != d { t.Errorf("Getwd returned %q; want %q", pwd, d) } @@ -1787,7 +1835,7 @@ func TestAppend(t *testing.T) { func TestStatDirWithTrailingSlash(t *testing.T) { // Create new temporary directory and arrange to clean it up. - path, err := ioutil.TempDir("", "/_TestStatDirWithSlash_") + path, err := ioutil.TempDir("", "_TestStatDirWithSlash_") if err != nil { t.Fatalf("TempDir: %s", err) } @@ -2451,14 +2499,53 @@ func TestDirSeek(t *testing.T) { } } -// Test that opening a file does not change its permissions. Issue 38225. -func TestOpenFileKeepsPermissions(t *testing.T) { - t.Parallel() - dir, err := ioutil.TempDir("", "TestOpenFileKeepsPermissions") +func TestReaddirSmallSeek(t *testing.T) { + // See issue 37161. Read only one entry from a directory, + // seek to the beginning, and read again. We should not see + // duplicate entries. + if runtime.GOOS == "windows" { + testenv.SkipFlaky(t, 36019) + } + wd, err := Getwd() if err != nil { t.Fatal(err) } - defer RemoveAll(dir) + df, err := Open(filepath.Join(wd, "testdata", "issue37161")) + if err != nil { + t.Fatal(err) + } + names1, err := df.Readdirnames(1) + if err != nil { + t.Fatal(err) + } + if _, err = df.Seek(0, 0); err != nil { + t.Fatal(err) + } + names2, err := df.Readdirnames(0) + if err != nil { + t.Fatal(err) + } + if len(names2) != 3 { + t.Fatalf("first names: %v, second names: %v", names1, names2) + } +} + +// isDeadlineExceeded reports whether err is or wraps os.ErrDeadlineExceeded. +// We also check that the error has a Timeout method that returns true. +func isDeadlineExceeded(err error) bool { + if !IsTimeout(err) { + return false + } + if !errors.Is(err, ErrDeadlineExceeded) { + return false + } + return true +} + +// Test that opening a file does not change its permissions. Issue 38225. +func TestOpenFileKeepsPermissions(t *testing.T) { + t.Parallel() + dir := t.TempDir() name := filepath.Join(dir, "x") f, err := Create(name) if err != nil { diff --git a/libgo/go/os/os_unix_test.go b/libgo/go/os/os_unix_test.go index 7af20d79f14..7b6fa0c045d 100644 --- a/libgo/go/os/os_unix_test.go +++ b/libgo/go/os/os_unix_test.go @@ -275,7 +275,7 @@ func newFileTest(t *testing.T, blocking bool) { _, err := file.Read(b) if !blocking { // We want it to fail with a timeout. - if !IsTimeout(err) { + if !isDeadlineExceeded(err) { t.Fatalf("No timeout reading from file: %v", err) } } else { diff --git a/libgo/go/os/os_windows_test.go b/libgo/go/os/os_windows_test.go index 8c141031434..f03ec750d02 100644 --- a/libgo/go/os/os_windows_test.go +++ b/libgo/go/os/os_windows_test.go @@ -965,9 +965,10 @@ func TestWindowsDevNullFile(t *testing.T) { // works on Windows when developer mode is active. // This is supported starting Windows 10 (1703, v10.0.14972). func TestSymlinkCreation(t *testing.T) { - if !isWindowsDeveloperModeActive() { + if !testenv.HasSymlink() && !isWindowsDeveloperModeActive() { t.Skip("Windows developer mode is not active") } + t.Parallel() temp, err := ioutil.TempDir("", "TestSymlinkCreation") if err != nil { @@ -1005,6 +1006,122 @@ func isWindowsDeveloperModeActive() bool { return val != 0 } +// TestRootRelativeDirSymlink verifies that symlinks to paths relative to the +// drive root (beginning with "\" but no volume name) are created with the +// correct symlink type. +// (See https://golang.org/issue/39183#issuecomment-632175728.) +func TestRootRelativeDirSymlink(t *testing.T) { + testenv.MustHaveSymlink(t) + t.Parallel() + + temp := t.TempDir() + dir := filepath.Join(temp, "dir") + if err := os.Mkdir(dir, 0755); err != nil { + t.Fatal(err) + } + + volumeRelDir := strings.TrimPrefix(dir, filepath.VolumeName(dir)) // leaves leading backslash + + link := filepath.Join(temp, "link") + err := os.Symlink(volumeRelDir, link) + if err != nil { + t.Fatal(err) + } + t.Logf("Symlink(%#q, %#q)", volumeRelDir, link) + + f, err := os.Open(link) + if err != nil { + t.Fatal(err) + } + defer f.Close() + if fi, err := f.Stat(); err != nil { + t.Fatal(err) + } else if !fi.IsDir() { + t.Errorf("Open(%#q).Stat().IsDir() = false; want true", f.Name()) + } +} + +// TestWorkingDirectoryRelativeSymlink verifies that symlinks to paths relative +// to the current working directory for the drive, such as "C:File.txt", are +// correctly converted to absolute links of the correct symlink type (per +// https://docs.microsoft.com/en-us/windows/win32/fileio/creating-symbolic-links). +func TestWorkingDirectoryRelativeSymlink(t *testing.T) { + testenv.MustHaveSymlink(t) + + // Construct a directory to be symlinked. + temp := t.TempDir() + if v := filepath.VolumeName(temp); len(v) < 2 || v[1] != ':' { + t.Skipf("Can't test relative symlinks: t.TempDir() (%#q) does not begin with a drive letter.", temp) + } + + absDir := filepath.Join(temp, `dir\sub`) + if err := os.MkdirAll(absDir, 0755); err != nil { + t.Fatal(err) + } + + // Change to the temporary directory and construct a + // working-directory-relative symlink. + oldwd, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + defer func() { + if err := os.Chdir(oldwd); err != nil { + t.Fatal(err) + } + }() + if err := os.Chdir(temp); err != nil { + t.Fatal(err) + } + t.Logf("Chdir(%#q)", temp) + + wdRelDir := filepath.VolumeName(temp) + `dir\sub` // no backslash after volume. + absLink := filepath.Join(temp, "link") + err = os.Symlink(wdRelDir, absLink) + if err != nil { + t.Fatal(err) + } + t.Logf("Symlink(%#q, %#q)", wdRelDir, absLink) + + // Now change back to the original working directory and verify that the + // symlink still refers to its original path and is correctly marked as a + // directory. + if err := os.Chdir(oldwd); err != nil { + t.Fatal(err) + } + t.Logf("Chdir(%#q)", oldwd) + + resolved, err := os.Readlink(absLink) + if err != nil { + t.Errorf("Readlink(%#q): %v", absLink, err) + } else if resolved != absDir { + t.Errorf("Readlink(%#q) = %#q; want %#q", absLink, resolved, absDir) + } + + linkFile, err := os.Open(absLink) + if err != nil { + t.Fatal(err) + } + defer linkFile.Close() + + linkInfo, err := linkFile.Stat() + if err != nil { + t.Fatal(err) + } + if !linkInfo.IsDir() { + t.Errorf("Open(%#q).Stat().IsDir() = false; want true", absLink) + } + + absInfo, err := os.Stat(absDir) + if err != nil { + t.Fatal(err) + } + + if !os.SameFile(absInfo, linkInfo) { + t.Errorf("SameFile(Stat(%#q), Open(%#q).Stat()) = false; want true", absDir, absLink) + } +} + // TestStatOfInvalidName is regression test for issue #24999. func TestStatOfInvalidName(t *testing.T) { _, err := os.Stat("*.go") diff --git a/libgo/go/os/path_test.go b/libgo/go/os/path_test.go index 6cb25bcaa71..d586daf936e 100644 --- a/libgo/go/os/path_test.go +++ b/libgo/go/os/path_test.go @@ -109,8 +109,8 @@ func TestMkdirAllAtSlash(t *testing.T) { t.Skipf("skipping on %s", runtime.GOOS) case "darwin": switch runtime.GOARCH { - case "arm", "arm64": - t.Skipf("skipping on darwin/%s, mkdir returns EPERM", runtime.GOARCH) + case "arm64": + t.Skipf("skipping on darwin/arm64, mkdir returns EPERM") } } RemoveAll("/_go_os_test") diff --git a/libgo/go/os/pipe_test.go b/libgo/go/os/pipe_test.go index 2e93e3946af..429bd813c20 100644 --- a/libgo/go/os/pipe_test.go +++ b/libgo/go/os/pipe_test.go @@ -104,6 +104,25 @@ func TestStdPipe(t *testing.T) { } } } + + // Test redirecting stdout but not stderr. Issue 40076. + cmd := osexec.Command(os.Args[0], "-test.run", "TestStdPipeHelper") + cmd.Stdout = w + var stderr bytes.Buffer + cmd.Stderr = &stderr + cmd.Env = append(os.Environ(), "GO_TEST_STD_PIPE_HELPER=1") + if err := cmd.Run(); err == nil { + t.Errorf("unexpected success of write to closed stdout") + } else if ee, ok := err.(*osexec.ExitError); !ok { + t.Errorf("unexpected exec error type %T: %v", err, err) + } else if ws, ok := ee.Sys().(syscall.WaitStatus); !ok { + t.Errorf("unexpected wait status type %T: %v", ee.Sys(), ee.Sys()) + } else if !ws.Signaled() || ws.Signal() != syscall.SIGPIPE { + t.Errorf("unexpected exit status %v for write to closed stdout", err) + } + if output := stderr.Bytes(); len(output) > 0 { + t.Errorf("unexpected output on stderr: %s", output) + } } // This is a helper for TestStdPipe. It's not a test in itself. diff --git a/libgo/go/os/readfrom_linux.go b/libgo/go/os/readfrom_linux.go new file mode 100644 index 00000000000..63ea45cf651 --- /dev/null +++ b/libgo/go/os/readfrom_linux.go @@ -0,0 +1,46 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package os + +import ( + "internal/poll" + "io" +) + +var pollCopyFileRange = poll.CopyFileRange + +func (f *File) readFrom(r io.Reader) (written int64, handled bool, err error) { + // copy_file_range(2) does not support destinations opened with + // O_APPEND, so don't even try. + if f.appendMode { + return 0, false, nil + } + + remain := int64(1 << 62) + + lr, ok := r.(*io.LimitedReader) + if ok { + remain, r = lr.N, lr.R + if remain <= 0 { + return 0, true, nil + } + } + + src, ok := r.(*File) + if !ok { + return 0, false, nil + } + if src.checkValid("ReadFrom") != nil { + // Avoid returning the error as we report handled as false, + // leave further error handling as the responsibility of the caller. + return 0, false, nil + } + + written, handled, err = pollCopyFileRange(&f.pfd, &src.pfd, remain) + if lr != nil { + lr.N -= written + } + return written, handled, NewSyscallError("copy_file_range", err) +} diff --git a/libgo/go/os/readfrom_linux_test.go b/libgo/go/os/readfrom_linux_test.go new file mode 100644 index 00000000000..00faf39fe5a --- /dev/null +++ b/libgo/go/os/readfrom_linux_test.go @@ -0,0 +1,363 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package os_test + +import ( + "bytes" + "internal/poll" + "io" + "io/ioutil" + "math/rand" + . "os" + "path/filepath" + "strconv" + "syscall" + "testing" + "time" +) + +func TestCopyFileRange(t *testing.T) { + sizes := []int{ + 1, + 42, + 1025, + syscall.Getpagesize() + 1, + 32769, + } + t.Run("Basic", func(t *testing.T) { + for _, size := range sizes { + t.Run(strconv.Itoa(size), func(t *testing.T) { + testCopyFileRange(t, int64(size), -1) + }) + } + }) + t.Run("Limited", func(t *testing.T) { + t.Run("OneLess", func(t *testing.T) { + for _, size := range sizes { + t.Run(strconv.Itoa(size), func(t *testing.T) { + testCopyFileRange(t, int64(size), int64(size)-1) + }) + } + }) + t.Run("Half", func(t *testing.T) { + for _, size := range sizes { + t.Run(strconv.Itoa(size), func(t *testing.T) { + testCopyFileRange(t, int64(size), int64(size)/2) + }) + } + }) + t.Run("More", func(t *testing.T) { + for _, size := range sizes { + t.Run(strconv.Itoa(size), func(t *testing.T) { + testCopyFileRange(t, int64(size), int64(size)+7) + }) + } + }) + }) + t.Run("DoesntTryInAppendMode", func(t *testing.T) { + dst, src, data, hook := newCopyFileRangeTest(t, 42) + + dst2, err := OpenFile(dst.Name(), O_RDWR|O_APPEND, 0755) + if err != nil { + t.Fatal(err) + } + defer dst2.Close() + + if _, err := io.Copy(dst2, src); err != nil { + t.Fatal(err) + } + if hook.called { + t.Fatal("called poll.CopyFileRange for destination in O_APPEND mode") + } + mustSeekStart(t, dst2) + mustContainData(t, dst2, data) // through traditional means + }) + t.Run("NotRegular", func(t *testing.T) { + t.Run("BothPipes", func(t *testing.T) { + hook := hookCopyFileRange(t) + + pr1, pw1, err := Pipe() + if err != nil { + t.Fatal(err) + } + defer pr1.Close() + defer pw1.Close() + + pr2, pw2, err := Pipe() + if err != nil { + t.Fatal(err) + } + defer pr2.Close() + defer pw2.Close() + + // The pipe is empty, and PIPE_BUF is large enough + // for this, by (POSIX) definition, so there is no + // need for an additional goroutine. + data := []byte("hello") + if _, err := pw1.Write(data); err != nil { + t.Fatal(err) + } + pw1.Close() + + n, err := io.Copy(pw2, pr1) + if err != nil { + t.Fatal(err) + } + if n != int64(len(data)) { + t.Fatalf("transfered %d, want %d", n, len(data)) + } + if !hook.called { + t.Fatalf("should have called poll.CopyFileRange") + } + pw2.Close() + mustContainData(t, pr2, data) + }) + t.Run("DstPipe", func(t *testing.T) { + dst, src, data, hook := newCopyFileRangeTest(t, 255) + dst.Close() + + pr, pw, err := Pipe() + if err != nil { + t.Fatal(err) + } + defer pr.Close() + defer pw.Close() + + n, err := io.Copy(pw, src) + if err != nil { + t.Fatal(err) + } + if n != int64(len(data)) { + t.Fatalf("transfered %d, want %d", n, len(data)) + } + if !hook.called { + t.Fatalf("should have called poll.CopyFileRange") + } + pw.Close() + mustContainData(t, pr, data) + }) + t.Run("SrcPipe", func(t *testing.T) { + dst, src, data, hook := newCopyFileRangeTest(t, 255) + src.Close() + + pr, pw, err := Pipe() + if err != nil { + t.Fatal(err) + } + defer pr.Close() + defer pw.Close() + + // The pipe is empty, and PIPE_BUF is large enough + // for this, by (POSIX) definition, so there is no + // need for an additional goroutine. + if _, err := pw.Write(data); err != nil { + t.Fatal(err) + } + pw.Close() + + n, err := io.Copy(dst, pr) + if err != nil { + t.Fatal(err) + } + if n != int64(len(data)) { + t.Fatalf("transfered %d, want %d", n, len(data)) + } + if !hook.called { + t.Fatalf("should have called poll.CopyFileRange") + } + mustSeekStart(t, dst) + mustContainData(t, dst, data) + }) + }) + t.Run("Nil", func(t *testing.T) { + var nilFile *File + anyFile, err := ioutil.TempFile("", "") + if err != nil { + t.Fatal(err) + } + defer Remove(anyFile.Name()) + defer anyFile.Close() + + if _, err := io.Copy(nilFile, nilFile); err != ErrInvalid { + t.Errorf("io.Copy(nilFile, nilFile) = %v, want %v", err, ErrInvalid) + } + if _, err := io.Copy(anyFile, nilFile); err != ErrInvalid { + t.Errorf("io.Copy(anyFile, nilFile) = %v, want %v", err, ErrInvalid) + } + if _, err := io.Copy(nilFile, anyFile); err != ErrInvalid { + t.Errorf("io.Copy(nilFile, anyFile) = %v, want %v", err, ErrInvalid) + } + + if _, err := nilFile.ReadFrom(nilFile); err != ErrInvalid { + t.Errorf("nilFile.ReadFrom(nilFile) = %v, want %v", err, ErrInvalid) + } + if _, err := anyFile.ReadFrom(nilFile); err != ErrInvalid { + t.Errorf("anyFile.ReadFrom(nilFile) = %v, want %v", err, ErrInvalid) + } + if _, err := nilFile.ReadFrom(anyFile); err != ErrInvalid { + t.Errorf("nilFile.ReadFrom(anyFile) = %v, want %v", err, ErrInvalid) + } + }) +} + +func testCopyFileRange(t *testing.T, size int64, limit int64) { + dst, src, data, hook := newCopyFileRangeTest(t, size) + + // If we have a limit, wrap the reader. + var ( + realsrc io.Reader + lr *io.LimitedReader + ) + if limit >= 0 { + lr = &io.LimitedReader{N: limit, R: src} + realsrc = lr + if limit < int64(len(data)) { + data = data[:limit] + } + } else { + realsrc = src + } + + // Now call ReadFrom (through io.Copy), which will hopefully call + // poll.CopyFileRange. + n, err := io.Copy(dst, realsrc) + if err != nil { + t.Fatal(err) + } + + // If we didn't have a limit, we should have called poll.CopyFileRange + // with the right file descriptor arguments. + if limit > 0 && !hook.called { + t.Fatal("never called poll.CopyFileRange") + } + if hook.called && hook.dstfd != int(dst.Fd()) { + t.Fatalf("wrong destination file descriptor: got %d, want %d", hook.dstfd, dst.Fd()) + } + if hook.called && hook.srcfd != int(src.Fd()) { + t.Fatalf("wrong source file descriptor: got %d, want %d", hook.srcfd, src.Fd()) + } + + // Check that the offsets after the transfer make sense, that the size + // of the transfer was reported correctly, and that the destination + // file contains exactly the bytes we expect it to contain. + dstoff, err := dst.Seek(0, io.SeekCurrent) + if err != nil { + t.Fatal(err) + } + srcoff, err := src.Seek(0, io.SeekCurrent) + if err != nil { + t.Fatal(err) + } + if dstoff != srcoff { + t.Errorf("offsets differ: dstoff = %d, srcoff = %d", dstoff, srcoff) + } + if dstoff != int64(len(data)) { + t.Errorf("dstoff = %d, want %d", dstoff, len(data)) + } + if n != int64(len(data)) { + t.Errorf("short ReadFrom: wrote %d bytes, want %d", n, len(data)) + } + mustSeekStart(t, dst) + mustContainData(t, dst, data) + + // If we had a limit, check that it was updated. + if lr != nil { + if want := limit - n; lr.N != want { + t.Fatalf("didn't update limit correctly: got %d, want %d", lr.N, want) + } + } +} + +// newCopyFileRangeTest initializes a new test for copy_file_range. +// +// It creates source and destination files, and populates the source file +// with random data of the specified size. It also hooks package os' call +// to poll.CopyFileRange and returns the hook so it can be inspected. +func newCopyFileRangeTest(t *testing.T, size int64) (dst, src *File, data []byte, hook *copyFileRangeHook) { + t.Helper() + + hook = hookCopyFileRange(t) + tmp := t.TempDir() + + src, err := Create(filepath.Join(tmp, "src")) + if err != nil { + t.Fatal(err) + } + t.Cleanup(func() { src.Close() }) + + dst, err = Create(filepath.Join(tmp, "dst")) + if err != nil { + t.Fatal(err) + } + t.Cleanup(func() { dst.Close() }) + + // Populate the source file with data, then rewind it, so it can be + // consumed by copy_file_range(2). + prng := rand.New(rand.NewSource(time.Now().Unix())) + data = make([]byte, size) + prng.Read(data) + if _, err := src.Write(data); err != nil { + t.Fatal(err) + } + if _, err := src.Seek(0, io.SeekStart); err != nil { + t.Fatal(err) + } + + return dst, src, data, hook +} + +// mustContainData ensures that the specified file contains exactly the +// specified data. +func mustContainData(t *testing.T, f *File, data []byte) { + t.Helper() + + got := make([]byte, len(data)) + if _, err := io.ReadFull(f, got); err != nil { + t.Fatal(err) + } + if !bytes.Equal(got, data) { + t.Fatalf("didn't get the same data back from %s", f.Name()) + } + if _, err := f.Read(make([]byte, 1)); err != io.EOF { + t.Fatalf("not at EOF") + } +} + +func mustSeekStart(t *testing.T, f *File) { + if _, err := f.Seek(0, io.SeekStart); err != nil { + t.Fatal(err) + } +} + +func hookCopyFileRange(t *testing.T) *copyFileRangeHook { + h := new(copyFileRangeHook) + h.install() + t.Cleanup(h.uninstall) + return h +} + +type copyFileRangeHook struct { + called bool + dstfd int + srcfd int + remain int64 + + original func(dst, src *poll.FD, remain int64) (int64, bool, error) +} + +func (h *copyFileRangeHook) install() { + h.original = *PollCopyFileRangeP + *PollCopyFileRangeP = func(dst, src *poll.FD, remain int64) (int64, bool, error) { + h.called = true + h.dstfd = dst.Sysfd + h.srcfd = src.Sysfd + h.remain = remain + return h.original(dst, src, remain) + } +} + +func (h *copyFileRangeHook) uninstall() { + *PollCopyFileRangeP = h.original +} diff --git a/libgo/go/os/readfrom_stub.go b/libgo/go/os/readfrom_stub.go new file mode 100644 index 00000000000..65429d0cab2 --- /dev/null +++ b/libgo/go/os/readfrom_stub.go @@ -0,0 +1,13 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !linux + +package os + +import "io" + +func (f *File) readFrom(r io.Reader) (n int64, handled bool, err error) { + return 0, false, nil +} diff --git a/libgo/go/os/removeall_at.go b/libgo/go/os/removeall_at.go index afee01d7935..8bbdcf0f414 100644 --- a/libgo/go/os/removeall_at.go +++ b/libgo/go/os/removeall_at.go @@ -9,7 +9,6 @@ package os import ( "internal/syscall/unix" "io" - "runtime" "syscall" ) @@ -178,7 +177,7 @@ func openFdAt(dirfd int, name string) (*File, error) { } // See comment in openFileNolog. - if runtime.GOOS == "darwin" && e == syscall.EINTR { + if e == syscall.EINTR { continue } diff --git a/libgo/go/os/signal/internal/pty/pty.go b/libgo/go/os/signal/internal/pty/pty.go index f7d61f9de59..dd0aee1cb2b 100644 --- a/libgo/go/os/signal/internal/pty/pty.go +++ b/libgo/go/os/signal/internal/pty/pty.go @@ -50,8 +50,8 @@ func (e *PtyError) Error() string { func (e *PtyError) Unwrap() error { return e.Errno } -// Open returns a master pty and the name of the linked slave tty. -func Open() (master *os.File, slave string, err error) { +// Open returns a control pty and the name of the linked process tty. +func Open() (pty *os.File, processTTY string, err error) { m := posix_openpt(_O_RDWR) if m < 0 { return nil, "", ptyError("posix_openpt", syscall.GetErrno()) @@ -74,6 +74,6 @@ func Open() (master *os.File, slave string, err error) { break } } - slave = string(s) - return os.NewFile(uintptr(m), "pty-master"), slave, nil + processTTY = string(s) + return os.NewFile(uintptr(m), "pty"), processTTY, nil } diff --git a/libgo/go/os/signal/signal.go b/libgo/go/os/signal/signal.go index 136dd9cc97f..8e31aa26278 100644 --- a/libgo/go/os/signal/signal.go +++ b/libgo/go/os/signal/signal.go @@ -122,12 +122,6 @@ func Notify(c chan<- os.Signal, sig ...os.Signal) { panic("os/signal: Notify using nil channel") } - watchSignalLoopOnce.Do(func() { - if watchSignalLoop != nil { - go watchSignalLoop() - } - }) - handlers.Lock() defer handlers.Unlock() @@ -148,6 +142,14 @@ func Notify(c chan<- os.Signal, sig ...os.Signal) { h.set(n) if handlers.ref[n] == 0 { enableSignal(n) + + // The runtime requires that we enable a + // signal before starting the watcher. + watchSignalLoopOnce.Do(func() { + if watchSignalLoop != nil { + go watchSignalLoop() + } + }) } handlers.ref[n]++ } diff --git a/libgo/go/os/signal/signal_cgo_test.go b/libgo/go/os/signal/signal_cgo_test.go index 3c23090489f..a117221400d 100644 --- a/libgo/go/os/signal/signal_cgo_test.go +++ b/libgo/go/os/signal/signal_cgo_test.go @@ -19,7 +19,7 @@ import ( "io" "os" "os/exec" - "os/signal/internal/pty" + ptypkg "os/signal/internal/pty" "strconv" "strings" "sync" @@ -71,20 +71,20 @@ func TestTerminalSignal(t *testing.T) { // The test only fails when using a "slow device," in this // case a pseudo-terminal. - master, sname, err := pty.Open() + pty, procTTYName, err := ptypkg.Open() if err != nil { - ptyErr := err.(*pty.PtyError) + ptyErr := err.(*ptypkg.PtyError) if ptyErr.FuncName == "posix_openpt" && ptyErr.Errno == syscall.EACCES { t.Skip("posix_openpt failed with EACCES, assuming chroot and skipping") } t.Fatal(err) } - defer master.Close() - slave, err := os.OpenFile(sname, os.O_RDWR, 0) + defer pty.Close() + procTTY, err := os.OpenFile(procTTYName, os.O_RDWR, 0) if err != nil { t.Fatal(err) } - defer slave.Close() + defer procTTY.Close() // Start an interactive shell. ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) @@ -92,34 +92,34 @@ func TestTerminalSignal(t *testing.T) { cmd := exec.CommandContext(ctx, bash, "--norc", "--noprofile", "-i") // Clear HISTFILE so that we don't read or clobber the user's bash history. cmd.Env = append(os.Environ(), "HISTFILE=") - cmd.Stdin = slave - cmd.Stdout = slave - cmd.Stderr = slave + cmd.Stdin = procTTY + cmd.Stdout = procTTY + cmd.Stderr = procTTY cmd.SysProcAttr = &syscall.SysProcAttr{ Setsid: true, Setctty: true, - Ctty: int(slave.Fd()), + Ctty: 0, } if err := cmd.Start(); err != nil { t.Fatal(err) } - if err := slave.Close(); err != nil { - t.Errorf("closing slave: %v", err) + if err := procTTY.Close(); err != nil { + t.Errorf("closing procTTY: %v", err) } progReady := make(chan bool) sawPrompt := make(chan bool, 10) const prompt = "prompt> " - // Read data from master in the background. + // Read data from pty in the background. var wg sync.WaitGroup wg.Add(1) defer wg.Wait() go func() { defer wg.Done() - input := bufio.NewReader(master) + input := bufio.NewReader(pty) var line, handled []byte for { b, err := input.ReadByte() @@ -130,11 +130,11 @@ func TestTerminalSignal(t *testing.T) { if perr, ok := err.(*os.PathError); ok { err = perr.Err } - // EOF means master is closed. + // EOF means pty is closed. // EIO means child process is done. - // "file already closed" means deferred close of master has happened. + // "file already closed" means deferred close of pty has happened. if err != io.EOF && err != syscall.EIO && !strings.Contains(err.Error(), "file already closed") { - t.Logf("error reading from master: %v", err) + t.Logf("error reading from pty: %v", err) } return } @@ -161,7 +161,7 @@ func TestTerminalSignal(t *testing.T) { }() // Set the bash prompt so that we can see it. - if _, err := master.Write([]byte("PS1='" + prompt + "'\n")); err != nil { + if _, err := pty.Write([]byte("PS1='" + prompt + "'\n")); err != nil { t.Fatalf("setting prompt: %v", err) } select { @@ -172,7 +172,7 @@ func TestTerminalSignal(t *testing.T) { // Start a small program that reads from stdin // (namely the code at the top of this function). - if _, err := master.Write([]byte("GO_TEST_TERMINAL_SIGNALS=1 " + os.Args[0] + " -test.run=TestTerminalSignal\n")); err != nil { + if _, err := pty.Write([]byte("GO_TEST_TERMINAL_SIGNALS=1 " + os.Args[0] + " -test.run=TestTerminalSignal\n")); err != nil { t.Fatal(err) } @@ -190,7 +190,7 @@ func TestTerminalSignal(t *testing.T) { time.Sleep(pause) // Send a ^Z to stop the program. - if _, err := master.Write([]byte{26}); err != nil { + if _, err := pty.Write([]byte{26}); err != nil { t.Fatalf("writing ^Z to pty: %v", err) } @@ -202,7 +202,7 @@ func TestTerminalSignal(t *testing.T) { } // Restart the stopped program. - if _, err := master.Write([]byte("fg\n")); err != nil { + if _, err := pty.Write([]byte("fg\n")); err != nil { t.Fatalf("writing %q to pty: %v", "fg", err) } @@ -217,7 +217,7 @@ func TestTerminalSignal(t *testing.T) { // Write some data for the program to read, // which should cause it to exit. - if _, err := master.Write([]byte{'\n'}); err != nil { + if _, err := pty.Write([]byte{'\n'}); err != nil { t.Fatalf("writing %q to pty: %v", "\n", err) } @@ -229,7 +229,7 @@ func TestTerminalSignal(t *testing.T) { } // Exit the shell with the program's exit status. - if _, err := master.Write([]byte("exit $?\n")); err != nil { + if _, err := pty.Write([]byte("exit $?\n")); err != nil { t.Fatalf("writing %q to pty: %v", "exit", err) } diff --git a/libgo/go/os/signal/signal_plan9.go b/libgo/go/os/signal/signal_plan9.go index 8408607c7fa..7d4871518a2 100644 --- a/libgo/go/os/signal/signal_plan9.go +++ b/libgo/go/os/signal/signal_plan9.go @@ -11,7 +11,7 @@ import ( var sigtab = make(map[os.Signal]int) -// In sig.s; jumps to runtime. +// Defined by the runtime package. func signal_disable(uint32) func signal_enable(uint32) func signal_ignore(uint32) @@ -19,8 +19,6 @@ func signal_ignored(uint32) bool func signal_recv() string func init() { - signal_enable(0) // first call - initialize - watchSignalLoop = loop } diff --git a/libgo/go/os/signal/signal_test.go b/libgo/go/os/signal/signal_test.go index 0708d4c188a..98a1cc1458d 100644 --- a/libgo/go/os/signal/signal_test.go +++ b/libgo/go/os/signal/signal_test.go @@ -22,51 +22,87 @@ import ( "time" ) -var testDeadline time.Time - -func TestMain(m *testing.M) { - flag.Parse() - - // TODO(golang.org/issue/28135): Remove this setup and use t.Deadline instead. - timeoutFlag := flag.Lookup("test.timeout") - if timeoutFlag != nil { - if d := timeoutFlag.Value.(flag.Getter).Get().(time.Duration); d != 0 { - testDeadline = time.Now().Add(d) +// settleTime is an upper bound on how long we expect signals to take to be +// delivered. Lower values make the test faster, but also flakier — especially +// on heavily loaded systems. +// +// The current value is set based on flakes observed in the Go builders. +var settleTime = 100 * time.Millisecond + +func init() { + if testenv.Builder() == "solaris-amd64-oraclerel" { + // The solaris-amd64-oraclerel builder has been observed to time out in + // TestNohup even with a 250ms settle time. + // + // Use a much longer settle time on that builder to try to suss out whether + // the test is flaky due to builder slowness (which may mean we need a + // longer GO_TEST_TIMEOUT_SCALE) or due to a dropped signal (which may + // instead need a test-skip and upstream bug filed against the Solaris + // kernel). + // + // This constant is chosen so as to make the test as generous as possible + // while still reliably completing within 3 minutes in non-short mode. + // + // See https://golang.org/issue/33174. + settleTime = 11 * time.Second + } else if s := os.Getenv("GO_TEST_TIMEOUT_SCALE"); s != "" { + if scale, err := strconv.Atoi(s); err == nil { + settleTime *= time.Duration(scale) } } - - os.Exit(m.Run()) } func waitSig(t *testing.T, c <-chan os.Signal, sig os.Signal) { + t.Helper() waitSig1(t, c, sig, false) } func waitSigAll(t *testing.T, c <-chan os.Signal, sig os.Signal) { + t.Helper() waitSig1(t, c, sig, true) } func waitSig1(t *testing.T, c <-chan os.Signal, sig os.Signal, all bool) { + t.Helper() + // Sleep multiple times to give the kernel more tries to // deliver the signal. - for i := 0; i < 10; i++ { + start := time.Now() + timer := time.NewTimer(settleTime / 10) + defer timer.Stop() + // If the caller notified for all signals on c, filter out SIGURG, + // which is used for runtime preemption and can come at unpredictable times. + // General user code should filter out all unexpected signals instead of just + // SIGURG, but since os/signal is tightly coupled to the runtime it seems + // appropriate to be stricter here. + for time.Since(start) < settleTime { select { case s := <-c: - // If the caller notified for all signals on - // c, filter out SIGURG, which is used for - // runtime preemption and can come at - // unpredictable times. - if all && s == syscall.SIGURG { - continue + if s == sig { + return } - if s != sig { + if !all || s != syscall.SIGURG { t.Fatalf("signal was %v, want %v", s, sig) } - return - - case <-time.After(100 * time.Millisecond): + case <-timer.C: + timer.Reset(settleTime / 10) } } - t.Fatalf("timeout waiting for %v", sig) + t.Fatalf("timeout after %v waiting for %v", settleTime, sig) +} + +// quiesce waits until we can be reasonably confident that all pending signals +// have been delivered by the OS. +func quiesce() { + // The kernel will deliver a signal as a thread returns + // from a syscall. If the only active thread is sleeping, + // and the system is busy, the kernel may not get around + // to waking up a thread to catch the signal. + // We try splitting up the sleep to give the kernel + // many chances to deliver the signal. + start := time.Now() + for time.Since(start) < settleTime { + time.Sleep(settleTime / 10) + } } // Test that basic signal handling works. @@ -112,50 +148,39 @@ func TestStress(t *testing.T) { dur = 100 * time.Millisecond } defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) - done := make(chan bool) - finished := make(chan bool) - go func() { - sig := make(chan os.Signal, 1) - Notify(sig, syscall.SIGUSR1) - defer Stop(sig) - Loop: - for { - select { - case <-sig: - case <-done: - break Loop - } - } - finished <- true - }() + + sig := make(chan os.Signal, 1) + Notify(sig, syscall.SIGUSR1) + go func() { - Loop: + stop := time.After(dur) for { select { - case <-done: - break Loop + case <-stop: + // Allow enough time for all signals to be delivered before we stop + // listening for them. + quiesce() + Stop(sig) + // According to its documentation, “[w]hen Stop returns, it in + // guaranteed that c will receive no more signals.” So we can safely + // close sig here: if there is a send-after-close race here, that is a + // bug in Stop and we would like to detect it. + close(sig) + return + default: syscall.Kill(syscall.Getpid(), syscall.SIGUSR1) runtime.Gosched() } } - finished <- true }() - time.Sleep(dur) - close(done) - <-finished - <-finished - // When run with 'go test -cpu=1,2,4' SIGUSR1 from this test can slip - // into subsequent TestSignal() causing failure. - // Sleep for a while to reduce the possibility of the failure. - time.Sleep(10 * time.Millisecond) + + for range sig { + // Receive signals until the sender closes sig. + } } func testCancel(t *testing.T, ignore bool) { - // Send SIGWINCH. By default this signal should be ignored. - syscall.Kill(syscall.Getpid(), syscall.SIGWINCH) - time.Sleep(100 * time.Millisecond) - // Ask to be notified on c1 when a SIGWINCH is received. c1 := make(chan os.Signal, 1) Notify(c1, syscall.SIGWINCH) @@ -175,25 +200,16 @@ func testCancel(t *testing.T, ignore bool) { waitSig(t, c2, syscall.SIGHUP) // Ignore, or reset the signal handlers for, SIGWINCH and SIGHUP. + // Either way, this should undo both calls to Notify above. if ignore { Ignore(syscall.SIGWINCH, syscall.SIGHUP) + // Don't bother deferring a call to Reset: it is documented to undo Notify, + // but its documentation says nothing about Ignore, and (as of the time of + // writing) it empirically does not undo an Ignore. } else { Reset(syscall.SIGWINCH, syscall.SIGHUP) } - // At this point we do not expect any further signals on c1. - // However, it is just barely possible that the initial SIGWINCH - // at the start of this function was delivered after we called - // Notify on c1. In that case the waitSig for SIGWINCH may have - // picked up that initial SIGWINCH, and the second SIGWINCH may - // then have been delivered on the channel. This sequence of events - // may have caused issue 15661. - // So, read any possible signal from the channel now. - select { - case <-c1: - default: - } - // Send this process a SIGWINCH. It should be ignored. syscall.Kill(syscall.Getpid(), syscall.SIGWINCH) @@ -202,22 +218,28 @@ func testCancel(t *testing.T, ignore bool) { syscall.Kill(syscall.Getpid(), syscall.SIGHUP) } + quiesce() + select { case s := <-c1: - t.Fatalf("unexpected signal %v", s) - case <-time.After(100 * time.Millisecond): + t.Errorf("unexpected signal %v", s) + default: // nothing to read - good } select { case s := <-c2: - t.Fatalf("unexpected signal %v", s) - case <-time.After(100 * time.Millisecond): + t.Errorf("unexpected signal %v", s) + default: // nothing to read - good } - // Reset the signal handlers for all signals. - Reset() + // One or both of the signals may have been blocked for this process + // by the calling process. + // Discard any queued signals now to avoid interfering with other tests. + Notify(c1, syscall.SIGWINCH) + Notify(c2, syscall.SIGHUP) + quiesce() } // Test that Reset cancels registration for listed signals on all channels. @@ -289,7 +311,10 @@ func TestDetectNohup(t *testing.T) { } } -var sendUncaughtSighup = flag.Int("send_uncaught_sighup", 0, "send uncaught SIGHUP during TestStop") +var ( + sendUncaughtSighup = flag.Int("send_uncaught_sighup", 0, "send uncaught SIGHUP during TestStop") + dieFromSighup = flag.Bool("die_from_sighup", false, "wait to die from uncaught SIGHUP") +) // Test that Stop cancels the channel's registrations. func TestStop(t *testing.T) { @@ -300,59 +325,74 @@ func TestStop(t *testing.T) { } for _, sig := range sigs { - // Send the signal. - // If it's SIGWINCH, we should not see it. - // If it's SIGHUP, maybe we'll die. Let the flag tell us what to do. - if sig == syscall.SIGWINCH || (sig == syscall.SIGHUP && *sendUncaughtSighup == 1) { - syscall.Kill(syscall.Getpid(), sig) - } - - // The kernel will deliver a signal as a thread returns - // from a syscall. If the only active thread is sleeping, - // and the system is busy, the kernel may not get around - // to waking up a thread to catch the signal. - // We try splitting up the sleep to give the kernel - // another chance to deliver the signal. - time.Sleep(50 * time.Millisecond) - time.Sleep(50 * time.Millisecond) - - // Ask for signal - c := make(chan os.Signal, 1) - Notify(c, sig) - defer Stop(c) - - // Send this process that signal - syscall.Kill(syscall.Getpid(), sig) - waitSig(t, c, sig) + sig := sig + t.Run(fmt.Sprint(sig), func(t *testing.T) { + // When calling Notify with a specific signal, + // independent signals should not interfere with each other, + // and we end up needing to wait for signals to quiesce a lot. + // Test the three different signals concurrently. + t.Parallel() + + // If the signal is not ignored, send the signal before registering a + // channel to verify the behavior of the default Go handler. + // If it's SIGWINCH or SIGUSR1 we should not see it. + // If it's SIGHUP, maybe we'll die. Let the flag tell us what to do. + mayHaveBlockedSignal := false + if !Ignored(sig) && (sig != syscall.SIGHUP || *sendUncaughtSighup == 1) { + syscall.Kill(syscall.Getpid(), sig) + quiesce() + + // We don't know whether sig is blocked for this process; see + // https://golang.org/issue/38165. Assume that it could be. + mayHaveBlockedSignal = true + } - Stop(c) - time.Sleep(50 * time.Millisecond) - select { - case s := <-c: - t.Fatalf("unexpected signal %v", s) - case <-time.After(50 * time.Millisecond): - // nothing to read - good - } + // Ask for signal + c := make(chan os.Signal, 1) + Notify(c, sig) - // Send the signal. - // If it's SIGWINCH, we should not see it. - // If it's SIGHUP, maybe we'll die. Let the flag tell us what to do. - if sig != syscall.SIGHUP || *sendUncaughtSighup == 2 { + // Send this process the signal again. syscall.Kill(syscall.Getpid(), sig) - } + waitSig(t, c, sig) + + if mayHaveBlockedSignal { + // We may have received a queued initial signal in addition to the one + // that we sent after Notify. If so, waitSig may have observed that + // initial signal instead of the second one, and we may need to wait for + // the second signal to clear. Do that now. + quiesce() + select { + case <-c: + default: + } + } - time.Sleep(50 * time.Millisecond) - select { - case s := <-c: - t.Fatalf("unexpected signal %v", s) - case <-time.After(50 * time.Millisecond): - // nothing to read - good - } + // Stop watching for the signal and send it again. + // If it's SIGHUP, maybe we'll die. Let the flag tell us what to do. + Stop(c) + if sig != syscall.SIGHUP || *sendUncaughtSighup == 2 { + syscall.Kill(syscall.Getpid(), sig) + quiesce() + + select { + case s := <-c: + t.Errorf("unexpected signal %v", s) + default: + // nothing to read - good + } + + // If we're going to receive a signal, it has almost certainly been + // received by now. However, it may have been blocked for this process — + // we don't know. Explicitly unblock it and wait for it to clear now. + Notify(c, sig) + quiesce() + Stop(c) + } + }) } } -// Test that when run under nohup, an uncaught SIGHUP does not kill the program, -// but a +// Test that when run under nohup, an uncaught SIGHUP does not kill the program. func TestNohup(t *testing.T) { // Ugly: ask for SIGHUP so that child will not have no-hup set // even if test is running under nohup environment. @@ -371,12 +411,38 @@ func TestNohup(t *testing.T) { // // Both should fail without nohup and succeed with nohup. + var subTimeout time.Duration + + var wg sync.WaitGroup + wg.Add(2) + if deadline, ok := t.Deadline(); ok { + subTimeout = time.Until(deadline) + subTimeout -= subTimeout / 10 // Leave 10% headroom for propagating output. + } for i := 1; i <= 2; i++ { - out, err := exec.Command(os.Args[0], "-test.run=TestStop", "-send_uncaught_sighup="+strconv.Itoa(i)).CombinedOutput() - if err == nil { - t.Fatalf("ran test with -send_uncaught_sighup=%d and it succeeded: expected failure.\nOutput:\n%s", i, out) - } + i := i + go t.Run(fmt.Sprintf("uncaught-%d", i), func(t *testing.T) { + defer wg.Done() + + args := []string{ + "-test.v", + "-test.run=TestStop", + "-send_uncaught_sighup=" + strconv.Itoa(i), + "-die_from_sighup", + } + if subTimeout != 0 { + args = append(args, fmt.Sprintf("-test.timeout=%v", subTimeout)) + } + out, err := exec.Command(os.Args[0], args...).CombinedOutput() + + if err == nil { + t.Errorf("ran test with -send_uncaught_sighup=%d and it succeeded: expected failure.\nOutput:\n%s", i, out) + } else { + t.Logf("test with -send_uncaught_sighup=%d failed as expected.\nError: %v\nOutput:\n%s", i, err, out) + } + }) } + wg.Wait() Stop(c) @@ -387,21 +453,46 @@ func TestNohup(t *testing.T) { } // Again, this time with nohup, assuming we can find it. - _, err := os.Stat("/usr/bin/nohup") + _, err := exec.LookPath("nohup") if err != nil { t.Skip("cannot find nohup; skipping second half of test") } + wg.Add(2) + if deadline, ok := t.Deadline(); ok { + subTimeout = time.Until(deadline) + subTimeout -= subTimeout / 10 // Leave 10% headroom for propagating output. + } for i := 1; i <= 2; i++ { - os.Remove("nohup.out") - out, err := exec.Command("/usr/bin/nohup", os.Args[0], "-test.run=TestStop", "-send_uncaught_sighup="+strconv.Itoa(i)).CombinedOutput() + i := i + go t.Run(fmt.Sprintf("nohup-%d", i), func(t *testing.T) { + defer wg.Done() - data, _ := ioutil.ReadFile("nohup.out") - os.Remove("nohup.out") - if err != nil { - t.Fatalf("ran test with -send_uncaught_sighup=%d under nohup and it failed: expected success.\nError: %v\nOutput:\n%s%s", i, err, out, data) - } + // POSIX specifies that nohup writes to a file named nohup.out if standard + // output is a terminal. However, for an exec.Command, standard output is + // not a terminal — so we don't need to read or remove that file (and, + // indeed, cannot even create it if the current user is unable to write to + // GOROOT/src, such as when GOROOT is installed and owned by root). + + args := []string{ + os.Args[0], + "-test.v", + "-test.run=TestStop", + "-send_uncaught_sighup=" + strconv.Itoa(i), + } + if subTimeout != 0 { + args = append(args, fmt.Sprintf("-test.timeout=%v", subTimeout)) + } + out, err := exec.Command("nohup", args...).CombinedOutput() + + if err != nil { + t.Errorf("ran test with -send_uncaught_sighup=%d under nohup and it failed: expected success.\nError: %v\nOutput:\n%s", i, err, out) + } else { + t.Logf("ran test with -send_uncaught_sighup=%d under nohup.\nOutput:\n%s", i, out) + } + }) } + wg.Wait() } // Test that SIGCONT works (issue 8953). @@ -416,7 +507,7 @@ func TestSIGCONT(t *testing.T) { // Test race between stopping and receiving a signal (issue 14571). func TestAtomicStop(t *testing.T) { if os.Getenv("GO_TEST_ATOMIC_STOP") != "" { - atomicStopTestProgram() + atomicStopTestProgram(t) t.Fatal("atomicStopTestProgram returned") } @@ -438,8 +529,8 @@ func TestAtomicStop(t *testing.T) { const execs = 10 for i := 0; i < execs; i++ { timeout := "0" - if !testDeadline.IsZero() { - timeout = testDeadline.Sub(time.Now()).String() + if deadline, ok := t.Deadline(); ok { + timeout = time.Until(deadline).String() } cmd := exec.Command(os.Args[0], "-test.run=TestAtomicStop", "-test.timeout="+timeout) cmd.Env = append(os.Environ(), "GO_TEST_ATOMIC_STOP=1") @@ -478,7 +569,7 @@ func TestAtomicStop(t *testing.T) { // atomicStopTestProgram is run in a subprocess by TestAtomicStop. // It tries to trigger a signal delivery race. This function should // either catch a signal or die from it. -func atomicStopTestProgram() { +func atomicStopTestProgram(t *testing.T) { // This test won't work if SIGINT is ignored here. if Ignored(syscall.SIGINT) { fmt.Println("SIGINT is ignored") @@ -488,10 +579,10 @@ func atomicStopTestProgram() { const tries = 10 timeout := 2 * time.Second - if !testDeadline.IsZero() { + if deadline, ok := t.Deadline(); ok { // Give each try an equal slice of the deadline, with one slice to spare for // cleanup. - timeout = testDeadline.Sub(time.Now()) / (tries + 1) + timeout = time.Until(deadline) / (tries + 1) } pid := syscall.Getpid() @@ -541,43 +632,45 @@ func TestTime(t *testing.T) { dur = 100 * time.Millisecond } defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) - done := make(chan bool) - finished := make(chan bool) - go func() { - sig := make(chan os.Signal, 1) - Notify(sig, syscall.SIGUSR1) - defer Stop(sig) - Loop: - for { - select { - case <-sig: - case <-done: - break Loop - } - } - finished <- true - }() + + sig := make(chan os.Signal, 1) + Notify(sig, syscall.SIGUSR1) + + stop := make(chan struct{}) go func() { - Loop: for { select { - case <-done: - break Loop + case <-stop: + // Allow enough time for all signals to be delivered before we stop + // listening for them. + quiesce() + Stop(sig) + // According to its documentation, “[w]hen Stop returns, it in + // guaranteed that c will receive no more signals.” So we can safely + // close sig here: if there is a send-after-close race, that is a bug in + // Stop and we would like to detect it. + close(sig) + return + default: syscall.Kill(syscall.Getpid(), syscall.SIGUSR1) runtime.Gosched() } } - finished <- true }() + + done := make(chan struct{}) + go func() { + for range sig { + // Receive signals until the sender closes sig. + } + close(done) + }() + t0 := time.Now() for t1 := t0; t1.Sub(t0) < dur; t1 = time.Now() { } // hammering on getting time - close(done) - <-finished - <-finished - // When run with 'go test -cpu=1,2,4' SIGUSR1 from this test can slip - // into subsequent TestSignal() causing failure. - // Sleep for a while to reduce the possibility of the failure. - time.Sleep(10 * time.Millisecond) + + close(stop) + <-done } diff --git a/libgo/go/os/signal/signal_unix.go b/libgo/go/os/signal/signal_unix.go index 532c0b586cb..c18db0c4618 100644 --- a/libgo/go/os/signal/signal_unix.go +++ b/libgo/go/os/signal/signal_unix.go @@ -25,8 +25,6 @@ func loop() { } func init() { - signal_enable(0) // first call - initialize - watchSignalLoop = loop } diff --git a/libgo/go/os/testdata/issue37161/a b/libgo/go/os/testdata/issue37161/a new file mode 100644 index 00000000000..78981922613 --- /dev/null +++ b/libgo/go/os/testdata/issue37161/a @@ -0,0 +1 @@ +a diff --git a/libgo/go/os/testdata/issue37161/b b/libgo/go/os/testdata/issue37161/b new file mode 100644 index 00000000000..61780798228 --- /dev/null +++ b/libgo/go/os/testdata/issue37161/b @@ -0,0 +1 @@ +b diff --git a/libgo/go/os/testdata/issue37161/c b/libgo/go/os/testdata/issue37161/c new file mode 100644 index 00000000000..f2ad6c76f01 --- /dev/null +++ b/libgo/go/os/testdata/issue37161/c @@ -0,0 +1 @@ +c diff --git a/libgo/go/os/timeout_test.go b/libgo/go/os/timeout_test.go index 0fe03fa517f..99b94c2e4cb 100644 --- a/libgo/go/os/timeout_test.go +++ b/libgo/go/os/timeout_test.go @@ -10,7 +10,6 @@ package os_test import ( "fmt" - "internal/poll" "io" "io/ioutil" "math/rand" @@ -57,9 +56,9 @@ var readTimeoutTests = []struct { }{ // Tests that read deadlines work, even if there's data ready // to be read. - {-5 * time.Second, [2]error{poll.ErrTimeout, poll.ErrTimeout}}, + {-5 * time.Second, [2]error{os.ErrDeadlineExceeded, os.ErrDeadlineExceeded}}, - {50 * time.Millisecond, [2]error{nil, poll.ErrTimeout}}, + {50 * time.Millisecond, [2]error{nil, os.ErrDeadlineExceeded}}, } func TestReadTimeout(t *testing.T) { @@ -85,7 +84,7 @@ func TestReadTimeout(t *testing.T) { for { n, err := r.Read(b[:]) if xerr != nil { - if !os.IsTimeout(err) { + if !isDeadlineExceeded(err) { t.Fatalf("#%d/%d: %v", i, j, err) } } @@ -148,9 +147,9 @@ var writeTimeoutTests = []struct { }{ // Tests that write deadlines work, even if there's buffer // space available to write. - {-5 * time.Second, [2]error{poll.ErrTimeout, poll.ErrTimeout}}, + {-5 * time.Second, [2]error{os.ErrDeadlineExceeded, os.ErrDeadlineExceeded}}, - {10 * time.Millisecond, [2]error{nil, poll.ErrTimeout}}, + {10 * time.Millisecond, [2]error{nil, os.ErrDeadlineExceeded}}, } func TestWriteTimeout(t *testing.T) { @@ -172,7 +171,7 @@ func TestWriteTimeout(t *testing.T) { for { n, err := w.Write([]byte("WRITE TIMEOUT TEST")) if xerr != nil { - if !os.IsTimeout(err) { + if !isDeadlineExceeded(err) { t.Fatalf("%d: %v", j, err) } } @@ -246,7 +245,7 @@ func timeoutReader(r *os.File, d, min, max time.Duration, ch chan<- error) { var n int n, err = r.Read(b) t1 := time.Now() - if n != 0 || err == nil || !os.IsTimeout(err) { + if n != 0 || err == nil || !isDeadlineExceeded(err) { err = fmt.Errorf("Read did not return (0, timeout): (%d, %v)", n, err) return } @@ -275,7 +274,7 @@ func TestReadTimeoutFluctuation(t *testing.T) { case <-max.C: t.Fatal("Read took over 1s; expected 0.1s") case err := <-ch: - if !os.IsTimeout(err) { + if !isDeadlineExceeded(err) { t.Fatal(err) } } @@ -297,7 +296,7 @@ func timeoutWriter(w *os.File, d, min, max time.Duration, ch chan<- error) { } } t1 := time.Now() - if err == nil || !os.IsTimeout(err) { + if err == nil || !isDeadlineExceeded(err) { err = fmt.Errorf("Write did not return (any, timeout): (%d, %v)", n, err) return } @@ -327,7 +326,7 @@ func TestWriteTimeoutFluctuation(t *testing.T) { case <-max.C: t.Fatalf("Write took over %v; expected 0.1s", d) case err := <-ch: - if !os.IsTimeout(err) { + if !isDeadlineExceeded(err) { t.Fatal(err) } } @@ -438,7 +437,7 @@ func testVariousDeadlines(t *testing.T) { select { case res := <-actvch: - if os.IsTimeout(res.err) { + if !isDeadlineExceeded(err) { t.Logf("good client timeout after %v, reading %d bytes", res.d, res.n) } else { t.Fatalf("client Copy = %d, %v; want timeout", res.n, res.err) @@ -494,7 +493,7 @@ func TestReadWriteDeadlineRace(t *testing.T) { var b [1]byte for i := 0; i < N; i++ { _, err := r.Read(b[:]) - if err != nil && !os.IsTimeout(err) { + if err != nil && !isDeadlineExceeded(err) { t.Error("Read returned non-timeout error", err) } } @@ -504,7 +503,7 @@ func TestReadWriteDeadlineRace(t *testing.T) { var b [1]byte for i := 0; i < N; i++ { _, err := w.Write(b[:]) - if err != nil && !os.IsTimeout(err) { + if err != nil && !isDeadlineExceeded(err) { t.Error("Write returned non-timeout error", err) } } @@ -541,7 +540,7 @@ func TestRacyRead(t *testing.T) { _, err := r.Read(b1) copy(b1, b2) // Mutate b1 to trigger potential race if err != nil { - if !os.IsTimeout(err) { + if !isDeadlineExceeded(err) { t.Error(err) } r.SetReadDeadline(time.Now().Add(time.Millisecond)) @@ -580,7 +579,7 @@ func TestRacyWrite(t *testing.T) { _, err := w.Write(b1) copy(b1, b2) // Mutate b1 to trigger potential race if err != nil { - if !os.IsTimeout(err) { + if !isDeadlineExceeded(err) { t.Error(err) } w.SetWriteDeadline(time.Now().Add(time.Millisecond)) diff --git a/libgo/go/os/user/lookup_windows.go b/libgo/go/os/user/lookup_windows.go index faaddd2341f..f65773ced3a 100644 --- a/libgo/go/os/user/lookup_windows.go +++ b/libgo/go/os/user/lookup_windows.go @@ -44,7 +44,7 @@ func lookupFullNameServer(servername, username string) (string, error) { } defer syscall.NetApiBufferFree(p) i := (*syscall.UserInfo10)(unsafe.Pointer(p)) - return windows.UTF16PtrToString(i.FullName, 1024), nil + return windows.UTF16PtrToString(i.FullName), nil } func lookupFullName(domain, username, domainAndUser string) (string, error) { @@ -167,7 +167,7 @@ func listGroupsForUsernameAndDomain(username, domain string) ([]string, error) { if entry.Name == nil { continue } - sid, err := lookupGroupName(windows.UTF16PtrToString(entry.Name, 1024)) + sid, err := lookupGroupName(windows.UTF16PtrToString(entry.Name)) if err != nil { return nil, err } diff --git a/libgo/go/os/wait_wait6.go b/libgo/go/os/wait_wait6.go index 45bf649015f..5420b2db732 100644 --- a/libgo/go/os/wait_wait6.go +++ b/libgo/go/os/wait_wait6.go @@ -18,15 +18,20 @@ const _P_PID = 0 // It does not actually call p.Wait. func (p *Process) blockUntilWaitable() (bool, error) { var errno syscall.Errno - // The arguments on 32-bit FreeBSD look like the following: - // - freebsd32_wait6_args{ idtype, id1, id2, status, options, wrusage, info } or - // - freebsd32_wait6_args{ idtype, pad, id1, id2, status, options, wrusage, info } when PAD64_REQUIRED=1 on ARM, MIPS or PowerPC - if runtime.GOARCH == "386" { - _, _, errno = syscall.Syscall9(syscall.SYS_WAIT6, _P_PID, uintptr(p.Pid), 0, 0, syscall.WEXITED|syscall.WNOWAIT, 0, 0, 0, 0) - } else if runtime.GOARCH == "arm" { - _, _, errno = syscall.Syscall9(syscall.SYS_WAIT6, _P_PID, 0, uintptr(p.Pid), 0, 0, syscall.WEXITED|syscall.WNOWAIT, 0, 0, 0) - } else { - _, _, errno = syscall.Syscall6(syscall.SYS_WAIT6, _P_PID, uintptr(p.Pid), 0, syscall.WEXITED|syscall.WNOWAIT, 0, 0) + for { + // The arguments on 32-bit FreeBSD look like the following: + // - freebsd32_wait6_args{ idtype, id1, id2, status, options, wrusage, info } or + // - freebsd32_wait6_args{ idtype, pad, id1, id2, status, options, wrusage, info } when PAD64_REQUIRED=1 on ARM, MIPS or PowerPC + if runtime.GOARCH == "386" { + _, _, errno = syscall.Syscall9(syscall.SYS_WAIT6, _P_PID, uintptr(p.Pid), 0, 0, syscall.WEXITED|syscall.WNOWAIT, 0, 0, 0, 0) + } else if runtime.GOARCH == "arm" { + _, _, errno = syscall.Syscall9(syscall.SYS_WAIT6, _P_PID, 0, uintptr(p.Pid), 0, 0, syscall.WEXITED|syscall.WNOWAIT, 0, 0, 0) + } else { + _, _, errno = syscall.Syscall6(syscall.SYS_WAIT6, _P_PID, uintptr(p.Pid), 0, syscall.WEXITED|syscall.WNOWAIT, 0, 0) + } + if errno != syscall.EINTR { + break + } } runtime.KeepAlive(p) if errno != 0 { diff --git a/libgo/go/os/wait_waitid.go b/libgo/go/os/wait_waitid.go index 4bb77f9c542..2c39f9bcd94 100644 --- a/libgo/go/os/wait_waitid.go +++ b/libgo/go/os/wait_waitid.go @@ -23,12 +23,18 @@ const _P_PID = 1 func (p *Process) blockUntilWaitable() (bool, error) { // The waitid system call expects a pointer to a siginfo_t, // which is 128 bytes on all GNU/Linux systems. - // On Darwin, it requires greater than or equal to 64 bytes - // for darwin/{386,arm} and 104 bytes for darwin/amd64. + // On darwin/amd64, it requires 104 bytes. // We don't care about the values it returns. var siginfo [16]uint64 psig := &siginfo[0] - r, _, e := syscall.Syscall6(syscall.SYS_WAITID, _P_PID, uintptr(p.Pid), uintptr(unsafe.Pointer(psig)), syscall.WEXITED|syscall.WNOWAIT, 0, 0) + var r uintptr + var e syscall.Errno + for { + r, _, e = syscall.Syscall6(syscall.SYS_WAITID, _P_PID, uintptr(p.Pid), uintptr(unsafe.Pointer(psig)), syscall.WEXITED|syscall.WNOWAIT, 0, 0) + if e != syscall.EINTR { + break + } + } runtime.KeepAlive(p) // Check r as well as e because syscall.Syscall6 currently // just returns errno, and the SIGCHLD signal handler may diff --git a/libgo/go/path/filepath/match.go b/libgo/go/path/filepath/match.go index 46badb5e840..20a334805ba 100644 --- a/libgo/go/path/filepath/match.go +++ b/libgo/go/path/filepath/match.go @@ -310,14 +310,14 @@ func glob(dir, pattern string, matches []string) (m []string, e error) { m = matches fi, err := os.Stat(dir) if err != nil { - return + return // ignore I/O error } if !fi.IsDir() { - return + return // ignore I/O error } d, err := os.Open(dir) if err != nil { - return + return // ignore I/O error } defer d.Close() diff --git a/libgo/go/path/filepath/path_test.go b/libgo/go/path/filepath/path_test.go index d3f43a692fe..537d848a948 100644 --- a/libgo/go/path/filepath/path_test.go +++ b/libgo/go/path/filepath/path_test.go @@ -434,12 +434,9 @@ func chtmpdir(t *testing.T) (restore func()) { } func TestWalk(t *testing.T) { - if runtime.GOOS == "darwin" { - switch runtime.GOARCH { - case "arm", "arm64": - restore := chtmpdir(t) - defer restore() - } + if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" { + restore := chtmpdir(t) + defer restore() } tmpDir, err := ioutil.TempDir("", "TestWalk") @@ -1285,11 +1282,8 @@ func TestDriveLetterInEvalSymlinks(t *testing.T) { func TestBug3486(t *testing.T) { // https://golang.org/issue/3486 t.Skip("skipping test because gccgo sources are arranged differently.") - if runtime.GOOS == "darwin" { - switch runtime.GOARCH { - case "arm", "arm64": - t.Skipf("skipping on %s/%s", runtime.GOOS, runtime.GOARCH) - } + if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" { + t.Skipf("skipping on %s/%s", runtime.GOOS, runtime.GOARCH) } root, err := filepath.EvalSymlinks(runtime.GOROOT() + "/test") if err != nil { diff --git a/libgo/go/reflect/all_test.go b/libgo/go/reflect/all_test.go index e5ec052f7de..ee37359814b 100644 --- a/libgo/go/reflect/all_test.go +++ b/libgo/go/reflect/all_test.go @@ -350,6 +350,7 @@ func TestCanSetField(t *testing.T) { } type testCase struct { + // -1 means Addr().Elem() of current value index []int canSet bool } @@ -360,17 +361,33 @@ func TestCanSetField(t *testing.T) { val: ValueOf(&S1{}), cases: []testCase{ {[]int{0}, false}, + {[]int{0, -1}, false}, {[]int{0, 0}, false}, + {[]int{0, 0, -1}, false}, + {[]int{0, -1, 0}, false}, + {[]int{0, -1, 0, -1}, false}, {[]int{0, 1}, true}, + {[]int{0, 1, -1}, true}, + {[]int{0, -1, 1}, true}, + {[]int{0, -1, 1, -1}, true}, {[]int{1}, false}, + {[]int{1, -1}, false}, {[]int{2}, true}, + {[]int{2, -1}, true}, }, }, { val: ValueOf(&S2{embed: &embed{}}), cases: []testCase{ {[]int{0}, false}, + {[]int{0, -1}, false}, {[]int{0, 0}, false}, + {[]int{0, 0, -1}, false}, + {[]int{0, -1, 0}, false}, + {[]int{0, -1, 0, -1}, false}, {[]int{0, 1}, true}, + {[]int{0, 1, -1}, true}, + {[]int{0, -1, 1}, true}, + {[]int{0, -1, 1, -1}, true}, {[]int{1}, false}, {[]int{2}, true}, }, @@ -378,8 +395,15 @@ func TestCanSetField(t *testing.T) { val: ValueOf(&S3{}), cases: []testCase{ {[]int{0}, true}, + {[]int{0, -1}, true}, {[]int{0, 0}, false}, + {[]int{0, 0, -1}, false}, + {[]int{0, -1, 0}, false}, + {[]int{0, -1, 0, -1}, false}, {[]int{0, 1}, true}, + {[]int{0, 1, -1}, true}, + {[]int{0, -1, 1}, true}, + {[]int{0, -1, 1, -1}, true}, {[]int{1}, false}, {[]int{2}, true}, }, @@ -387,8 +411,15 @@ func TestCanSetField(t *testing.T) { val: ValueOf(&S4{Embed: &Embed{}}), cases: []testCase{ {[]int{0}, true}, + {[]int{0, -1}, true}, {[]int{0, 0}, false}, + {[]int{0, 0, -1}, false}, + {[]int{0, -1, 0}, false}, + {[]int{0, -1, 0, -1}, false}, {[]int{0, 1}, true}, + {[]int{0, 1, -1}, true}, + {[]int{0, -1, 1}, true}, + {[]int{0, -1, 1, -1}, true}, {[]int{1}, false}, {[]int{2}, true}, }, @@ -402,7 +433,11 @@ func TestCanSetField(t *testing.T) { if f.Kind() == Ptr { f = f.Elem() } - f = f.Field(i) + if i == -1 { + f = f.Addr().Elem() + } else { + f = f.Field(i) + } } if got := f.CanSet(); got != tc.canSet { t.Errorf("CanSet() = %v, want %v", got, tc.canSet) @@ -1657,6 +1692,55 @@ func TestSelect(t *testing.T) { } } +func TestSelectMaxCases(t *testing.T) { + var sCases []SelectCase + channel := make(chan int) + close(channel) + for i := 0; i < 65536; i++ { + sCases = append(sCases, SelectCase{ + Dir: SelectRecv, + Chan: ValueOf(channel), + }) + } + // Should not panic + _, _, _ = Select(sCases) + sCases = append(sCases, SelectCase{ + Dir: SelectRecv, + Chan: ValueOf(channel), + }) + defer func() { + if err := recover(); err != nil { + if err.(string) != "reflect.Select: too many cases (max 65536)" { + t.Fatalf("unexpected error from select call with greater than max supported cases") + } + } else { + t.Fatalf("expected select call to panic with greater than max supported cases") + } + }() + // Should panic + _, _, _ = Select(sCases) +} + +func BenchmarkSelect(b *testing.B) { + channel := make(chan int) + close(channel) + var cases []SelectCase + for i := 0; i < 8; i++ { + cases = append(cases, SelectCase{ + Dir: SelectRecv, + Chan: ValueOf(channel), + }) + } + for _, numCases := range []int{1, 4, 8} { + b.Run(strconv.Itoa(numCases), func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _, _, _ = Select(cases[:numCases]) + } + }) + } +} + // selectWatch and the selectWatcher are a watchdog mechanism for running Select. // If the selectWatcher notices that the select has been blocked for >1 second, it prints // an error describing the select and panics the entire test binary. @@ -2001,7 +2085,7 @@ func TestMakeFuncValidReturnAssignments(t *testing.T) { func TestMakeFuncInvalidReturnAssignments(t *testing.T) { // Type doesn't implement the required interface. - shouldPanic(func() { + shouldPanic("", func() { var f func() error f = MakeFunc(TypeOf(f), func([]Value) []Value { return []Value{ValueOf(int(7))} @@ -2009,7 +2093,7 @@ func TestMakeFuncInvalidReturnAssignments(t *testing.T) { f() }) // Assigning to an interface with additional methods. - shouldPanic(func() { + shouldPanic("", func() { var f func() io.ReadWriteCloser f = MakeFunc(TypeOf(f), func([]Value) []Value { var w io.WriteCloser = &WC{} @@ -2018,7 +2102,7 @@ func TestMakeFuncInvalidReturnAssignments(t *testing.T) { f() }) // Directional channels can't be assigned to bidirectional ones. - shouldPanic(func() { + shouldPanic("", func() { var f func() chan int f = MakeFunc(TypeOf(f), func([]Value) []Value { var c <-chan int = make(chan int) @@ -2027,7 +2111,7 @@ func TestMakeFuncInvalidReturnAssignments(t *testing.T) { f() }) // Two named types which are otherwise identical. - shouldPanic(func() { + shouldPanic("", func() { type T struct{ a, b, c int } type U struct{ a, b, c int } var f func() T @@ -2491,7 +2575,7 @@ func TestMethod5(t *testing.T) { var tnil Tinter vnil := ValueOf(&tnil).Elem() - shouldPanic(func() { vnil.Method(0) }) + shouldPanic("Method", func() { vnil.Method(0) }) } func TestInterfaceSet(t *testing.T) { @@ -3203,9 +3287,9 @@ func TestSlice3(t *testing.T) { t.Errorf("xs.Slice3(3, 5, 7)[0:4] = %v", v[0:4]) } rv := ValueOf(&xs).Elem() - shouldPanic(func() { rv.Slice3(1, 2, 1) }) - shouldPanic(func() { rv.Slice3(1, 1, 11) }) - shouldPanic(func() { rv.Slice3(2, 2, 1) }) + shouldPanic("Slice3", func() { rv.Slice3(1, 2, 1) }) + shouldPanic("Slice3", func() { rv.Slice3(1, 1, 11) }) + shouldPanic("Slice3", func() { rv.Slice3(2, 2, 1) }) xa := [8]int{10, 20, 30, 40, 50, 60, 70, 80} v = ValueOf(&xa).Elem().Slice3(2, 5, 6).Interface().([]int) @@ -3219,13 +3303,13 @@ func TestSlice3(t *testing.T) { t.Errorf("xs.Slice(2, 5, 6)[0:4] = %v", v[0:4]) } rv = ValueOf(&xa).Elem() - shouldPanic(func() { rv.Slice3(1, 2, 1) }) - shouldPanic(func() { rv.Slice3(1, 1, 11) }) - shouldPanic(func() { rv.Slice3(2, 2, 1) }) + shouldPanic("Slice3", func() { rv.Slice3(1, 2, 1) }) + shouldPanic("Slice3", func() { rv.Slice3(1, 1, 11) }) + shouldPanic("Slice3", func() { rv.Slice3(2, 2, 1) }) s := "hello world" rv = ValueOf(&s).Elem() - shouldPanic(func() { rv.Slice3(1, 2, 3) }) + shouldPanic("Slice3", func() { rv.Slice3(1, 2, 3) }) rv = ValueOf(&xs).Elem() rv = rv.Slice3(3, 5, 7) @@ -3242,11 +3326,11 @@ func TestSetLenCap(t *testing.T) { xa := [8]int{10, 20, 30, 40, 50, 60, 70, 80} vs := ValueOf(&xs).Elem() - shouldPanic(func() { vs.SetLen(10) }) - shouldPanic(func() { vs.SetCap(10) }) - shouldPanic(func() { vs.SetLen(-1) }) - shouldPanic(func() { vs.SetCap(-1) }) - shouldPanic(func() { vs.SetCap(6) }) // smaller than len + shouldPanic("SetLen", func() { vs.SetLen(10) }) + shouldPanic("SetCap", func() { vs.SetCap(10) }) + shouldPanic("SetLen", func() { vs.SetLen(-1) }) + shouldPanic("SetCap", func() { vs.SetCap(-1) }) + shouldPanic("SetCap", func() { vs.SetCap(6) }) // smaller than len vs.SetLen(5) if len(xs) != 5 || cap(xs) != 8 { t.Errorf("after SetLen(5), len, cap = %d, %d, want 5, 8", len(xs), cap(xs)) @@ -3259,12 +3343,12 @@ func TestSetLenCap(t *testing.T) { if len(xs) != 5 || cap(xs) != 5 { t.Errorf("after SetCap(5), len, cap = %d, %d, want 5, 5", len(xs), cap(xs)) } - shouldPanic(func() { vs.SetCap(4) }) // smaller than len - shouldPanic(func() { vs.SetLen(6) }) // bigger than cap + shouldPanic("SetCap", func() { vs.SetCap(4) }) // smaller than len + shouldPanic("SetLen", func() { vs.SetLen(6) }) // bigger than cap va := ValueOf(&xa).Elem() - shouldPanic(func() { va.SetLen(8) }) - shouldPanic(func() { va.SetCap(8) }) + shouldPanic("SetLen", func() { va.SetLen(8) }) + shouldPanic("SetCap", func() { va.SetCap(8) }) } func TestVariadic(t *testing.T) { @@ -3422,16 +3506,16 @@ func TestUnexported(t *testing.T) { isValid(v.Elem().Field(1)) isValid(v.Elem().FieldByName("x")) isValid(v.Elem().FieldByName("y")) - shouldPanic(func() { v.Elem().Field(0).Interface() }) - shouldPanic(func() { v.Elem().Field(1).Interface() }) - shouldPanic(func() { v.Elem().FieldByName("x").Interface() }) - shouldPanic(func() { v.Elem().FieldByName("y").Interface() }) - shouldPanic(func() { v.Type().Method(0) }) + shouldPanic("Interface", func() { v.Elem().Field(0).Interface() }) + shouldPanic("Interface", func() { v.Elem().Field(1).Interface() }) + shouldPanic("Interface", func() { v.Elem().FieldByName("x").Interface() }) + shouldPanic("Interface", func() { v.Elem().FieldByName("y").Interface() }) + shouldPanic("Method", func() { v.Type().Method(0) }) } func TestSetPanic(t *testing.T) { ok := func(f func()) { f() } - bad := shouldPanic + bad := func(f func()) { shouldPanic("Set", f) } clear := func(v Value) { v.Set(Zero(v.Type())) } type t0 struct { @@ -3548,56 +3632,75 @@ func TestCallPanic(t *testing.T) { namedT2 T2 // 7 } ok := func(f func()) { f() } - bad := shouldPanic + badCall := func(f func()) { shouldPanic("Call", f) } + badMethod := func(f func()) { shouldPanic("Method", f) } call := func(v Value) { v.Call(nil) } i := timp(0) v := ValueOf(T{i, i, i, i, T2{i, i}, i, i, T2{i, i}}) - ok(func() { call(v.Field(0).Method(0)) }) // .t0.W - bad(func() { call(v.Field(0).Elem().Method(0)) }) // .t0.W - bad(func() { call(v.Field(0).Method(1)) }) // .t0.w - bad(func() { call(v.Field(0).Elem().Method(2)) }) // .t0.w - ok(func() { call(v.Field(1).Method(0)) }) // .T1.Y - ok(func() { call(v.Field(1).Elem().Method(0)) }) // .T1.Y - bad(func() { call(v.Field(1).Method(1)) }) // .T1.y - bad(func() { call(v.Field(1).Elem().Method(2)) }) // .T1.y - - ok(func() { call(v.Field(2).Method(0)) }) // .NamedT0.W - ok(func() { call(v.Field(2).Elem().Method(0)) }) // .NamedT0.W - bad(func() { call(v.Field(2).Method(1)) }) // .NamedT0.w - bad(func() { call(v.Field(2).Elem().Method(2)) }) // .NamedT0.w - - ok(func() { call(v.Field(3).Method(0)) }) // .NamedT1.Y - ok(func() { call(v.Field(3).Elem().Method(0)) }) // .NamedT1.Y - bad(func() { call(v.Field(3).Method(1)) }) // .NamedT1.y - bad(func() { call(v.Field(3).Elem().Method(3)) }) // .NamedT1.y - - ok(func() { call(v.Field(4).Field(0).Method(0)) }) // .NamedT2.T1.Y - ok(func() { call(v.Field(4).Field(0).Elem().Method(0)) }) // .NamedT2.T1.W - ok(func() { call(v.Field(4).Field(1).Method(0)) }) // .NamedT2.t0.W - bad(func() { call(v.Field(4).Field(1).Elem().Method(0)) }) // .NamedT2.t0.W - - bad(func() { call(v.Field(5).Method(0)) }) // .namedT0.W - bad(func() { call(v.Field(5).Elem().Method(0)) }) // .namedT0.W - bad(func() { call(v.Field(5).Method(1)) }) // .namedT0.w - bad(func() { call(v.Field(5).Elem().Method(2)) }) // .namedT0.w - - bad(func() { call(v.Field(6).Method(0)) }) // .namedT1.Y - bad(func() { call(v.Field(6).Elem().Method(0)) }) // .namedT1.Y - bad(func() { call(v.Field(6).Method(0)) }) // .namedT1.y - bad(func() { call(v.Field(6).Elem().Method(0)) }) // .namedT1.y - - bad(func() { call(v.Field(7).Field(0).Method(0)) }) // .namedT2.T1.Y - bad(func() { call(v.Field(7).Field(0).Elem().Method(0)) }) // .namedT2.T1.W - bad(func() { call(v.Field(7).Field(1).Method(0)) }) // .namedT2.t0.W - bad(func() { call(v.Field(7).Field(1).Elem().Method(0)) }) // .namedT2.t0.W -} - -func shouldPanic(f func()) { + badCall(func() { call(v.Field(0).Method(0)) }) // .t0.W + badCall(func() { call(v.Field(0).Elem().Method(0)) }) // .t0.W + badCall(func() { call(v.Field(0).Method(1)) }) // .t0.w + badMethod(func() { call(v.Field(0).Elem().Method(2)) }) // .t0.w + ok(func() { call(v.Field(1).Method(0)) }) // .T1.Y + ok(func() { call(v.Field(1).Elem().Method(0)) }) // .T1.Y + badCall(func() { call(v.Field(1).Method(1)) }) // .T1.y + badMethod(func() { call(v.Field(1).Elem().Method(2)) }) // .T1.y + + ok(func() { call(v.Field(2).Method(0)) }) // .NamedT0.W + ok(func() { call(v.Field(2).Elem().Method(0)) }) // .NamedT0.W + badCall(func() { call(v.Field(2).Method(1)) }) // .NamedT0.w + badMethod(func() { call(v.Field(2).Elem().Method(2)) }) // .NamedT0.w + + ok(func() { call(v.Field(3).Method(0)) }) // .NamedT1.Y + ok(func() { call(v.Field(3).Elem().Method(0)) }) // .NamedT1.Y + badCall(func() { call(v.Field(3).Method(1)) }) // .NamedT1.y + badMethod(func() { call(v.Field(3).Elem().Method(3)) }) // .NamedT1.y + + ok(func() { call(v.Field(4).Field(0).Method(0)) }) // .NamedT2.T1.Y + ok(func() { call(v.Field(4).Field(0).Elem().Method(0)) }) // .NamedT2.T1.W + badCall(func() { call(v.Field(4).Field(1).Method(0)) }) // .NamedT2.t0.W + badCall(func() { call(v.Field(4).Field(1).Elem().Method(0)) }) // .NamedT2.t0.W + + badCall(func() { call(v.Field(5).Method(0)) }) // .namedT0.W + badCall(func() { call(v.Field(5).Elem().Method(0)) }) // .namedT0.W + badCall(func() { call(v.Field(5).Method(1)) }) // .namedT0.w + badMethod(func() { call(v.Field(5).Elem().Method(2)) }) // .namedT0.w + + badCall(func() { call(v.Field(6).Method(0)) }) // .namedT1.Y + badCall(func() { call(v.Field(6).Elem().Method(0)) }) // .namedT1.Y + badCall(func() { call(v.Field(6).Method(0)) }) // .namedT1.y + badCall(func() { call(v.Field(6).Elem().Method(0)) }) // .namedT1.y + + badCall(func() { call(v.Field(7).Field(0).Method(0)) }) // .namedT2.T1.Y + badCall(func() { call(v.Field(7).Field(0).Elem().Method(0)) }) // .namedT2.T1.W + badCall(func() { call(v.Field(7).Field(1).Method(0)) }) // .namedT2.t0.W + badCall(func() { call(v.Field(7).Field(1).Elem().Method(0)) }) // .namedT2.t0.W +} + +func shouldPanic(expect string, f func()) { defer func() { - if recover() == nil { + r := recover() + if r == nil { panic("did not panic") } + if expect != "" { + var s string + switch r := r.(type) { + case string: + s = r + case *ValueError: + s = r.Error() + default: + panic(fmt.Sprintf("panicked with unexpected type %T", r)) + } + if !strings.HasPrefix(s, "reflect") { + panic(`panic string does not start with "reflect": ` + s) + } + if !strings.Contains(s, expect) { + panic(`panic string does not contain "` + expect + `": ` + s) + } + } }() f() } @@ -4150,6 +4253,40 @@ func TestConvert(t *testing.T) { } } +var gFloat32 float32 + +func TestConvertNaNs(t *testing.T) { + const snan uint32 = 0x7f800001 + + // Test to see if a store followed by a load of a signaling NaN + // maintains the signaling bit. The only platform known to fail + // this test is 386,GO386=387. The real test below will always fail + // if the platform can't even store+load a float without mucking + // with the bits. + gFloat32 = math.Float32frombits(snan) + runtime.Gosched() // make sure we don't optimize the store/load away + r := math.Float32bits(gFloat32) + if r != snan { + // This should only happen on 386,GO386=387. We have no way to + // test for 387, so we just make sure we're at least on 386. + if runtime.GOARCH != "386" { + t.Errorf("store/load of sNaN not faithful") + } + t.Skip("skipping test, float store+load not faithful") + } + + type myFloat32 float32 + x := V(myFloat32(math.Float32frombits(snan))) + y := x.Convert(TypeOf(float32(0))) + z := y.Interface().(float32) + if got := math.Float32bits(z); got != snan { + if runtime.GOARCH == "386" { + t.Skip("skipping test, float conversion not faithful") + } + t.Errorf("signaling nan conversion got %x, want %x", got, snan) + } +} + type ComparableStruct struct { X int } @@ -4401,7 +4538,7 @@ func TestArrayOfAlg(t *testing.T) { at = ArrayOf(6, TypeOf([]int(nil))) v1 = New(at).Elem() - shouldPanic(func() { _ = v1.Interface() == v1.Interface() }) + shouldPanic("", func() { _ = v1.Interface() == v1.Interface() }) } func TestArrayOfGenericAlg(t *testing.T) { @@ -4545,23 +4682,23 @@ func TestSliceOfGC(t *testing.T) { func TestStructOfFieldName(t *testing.T) { // invalid field name "1nvalid" - shouldPanic(func() { + shouldPanic("has invalid name", func() { StructOf([]StructField{ - {Name: "valid", Type: TypeOf("")}, + {Name: "Valid", Type: TypeOf("")}, {Name: "1nvalid", Type: TypeOf("")}, }) }) // invalid field name "+" - shouldPanic(func() { + shouldPanic("has invalid name", func() { StructOf([]StructField{ - {Name: "val1d", Type: TypeOf("")}, + {Name: "Val1d", Type: TypeOf("")}, {Name: "+", Type: TypeOf("")}, }) }) // no field name - shouldPanic(func() { + shouldPanic("has no name", func() { StructOf([]StructField{ {Name: "", Type: TypeOf("")}, }) @@ -4689,19 +4826,19 @@ func TestStructOf(t *testing.T) { } // check duplicate names - shouldPanic(func() { + shouldPanic("duplicate field", func() { StructOf([]StructField{ - {Name: "string", Type: TypeOf("")}, - {Name: "string", Type: TypeOf("")}, + {Name: "string", PkgPath: "p", Type: TypeOf("")}, + {Name: "string", PkgPath: "p", Type: TypeOf("")}, }) }) - shouldPanic(func() { + shouldPanic("has no name", func() { StructOf([]StructField{ {Type: TypeOf("")}, - {Name: "string", Type: TypeOf("")}, + {Name: "string", PkgPath: "p", Type: TypeOf("")}, }) }) - shouldPanic(func() { + shouldPanic("has no name", func() { StructOf([]StructField{ {Type: TypeOf("")}, {Type: TypeOf("")}, @@ -4924,7 +5061,7 @@ func TestStructOfAlg(t *testing.T) { st = StructOf([]StructField{{Name: "X", Tag: "x", Type: TypeOf([]int(nil))}}) v1 = New(st).Elem() - shouldPanic(func() { _ = v1.Interface() == v1.Interface() }) + shouldPanic("", func() { _ = v1.Interface() == v1.Interface() }) } func TestStructOfGenericAlg(t *testing.T) { @@ -5258,7 +5395,7 @@ func TestStructOfWithInterface(t *testing.T) { rt := StructOf(fields) rv := New(rt).Elem() // This should panic since the pointer is nil. - shouldPanic(func() { + shouldPanic("", func() { rv.Interface().(IfaceSet).Set(want) }) @@ -5272,7 +5409,7 @@ func TestStructOfWithInterface(t *testing.T) { rt = StructOf(fields) rv = New(rt).Elem() // This should panic since the pointer is nil. - shouldPanic(func() { + shouldPanic("", func() { rv.Interface().(IfaceSet).Set(want) }) @@ -5294,7 +5431,7 @@ func TestStructOfWithInterface(t *testing.T) { // With the current implementation this is expected to panic. // Ideally it should work and we should be able to see a panic // if we call the Set method. - shouldPanic(func() { + shouldPanic("", func() { StructOf(fields) }) @@ -5315,7 +5452,7 @@ func TestStructOfWithInterface(t *testing.T) { // With the current implementation this is expected to panic. // Ideally it should work and we should be able to call the // Set and Get methods. - shouldPanic(func() { + shouldPanic("", func() { StructOf(fields) }) } @@ -5349,7 +5486,7 @@ func TestStructOfDifferentPkgPath(t *testing.T) { Type: TypeOf(int(0)), }, } - shouldPanic(func() { + shouldPanic("different PkgPath", func() { StructOf(fields) }) } @@ -5466,7 +5603,7 @@ func TestMapOf(t *testing.T) { checkSameType(t, MapOf(TypeOf(V(0)), TypeOf(K(""))), map[V]K(nil)) // check that invalid key type panics - shouldPanic(func() { MapOf(TypeOf((func())(nil)), TypeOf(false)) }) + shouldPanic("invalid key type", func() { MapOf(TypeOf((func())(nil)), TypeOf(false)) }) } func TestMapOfGCKeys(t *testing.T) { @@ -5598,8 +5735,8 @@ func TestFuncOf(t *testing.T) { // check that variadic requires last element be a slice. FuncOf([]Type{TypeOf(1), TypeOf(""), SliceOf(TypeOf(false))}, nil, true) - shouldPanic(func() { FuncOf([]Type{TypeOf(0), TypeOf(""), TypeOf(false)}, nil, true) }) - shouldPanic(func() { FuncOf(nil, nil, true) }) + shouldPanic("must be slice", func() { FuncOf([]Type{TypeOf(0), TypeOf(""), TypeOf(false)}, nil, true) }) + shouldPanic("must be slice", func() { FuncOf(nil, nil, true) }) } type B1 struct { @@ -6845,7 +6982,7 @@ func TestUnaddressableField(t *testing.T) { } lv := ValueOf(&localBuffer).Elem() rv := ValueOf(b) - shouldPanic(func() { + shouldPanic("Set", func() { lv.Set(rv) }) } diff --git a/libgo/go/reflect/swapper.go b/libgo/go/reflect/swapper.go index 016f95d7b01..0cf40666b1e 100644 --- a/libgo/go/reflect/swapper.go +++ b/libgo/go/reflect/swapper.go @@ -4,7 +4,10 @@ package reflect -import "unsafe" +import ( + "internal/unsafeheader" + "unsafe" +) // Swapper returns a function that swaps the elements in the provided // slice. @@ -58,7 +61,7 @@ func Swapper(slice interface{}) func(i, j int) { } } - s := (*sliceHeader)(v.ptr) + s := (*unsafeheader.Slice)(v.ptr) tmp := unsafe_New(typ) // swap scratch space return func(i, j int) { diff --git a/libgo/go/reflect/value.go b/libgo/go/reflect/value.go index 7c6a3e8a935..e60f84fe78d 100644 --- a/libgo/go/reflect/value.go +++ b/libgo/go/reflect/value.go @@ -5,6 +5,7 @@ package reflect import ( + "internal/unsafeheader" "math" "runtime" "unsafe" @@ -178,6 +179,17 @@ func methodName() string { return f.Name() } +// methodNameSkip is like methodName, but skips another stack frame. +// This is a separate function so that reflect.flag.mustBe will be inlined. +func methodNameSkip() string { + pc, _, _, _ := runtime.Caller(3) + f := runtime.FuncForPC(pc) + if f == nil { + return "unknown method" + } + return f.Name() +} + // emptyInterface is the header for an interface{} value. type emptyInterface struct { typ *rtype @@ -217,10 +229,10 @@ func (f flag) mustBeExported() { func (f flag) mustBeExportedSlow() { if f == 0 { - panic(&ValueError{methodName(), Invalid}) + panic(&ValueError{methodNameSkip(), Invalid}) } if f&flagRO != 0 { - panic("reflect: " + methodName() + " using value obtained using unexported field") + panic("reflect: " + methodNameSkip() + " using value obtained using unexported field") } } @@ -235,14 +247,14 @@ func (f flag) mustBeAssignable() { func (f flag) mustBeAssignableSlow() { if f == 0 { - panic(&ValueError{methodName(), Invalid}) + panic(&ValueError{methodNameSkip(), Invalid}) } // Assignable if addressable and not read-only. if f&flagRO != 0 { - panic("reflect: " + methodName() + " using value obtained using unexported field") + panic("reflect: " + methodNameSkip() + " using value obtained using unexported field") } if f&flagAddr == 0 { - panic("reflect: " + methodName() + " using unaddressable value") + panic("reflect: " + methodNameSkip() + " using unaddressable value") } } @@ -255,7 +267,10 @@ func (v Value) Addr() Value { if v.flag&flagAddr == 0 { panic("reflect.Value.Addr of unaddressable value") } - return Value{v.typ.ptrTo(), v.ptr, v.flag.ro() | flag(Ptr)} + // Preserve flagRO instead of using v.flag.ro() so that + // v.Addr().Elem() is equivalent to v (#32772) + fl := v.flag & flagRO + return Value{v.typ.ptrTo(), v.ptr, fl | flag(Ptr)} } // Bool returns v's underlying value. @@ -563,7 +578,7 @@ func (v Value) Cap() int { return chancap(v.pointer()) case Slice: // Slice is always bigger than a word; assume flagIndir. - return (*sliceHeader)(v.ptr).Cap + return (*unsafeheader.Slice)(v.ptr).Cap } panic(&ValueError{"reflect.Value.Cap", v.kind()}) } @@ -742,7 +757,7 @@ func (v Value) Index(i int) Value { case Slice: // Element flag same as Elem of Ptr. // Addressable, indirect, possibly read-only. - s := (*sliceHeader)(v.ptr) + s := (*unsafeheader.Slice)(v.ptr) if uint(i) >= uint(s.Len) { panic("reflect: slice index out of range") } @@ -753,7 +768,7 @@ func (v Value) Index(i int) Value { return Value{typ, val, fl} case String: - s := (*stringHeader)(v.ptr) + s := (*unsafeheader.String)(v.ptr) if uint(i) >= uint(s.Len) { panic("reflect: string index out of range") } @@ -950,10 +965,10 @@ func (v Value) Len() int { return maplen(v.pointer()) case Slice: // Slice is bigger than a word; assume flagIndir. - return (*sliceHeader)(v.ptr).Len + return (*unsafeheader.Slice)(v.ptr).Len case String: // String is bigger than a word; assume flagIndir. - return (*stringHeader)(v.ptr).Len + return (*unsafeheader.String)(v.ptr).Len } panic(&ValueError{"reflect.Value.Len", v.kind()}) } @@ -1122,7 +1137,7 @@ func (v Value) Method(i int) Value { if v.typ.Kind() == Interface && v.IsNil() { panic("reflect: Method on nil interface value") } - fl := v.flag & (flagStickyRO | flagIndir) // Clear flagEmbedRO + fl := v.flag.ro() | (v.flag & flagIndir) fl |= flag(Func) fl |= flag(i)< uint(s.Cap) { panic("reflect: slice length out of range in SetLen") } @@ -1442,7 +1457,7 @@ func (v Value) SetLen(n int) { func (v Value) SetCap(n int) { v.mustBeAssignable() v.mustBe(Slice) - s := (*sliceHeader)(v.ptr) + s := (*unsafeheader.Slice)(v.ptr) if n < s.Len || n > s.Cap { panic("reflect: slice capacity out of range in SetCap") } @@ -1544,18 +1559,18 @@ func (v Value) Slice(i, j int) Value { case Slice: typ = (*sliceType)(unsafe.Pointer(v.typ)) - s := (*sliceHeader)(v.ptr) + s := (*unsafeheader.Slice)(v.ptr) base = s.Data cap = s.Cap case String: - s := (*stringHeader)(v.ptr) + s := (*unsafeheader.String)(v.ptr) if i < 0 || j < i || j > s.Len { panic("reflect.Value.Slice: string slice index out of bounds") } - var t stringHeader + var t unsafeheader.String if i < s.Len { - t = stringHeader{arrayAt(s.Data, i, 1, "i < s.Len"), j - i} + t = unsafeheader.String{Data: arrayAt(s.Data, i, 1, "i < s.Len"), Len: j - i} } return Value{v.typ, unsafe.Pointer(&t), v.flag} } @@ -1567,8 +1582,8 @@ func (v Value) Slice(i, j int) Value { // Declare slice so that gc can see the base pointer in it. var x []unsafe.Pointer - // Reinterpret as *sliceHeader to edit. - s := (*sliceHeader)(unsafe.Pointer(&x)) + // Reinterpret as *unsafeheader.Slice to edit. + s := (*unsafeheader.Slice)(unsafe.Pointer(&x)) s.Len = j - i s.Cap = cap - i if cap-i > 0 { @@ -1606,7 +1621,7 @@ func (v Value) Slice3(i, j, k int) Value { case Slice: typ = (*sliceType)(unsafe.Pointer(v.typ)) - s := (*sliceHeader)(v.ptr) + s := (*unsafeheader.Slice)(v.ptr) base = s.Data cap = s.Cap } @@ -1619,8 +1634,8 @@ func (v Value) Slice3(i, j, k int) Value { // can see the base pointer in it. var x []unsafe.Pointer - // Reinterpret as *sliceHeader to edit. - s := (*sliceHeader)(unsafe.Pointer(&x)) + // Reinterpret as *unsafeheader.Slice to edit. + s := (*unsafeheader.Slice)(unsafe.Pointer(&x)) s.Len = j - i s.Cap = k - i if k-i > 0 { @@ -1757,12 +1772,6 @@ type StringHeader struct { Len int } -// stringHeader is a safe version of StringHeader used within this package. -type stringHeader struct { - Data unsafe.Pointer - Len int -} - // SliceHeader is the runtime representation of a slice. // It cannot be used safely or portably and its representation may // change in a later release. @@ -1775,13 +1784,6 @@ type SliceHeader struct { Cap int } -// sliceHeader is a safe version of SliceHeader used within this package. -type sliceHeader struct { - Data unsafe.Pointer - Len int - Cap int -} - func typesMustMatch(what string, t1, t2 Type) { if t1 != t2 { panic(what + ": " + t1.String() + " != " + t2.String()) @@ -1882,22 +1884,22 @@ func Copy(dst, src Value) int { typesMustMatch("reflect.Copy", de, se) } - var ds, ss sliceHeader + var ds, ss unsafeheader.Slice if dk == Array { ds.Data = dst.ptr ds.Len = dst.Len() ds.Cap = ds.Len } else { - ds = *(*sliceHeader)(dst.ptr) + ds = *(*unsafeheader.Slice)(dst.ptr) } if sk == Array { ss.Data = src.ptr ss.Len = src.Len() ss.Cap = ss.Len } else if sk == Slice { - ss = *(*sliceHeader)(src.ptr) + ss = *(*unsafeheader.Slice)(src.ptr) } else { - sh := *(*stringHeader)(src.ptr) + sh := *(*unsafeheader.String)(src.ptr) ss.Data = sh.Data ss.Len = sh.Len ss.Cap = sh.Len @@ -1964,11 +1966,23 @@ type SelectCase struct { // and, if that case was a receive operation, the value received and a // boolean indicating whether the value corresponds to a send on the channel // (as opposed to a zero value received because the channel is closed). +// Select supports a maximum of 65536 cases. func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) { + if len(cases) > 65536 { + panic("reflect.Select: too many cases (max 65536)") + } // NOTE: Do not trust that caller is not modifying cases data underfoot. // The range is safe because the caller cannot modify our copy of the len // and each iteration makes its own copy of the value c. - runcases := make([]runtimeSelect, len(cases)) + var runcases []runtimeSelect + if len(cases) > 4 { + // Slice is heap allocated due to runtime dependent capacity. + runcases = make([]runtimeSelect, len(cases)) + } else { + // Slice can be stack allocated due to constant capacity. + runcases = make([]runtimeSelect, len(cases), 4) + } + haveDefault := false for i, c := range cases { rc := &runcases[i] @@ -2073,7 +2087,7 @@ func MakeSlice(typ Type, len, cap int) Value { panic("reflect.MakeSlice: len > cap") } - s := sliceHeader{unsafe_NewArray(typ.Elem().(*rtype), cap), len, cap} + s := unsafeheader.Slice{Data: unsafe_NewArray(typ.Elem().(*rtype), cap), Len: len, Cap: cap} return Value{typ.(*rtype), unsafe.Pointer(&s), flagIndir | flag(Slice)} } @@ -2346,6 +2360,14 @@ func makeFloat(f flag, v float64, t Type) Value { return Value{typ, ptr, f | flagIndir | flag(typ.Kind())} } +// makeFloat returns a Value of type t equal to v, where t is a float32 type. +func makeFloat32(f flag, v float32, t Type) Value { + typ := t.common() + ptr := unsafe_New(typ) + *(*float32)(ptr) = v + return Value{typ, ptr, f | flagIndir | flag(typ.Kind())} +} + // makeComplex returns a Value of type t equal to v (possibly truncated to complex64), // where t is a complex64 or complex128 type. func makeComplex(f flag, v complex128, t Type) Value { @@ -2418,6 +2440,12 @@ func cvtUintFloat(v Value, t Type) Value { // convertOp: floatXX -> floatXX func cvtFloat(v Value, t Type) Value { + if v.Type().Kind() == Float32 && t.Kind() == Float32 { + // Don't do any conversion if both types have underlying type float32. + // This avoids converting to float64 and back, which will + // convert a signaling NaN to a quiet NaN. See issue 36400. + return makeFloat32(v.flag.ro(), *(*float32)(v.ptr), t) + } return makeFloat(v.flag.ro(), v.Float(), t) } @@ -2428,12 +2456,12 @@ func cvtComplex(v Value, t Type) Value { // convertOp: intXX -> string func cvtIntString(v Value, t Type) Value { - return makeString(v.flag.ro(), string(v.Int()), t) + return makeString(v.flag.ro(), string(rune(v.Int())), t) } // convertOp: uintXX -> string func cvtUintString(v Value, t Type) Value { - return makeString(v.flag.ro(), string(v.Uint()), t) + return makeString(v.flag.ro(), string(rune(v.Uint())), t) } // convertOp: []byte -> string @@ -2557,7 +2585,7 @@ func typedmemmove(t *rtype, dst, src unsafe.Pointer) // typedslicecopy copies a slice of elemType values from src to dst, // returning the number of elements copied. //go:noescape -func typedslicecopy(elemType *rtype, dst, src sliceHeader) int +func typedslicecopy(elemType *rtype, dst, src unsafeheader.Slice) int //go:noescape func typehash(t *rtype, p unsafe.Pointer, h uintptr) uintptr diff --git a/libgo/go/regexp/all_test.go b/libgo/go/regexp/all_test.go index 626a69142f5..be7a2e71118 100644 --- a/libgo/go/regexp/all_test.go +++ b/libgo/go/regexp/all_test.go @@ -418,24 +418,32 @@ func TestLiteralPrefix(t *testing.T) { } } +type subexpIndex struct { + name string + index int +} + type subexpCase struct { - input string - num int - names []string + input string + num int + names []string + indices []subexpIndex } +var emptySubexpIndices = []subexpIndex{{"", -1}, {"missing", -1}} + var subexpCases = []subexpCase{ - {``, 0, nil}, - {`.*`, 0, nil}, - {`abba`, 0, nil}, - {`ab(b)a`, 1, []string{"", ""}}, - {`ab(.*)a`, 1, []string{"", ""}}, - {`(.*)ab(.*)a`, 2, []string{"", "", ""}}, - {`(.*)(ab)(.*)a`, 3, []string{"", "", "", ""}}, - {`(.*)((a)b)(.*)a`, 4, []string{"", "", "", "", ""}}, - {`(.*)(\(ab)(.*)a`, 3, []string{"", "", "", ""}}, - {`(.*)(\(a\)b)(.*)a`, 3, []string{"", "", "", ""}}, - {`(?P.*)(?P(a)b)(?P.*)a`, 4, []string{"", "foo", "bar", "", "foo"}}, + {``, 0, nil, emptySubexpIndices}, + {`.*`, 0, nil, emptySubexpIndices}, + {`abba`, 0, nil, emptySubexpIndices}, + {`ab(b)a`, 1, []string{"", ""}, emptySubexpIndices}, + {`ab(.*)a`, 1, []string{"", ""}, emptySubexpIndices}, + {`(.*)ab(.*)a`, 2, []string{"", "", ""}, emptySubexpIndices}, + {`(.*)(ab)(.*)a`, 3, []string{"", "", "", ""}, emptySubexpIndices}, + {`(.*)((a)b)(.*)a`, 4, []string{"", "", "", "", ""}, emptySubexpIndices}, + {`(.*)(\(ab)(.*)a`, 3, []string{"", "", "", ""}, emptySubexpIndices}, + {`(.*)(\(a\)b)(.*)a`, 3, []string{"", "", "", ""}, emptySubexpIndices}, + {`(?P.*)(?P(a)b)(?P.*)a`, 4, []string{"", "foo", "bar", "", "foo"}, []subexpIndex{{"", -1}, {"missing", -1}, {"foo", 1}, {"bar", 2}}}, } func TestSubexp(t *testing.T) { @@ -458,6 +466,12 @@ func TestSubexp(t *testing.T) { } } } + for _, subexp := range c.indices { + index := re.SubexpIndex(subexp.name) + if index != subexp.index { + t.Errorf("%q: SubexpIndex(%q) = %d, want %d", c.input, subexp.name, index, subexp.index) + } + } } } diff --git a/libgo/go/regexp/example_test.go b/libgo/go/regexp/example_test.go index ea35a2e5918..466b38b0fa2 100644 --- a/libgo/go/regexp/example_test.go +++ b/libgo/go/regexp/example_test.go @@ -280,6 +280,19 @@ func ExampleRegexp_SubexpNames() { // Turing Alan } +func ExampleRegexp_SubexpIndex() { + re := regexp.MustCompile(`(?P[a-zA-Z]+) (?P[a-zA-Z]+)`) + fmt.Println(re.MatchString("Alan Turing")) + matches := re.FindStringSubmatch("Alan Turing") + lastIndex := re.SubexpIndex("last") + fmt.Printf("last => %d\n", lastIndex) + fmt.Println(matches[lastIndex]) + // Output: + // true + // last => 2 + // Turing +} + func ExampleRegexp_Split() { a := regexp.MustCompile(`a`) fmt.Println(a.Split("banana", -1)) diff --git a/libgo/go/regexp/regexp.go b/libgo/go/regexp/regexp.go index 19ca6f2223f..b547a2ab97d 100644 --- a/libgo/go/regexp/regexp.go +++ b/libgo/go/regexp/regexp.go @@ -345,6 +345,24 @@ func (re *Regexp) SubexpNames() []string { return re.subexpNames } +// SubexpIndex returns the index of the first subexpression with the given name, +// or -1 if there is no subexpression with that name. +// +// Note that multiple subexpressions can be written using the same name, as in +// (?Pa+)(?Pb+), which declares two subexpressions named "bob". +// In this case, SubexpIndex returns the index of the leftmost such subexpression +// in the regular expression. +func (re *Regexp) SubexpIndex(name string) int { + if name != "" { + for i, s := range re.subexpNames { + if name == s { + return i + } + } + } + return -1 +} + const endOfText rune = -1 // input abstracts different representations of the input text. It provides diff --git a/libgo/go/regexp/syntax/compile.go b/libgo/go/regexp/syntax/compile.go index 1d8ab87a6d5..7524d628fe1 100644 --- a/libgo/go/regexp/syntax/compile.go +++ b/libgo/go/regexp/syntax/compile.go @@ -12,57 +12,47 @@ import "unicode" // See https://swtch.com/~rsc/regexp/regexp1.html for inspiration. // // These aren't really pointers: they're integers, so we can reinterpret them -// this way without using package unsafe. A value l denotes -// p.inst[l>>1].Out (l&1==0) or .Arg (l&1==1). -// l == 0 denotes the empty list, okay because we start every program +// this way without using package unsafe. A value l.head denotes +// p.inst[l.head>>1].Out (l.head&1==0) or .Arg (l.head&1==1). +// head == 0 denotes the empty list, okay because we start every program // with a fail instruction, so we'll never want to point at its output link. -type patchList uint32 +type patchList struct { + head, tail uint32 +} -func (l patchList) next(p *Prog) patchList { - i := &p.Inst[l>>1] - if l&1 == 0 { - return patchList(i.Out) - } - return patchList(i.Arg) +func makePatchList(n uint32) patchList { + return patchList{n, n} } func (l patchList) patch(p *Prog, val uint32) { - for l != 0 { - i := &p.Inst[l>>1] - if l&1 == 0 { - l = patchList(i.Out) + head := l.head + for head != 0 { + i := &p.Inst[head>>1] + if head&1 == 0 { + head = i.Out i.Out = val } else { - l = patchList(i.Arg) + head = i.Arg i.Arg = val } } } func (l1 patchList) append(p *Prog, l2 patchList) patchList { - if l1 == 0 { + if l1.head == 0 { return l2 } - if l2 == 0 { + if l2.head == 0 { return l1 } - last := l1 - for { - next := last.next(p) - if next == 0 { - break - } - last = next - } - - i := &p.Inst[last>>1] - if last&1 == 0 { - i.Out = uint32(l2) + i := &p.Inst[l1.tail>>1] + if l1.tail&1 == 0 { + i.Out = l2.head } else { - i.Arg = uint32(l2) + i.Arg = l2.head } - return l1 + return patchList{l1.head, l2.tail} } // A frag represents a compiled program fragment. @@ -176,7 +166,7 @@ func (c *compiler) inst(op InstOp) frag { func (c *compiler) nop() frag { f := c.inst(InstNop) - f.out = patchList(f.i << 1) + f.out = makePatchList(f.i << 1) return f } @@ -186,7 +176,7 @@ func (c *compiler) fail() frag { func (c *compiler) cap(arg uint32) frag { f := c.inst(InstCapture) - f.out = patchList(f.i << 1) + f.out = makePatchList(f.i << 1) c.p.Inst[f.i].Arg = arg if c.p.NumCap < int(arg)+1 { @@ -229,10 +219,10 @@ func (c *compiler) quest(f1 frag, nongreedy bool) frag { i := &c.p.Inst[f.i] if nongreedy { i.Arg = f1.i - f.out = patchList(f.i << 1) + f.out = makePatchList(f.i << 1) } else { i.Out = f1.i - f.out = patchList(f.i<<1 | 1) + f.out = makePatchList(f.i<<1 | 1) } f.out = f.out.append(c.p, f1.out) return f @@ -243,10 +233,10 @@ func (c *compiler) star(f1 frag, nongreedy bool) frag { i := &c.p.Inst[f.i] if nongreedy { i.Arg = f1.i - f.out = patchList(f.i << 1) + f.out = makePatchList(f.i << 1) } else { i.Out = f1.i - f.out = patchList(f.i<<1 | 1) + f.out = makePatchList(f.i<<1 | 1) } f1.out.patch(c.p, f.i) return f @@ -259,7 +249,7 @@ func (c *compiler) plus(f1 frag, nongreedy bool) frag { func (c *compiler) empty(op EmptyOp) frag { f := c.inst(InstEmptyWidth) c.p.Inst[f.i].Arg = uint32(op) - f.out = patchList(f.i << 1) + f.out = makePatchList(f.i << 1) return f } @@ -273,7 +263,7 @@ func (c *compiler) rune(r []rune, flags Flags) frag { flags &^= FoldCase } i.Arg = uint32(flags) - f.out = patchList(f.i << 1) + f.out = makePatchList(f.i << 1) // Special cases for exec machine. switch { diff --git a/libgo/go/regexp/syntax/parse.go b/libgo/go/regexp/syntax/parse.go index 8c6d43a7063..7b4030935a7 100644 --- a/libgo/go/regexp/syntax/parse.go +++ b/libgo/go/regexp/syntax/parse.go @@ -177,16 +177,16 @@ func (p *parser) maybeConcat(r rune, flags Flags) bool { return false // did not push r } -// newLiteral returns a new OpLiteral Regexp with the given flags -func (p *parser) newLiteral(r rune, flags Flags) *Regexp { +// literal pushes a literal regexp for the rune r on the stack. +func (p *parser) literal(r rune) { re := p.newRegexp(OpLiteral) - re.Flags = flags - if flags&FoldCase != 0 { + re.Flags = p.flags + if p.flags&FoldCase != 0 { r = minFoldRune(r) } re.Rune0[0] = r re.Rune = re.Rune0[:1] - return re + p.push(re) } // minFoldRune returns the minimum rune fold-equivalent to r. @@ -204,12 +204,6 @@ func minFoldRune(r rune) rune { return min } -// literal pushes a literal regexp for the rune r on the stack -// and returns that regexp. -func (p *parser) literal(r rune) { - p.push(p.newLiteral(r, p.flags)) -} - // op pushes a regexp with the given op onto the stack // and returns that regexp. func (p *parser) op(op Op) *Regexp { diff --git a/libgo/go/runtime/callers_test.go b/libgo/go/runtime/callers_test.go index 1fc7f861894..1c0e44185cd 100644 --- a/libgo/go/runtime/callers_test.go +++ b/libgo/go/runtime/callers_test.go @@ -68,6 +68,8 @@ func testCallers(t *testing.T, pcs []uintptr, pan bool) { } func testCallersEqual(t *testing.T, pcs []uintptr, want []string, ignore map[string]struct{}) { + t.Helper() + got := make([]string, 0, len(want)) frames := runtime.CallersFrames(pcs) diff --git a/libgo/go/runtime/chan.go b/libgo/go/runtime/chan.go index ec8252bb32a..de1d80acd30 100644 --- a/libgo/go/runtime/chan.go +++ b/libgo/go/runtime/chan.go @@ -121,6 +121,7 @@ func makechan(t *chantype, size int) *hchan { c.elemsize = uint16(elem.size) c.elemtype = elem c.dataqsiz = uint(size) + lockInit(&c.lock, lockRankHchan) if debugChan { print("makechan: chan=", c, "; elemsize=", elem.size, "; dataqsiz=", size, "\n") @@ -133,6 +134,21 @@ func chanbuf(c *hchan, i uint) unsafe.Pointer { return add(c.buf, uintptr(i)*uintptr(c.elemsize)) } +// full reports whether a send on c would block (that is, the channel is full). +// It uses a single word-sized read of mutable state, so although +// the answer is instantaneously true, the correct answer may have changed +// by the time the calling function receives the return value. +func full(c *hchan) bool { + // c.dataqsiz is immutable (never written after the channel is created) + // so it is safe to read at any time during channel operation. + if c.dataqsiz == 0 { + // Assumes that a pointer read is relaxed-atomic. + return c.recvq.first == nil + } + // Assumes that a uint read is relaxed-atomic. + return c.qcount == c.dataqsiz +} + // entry point for c <- x from compiled code //go:nosplit func chansend1(c *hchan, elem unsafe.Pointer) { @@ -177,7 +193,7 @@ func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool { // // After observing that the channel is not closed, we observe that the channel is // not ready for sending. Each of these observations is a single word-sized read - // (first c.closed and second c.recvq.first or c.qcount depending on kind of channel). + // (first c.closed and second full()). // Because a closed channel cannot transition from 'ready for sending' to // 'not ready for sending', even if the channel is closed between the two observations, // they imply a moment between the two when the channel was both not yet closed @@ -186,9 +202,10 @@ func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool { // // It is okay if the reads are reordered here: if we observe that the channel is not // ready for sending and then observe that it is not closed, that implies that the - // channel wasn't closed during the first observation. - if !block && c.closed == 0 && ((c.dataqsiz == 0 && c.recvq.first == nil) || - (c.dataqsiz > 0 && c.qcount == c.dataqsiz)) { + // channel wasn't closed during the first observation. However, nothing here + // guarantees forward progress. We rely on the side effects of lock release in + // chanrecv() and closechan() to update this thread's view of c.closed and full(). + if !block && c.closed == 0 && full(c) { return false } @@ -418,6 +435,16 @@ func closechan(c *hchan) { } } +// empty reports whether a read from c would block (that is, the channel is +// empty). It uses a single atomic read of mutable state. +func empty(c *hchan) bool { + // c.dataqsiz is immutable. + if c.dataqsiz == 0 { + return atomic.Loadp(unsafe.Pointer(&c.sendq.first)) == nil + } + return atomic.Loaduint(&c.qcount) == 0 +} + // entry points for <- c from compiled code //go:nosplit func chanrecv1(c *hchan, elem unsafe.Pointer) { @@ -458,21 +485,36 @@ func chanrecv(c *hchan, ep unsafe.Pointer, block bool) (selected, received bool) } // Fast path: check for failed non-blocking operation without acquiring the lock. - // - // After observing that the channel is not ready for receiving, we observe that the - // channel is not closed. Each of these observations is a single word-sized read - // (first c.sendq.first or c.qcount, and second c.closed). - // Because a channel cannot be reopened, the later observation of the channel - // being not closed implies that it was also not closed at the moment of the - // first observation. We behave as if we observed the channel at that moment - // and report that the receive cannot proceed. - // - // The order of operations is important here: reversing the operations can lead to - // incorrect behavior when racing with a close. - if !block && (c.dataqsiz == 0 && c.sendq.first == nil || - c.dataqsiz > 0 && atomic.Loaduint(&c.qcount) == 0) && - atomic.Load(&c.closed) == 0 { - return + if !block && empty(c) { + // After observing that the channel is not ready for receiving, we observe whether the + // channel is closed. + // + // Reordering of these checks could lead to incorrect behavior when racing with a close. + // For example, if the channel was open and not empty, was closed, and then drained, + // reordered reads could incorrectly indicate "open and empty". To prevent reordering, + // we use atomic loads for both checks, and rely on emptying and closing to happen in + // separate critical sections under the same lock. This assumption fails when closing + // an unbuffered channel with a blocked send, but that is an error condition anyway. + if atomic.Load(&c.closed) == 0 { + // Because a channel cannot be reopened, the later observation of the channel + // being not closed implies that it was also not closed at the moment of the + // first observation. We behave as if we observed the channel at that moment + // and report that the receive cannot proceed. + return + } + // The channel is irreversibly closed. Re-check whether the channel has any pending data + // to receive, which could have arrived between the empty and closed checks above. + // Sequential consistency is also required here, when racing with such a send. + if empty(c) { + // The channel is irreversibly closed and empty. + if raceenabled { + raceacquire(c.raceaddr()) + } + if ep != nil { + typedmemclr(c.elemtype, ep) + } + return true, false + } } var t0 int64 diff --git a/libgo/go/runtime/chan_test.go b/libgo/go/runtime/chan_test.go index c194781ede9..ac81d409bda 100644 --- a/libgo/go/runtime/chan_test.go +++ b/libgo/go/runtime/chan_test.go @@ -1132,6 +1132,20 @@ func BenchmarkChanPopular(b *testing.B) { wg.Wait() } +func BenchmarkChanClosed(b *testing.B) { + c := make(chan struct{}) + close(c) + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + select { + case <-c: + default: + b.Error("Unreachable") + } + } + }) +} + var ( alwaysFalse = false workSink = 0 diff --git a/libgo/go/runtime/checkptr.go b/libgo/go/runtime/checkptr.go index d5f116c3927..e52f7df5b2b 100644 --- a/libgo/go/runtime/checkptr.go +++ b/libgo/go/runtime/checkptr.go @@ -14,18 +14,18 @@ func checkptrAlignment(p unsafe.Pointer, elem *_type, n uintptr) { // no pointers themselves. See issue 37298. // TODO(mdempsky): What about fieldAlign? if elem.ptrdata != 0 && uintptr(p)&(uintptr(elem.align)-1) != 0 { - throw("checkptr: unsafe pointer conversion") + throw("checkptr: misaligned pointer conversion") } // Check that (*[n]elem)(p) doesn't straddle multiple heap objects. if size := n * elem.size; size > 1 && checkptrBase(p) != checkptrBase(add(p, size-1)) { - throw("checkptr: unsafe pointer conversion") + throw("checkptr: converted pointer straddles multiple allocations") } } func checkptrArithmetic(p unsafe.Pointer, originals []unsafe.Pointer) { if 0 < uintptr(p) && uintptr(p) < minLegalPointer { - throw("checkptr: unsafe pointer arithmetic") + throw("checkptr: pointer arithmetic computed bad pointer value") } // Check that if the computed pointer p points into a heap @@ -42,7 +42,7 @@ func checkptrArithmetic(p unsafe.Pointer, originals []unsafe.Pointer) { } } - throw("checkptr: unsafe pointer arithmetic") + throw("checkptr: pointer arithmetic result points to invalid allocation") } // checkptrBase returns the base address for the allocation containing diff --git a/libgo/go/runtime/checkptr_test.go b/libgo/go/runtime/checkptr_test.go index 0ca7b20cfd4..76aa2cdb2ba 100644 --- a/libgo/go/runtime/checkptr_test.go +++ b/libgo/go/runtime/checkptr_test.go @@ -28,11 +28,11 @@ func TestCheckPtr(t *testing.T) { cmd string want string }{ - {"CheckPtrAlignmentPtr", "fatal error: checkptr: unsafe pointer conversion\n"}, + {"CheckPtrAlignmentPtr", "fatal error: checkptr: misaligned pointer conversion\n"}, {"CheckPtrAlignmentNoPtr", ""}, - {"CheckPtrArithmetic", "fatal error: checkptr: unsafe pointer arithmetic\n"}, - {"CheckPtrSize", "fatal error: checkptr: unsafe pointer conversion\n"}, - {"CheckPtrSmall", "fatal error: checkptr: unsafe pointer arithmetic\n"}, + {"CheckPtrArithmetic", "fatal error: checkptr: pointer arithmetic result points to invalid allocation\n"}, + {"CheckPtrSize", "fatal error: checkptr: converted pointer straddles multiple allocations\n"}, + {"CheckPtrSmall", "fatal error: checkptr: pointer arithmetic computed bad pointer value\n"}, } for _, tc := range testCases { diff --git a/libgo/go/runtime/conv_wasm_test.go b/libgo/go/runtime/conv_wasm_test.go new file mode 100644 index 00000000000..5054fca04dc --- /dev/null +++ b/libgo/go/runtime/conv_wasm_test.go @@ -0,0 +1,128 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime_test + +import ( + "testing" +) + +var res int64 +var ures uint64 + +func TestFloatTruncation(t *testing.T) { + testdata := []struct { + input float64 + convInt64 int64 + convUInt64 uint64 + overflow bool + }{ + // max +- 1 + { + input: 0x7fffffffffffffff, + convInt64: -0x8000000000000000, + convUInt64: 0x8000000000000000, + }, + // For out-of-bounds conversion, the result is implementation-dependent. + // This test verifies the implementation of wasm architecture. + { + input: 0x8000000000000000, + convInt64: -0x8000000000000000, + convUInt64: 0x8000000000000000, + }, + { + input: 0x7ffffffffffffffe, + convInt64: -0x8000000000000000, + convUInt64: 0x8000000000000000, + }, + // neg max +- 1 + { + input: -0x8000000000000000, + convInt64: -0x8000000000000000, + convUInt64: 0x8000000000000000, + }, + { + input: -0x8000000000000001, + convInt64: -0x8000000000000000, + convUInt64: 0x8000000000000000, + }, + { + input: -0x7fffffffffffffff, + convInt64: -0x8000000000000000, + convUInt64: 0x8000000000000000, + }, + // trunc point +- 1 + { + input: 0x7ffffffffffffdff, + convInt64: 0x7ffffffffffffc00, + convUInt64: 0x7ffffffffffffc00, + }, + { + input: 0x7ffffffffffffe00, + convInt64: -0x8000000000000000, + convUInt64: 0x8000000000000000, + }, + { + input: 0x7ffffffffffffdfe, + convInt64: 0x7ffffffffffffc00, + convUInt64: 0x7ffffffffffffc00, + }, + // neg trunc point +- 1 + { + input: -0x7ffffffffffffdff, + convInt64: -0x7ffffffffffffc00, + convUInt64: 0x8000000000000000, + }, + { + input: -0x7ffffffffffffe00, + convInt64: -0x8000000000000000, + convUInt64: 0x8000000000000000, + }, + { + input: -0x7ffffffffffffdfe, + convInt64: -0x7ffffffffffffc00, + convUInt64: 0x8000000000000000, + }, + // umax +- 1 + { + input: 0xffffffffffffffff, + convInt64: -0x8000000000000000, + convUInt64: 0x8000000000000000, + }, + { + input: 0x10000000000000000, + convInt64: -0x8000000000000000, + convUInt64: 0x8000000000000000, + }, + { + input: 0xfffffffffffffffe, + convInt64: -0x8000000000000000, + convUInt64: 0x8000000000000000, + }, + // umax trunc +- 1 + { + input: 0xfffffffffffffbff, + convInt64: -0x8000000000000000, + convUInt64: 0xfffffffffffff800, + }, + { + input: 0xfffffffffffffc00, + convInt64: -0x8000000000000000, + convUInt64: 0x8000000000000000, + }, + { + input: 0xfffffffffffffbfe, + convInt64: -0x8000000000000000, + convUInt64: 0xfffffffffffff800, + }, + } + for _, item := range testdata { + if got, want := int64(item.input), item.convInt64; got != want { + t.Errorf("int64(%f): got %x, want %x", item.input, got, want) + } + if got, want := uint64(item.input), item.convUInt64; got != want { + t.Errorf("uint64(%f): got %x, want %x", item.input, got, want) + } + } +} diff --git a/libgo/go/runtime/crash_cgo_test.go b/libgo/go/runtime/crash_cgo_test.go index 2b7d274f953..7c10213b868 100644 --- a/libgo/go/runtime/crash_cgo_test.go +++ b/libgo/go/runtime/crash_cgo_test.go @@ -284,7 +284,13 @@ func testCgoPprof(t *testing.T, buildArg, runArg, top, bottom string) { t.Fatal(err) } - got, err := testenv.CleanCmdEnv(exec.Command(exe, runArg)).CombinedOutput() + // pprofCgoTraceback is called whenever CGO code is executing and a signal + // is received. Disable signal preemption to increase the likelihood at + // least one SIGPROF signal fired to capture a sample. See issue #37201. + cmd := testenv.CleanCmdEnv(exec.Command(exe, runArg)) + cmd.Env = append(cmd.Env, "GODEBUG=asyncpreemptoff=1") + + got, err := cmd.CombinedOutput() if err != nil { if testenv.Builder() == "linux-amd64-alpine" { // See Issue 18243 and Issue 19938. @@ -561,3 +567,48 @@ func findTrace(text, top string) []string { } return nil } + +func TestSegv(t *testing.T) { + switch runtime.GOOS { + case "plan9", "windows": + t.Skipf("no signals on %s", runtime.GOOS) + } + + for _, test := range []string{"Segv", "SegvInCgo"} { + t.Run(test, func(t *testing.T) { + t.Parallel() + got := runTestProg(t, "testprogcgo", test) + t.Log(got) + if !strings.Contains(got, "SIGSEGV") { + t.Errorf("expected crash from signal") + } + }) + } +} + +// TestEINTR tests that we handle EINTR correctly. +// See issue #20400 and friends. +func TestEINTR(t *testing.T) { + switch runtime.GOOS { + case "plan9", "windows": + t.Skipf("no EINTR on %s", runtime.GOOS) + case "linux": + if runtime.GOARCH == "386" { + // On linux-386 the Go signal handler sets + // a restorer function that is not preserved + // by the C sigaction call in the test, + // causing the signal handler to crash when + // returning the normal code. The test is not + // architecture-specific, so just skip on 386 + // rather than doing a complicated workaround. + t.Skip("skipping on linux-386; C sigaction does not preserve Go restorer") + } + } + + t.Parallel() + output := runTestProg(t, "testprogcgo", "EINTR") + want := "OK\n" + if output != want { + t.Fatalf("want %s, got %s\n", want, output) + } +} diff --git a/libgo/go/runtime/crash_unix_test.go b/libgo/go/runtime/crash_unix_test.go index 7ce5bb207d1..80184d94ad5 100644 --- a/libgo/go/runtime/crash_unix_test.go +++ b/libgo/go/runtime/crash_unix_test.go @@ -15,6 +15,7 @@ import ( "os/exec" "path/filepath" "runtime" + "strings" "sync" "syscall" "testing" @@ -291,6 +292,12 @@ func TestSignalExitStatus(t *testing.T) { } func TestSignalIgnoreSIGTRAP(t *testing.T) { + if runtime.GOOS == "openbsd" { + if bn := testenv.Builder(); strings.HasSuffix(bn, "-62") || strings.HasSuffix(bn, "-64") { + testenv.SkipFlaky(t, 17496) + } + } + output := runTestProg(t, "testprognet", "SignalIgnoreSIGTRAP") want := "OK\n" if output != want { diff --git a/libgo/go/runtime/debug.go b/libgo/go/runtime/debug.go index e480466b4d5..1202e362a5a 100644 --- a/libgo/go/runtime/debug.go +++ b/libgo/go/runtime/debug.go @@ -26,12 +26,12 @@ func GOMAXPROCS(n int) int { return ret } - stopTheWorld("GOMAXPROCS") + stopTheWorldGC("GOMAXPROCS") // newprocs will be processed by startTheWorld newprocs = int32(n) - startTheWorld() + startTheWorldGC() return ret } diff --git a/libgo/go/runtime/debug/mod.go b/libgo/go/runtime/debug/mod.go index c283928ff99..feac16894fb 100644 --- a/libgo/go/runtime/debug/mod.go +++ b/libgo/go/runtime/debug/mod.go @@ -48,9 +48,27 @@ func readBuildInfo(data string) (*BuildInfo, bool) { repLine = "=>\t" ) - info := &BuildInfo{} + readEntryFirstLine := func(elem []string) (Module, bool) { + if len(elem) != 2 && len(elem) != 3 { + return Module{}, false + } + sum := "" + if len(elem) == 3 { + sum = elem[2] + } + return Module{ + Path: elem[0], + Version: elem[1], + Sum: sum, + }, true + } - var line string + var ( + info = &BuildInfo{} + last *Module + line string + ok bool + ) // Reverse of cmd/go/internal/modload.PackageBuildInfo for len(data) > 0 { i := strings.IndexByte(data, '\n') @@ -64,42 +82,33 @@ func readBuildInfo(data string) (*BuildInfo, bool) { info.Path = elem case strings.HasPrefix(line, modLine): elem := strings.Split(line[len(modLine):], "\t") - if len(elem) != 3 { + last = &info.Main + *last, ok = readEntryFirstLine(elem) + if !ok { return nil, false } - info.Main = Module{ - Path: elem[0], - Version: elem[1], - Sum: elem[2], - } case strings.HasPrefix(line, depLine): elem := strings.Split(line[len(depLine):], "\t") - if len(elem) != 2 && len(elem) != 3 { + last = new(Module) + info.Deps = append(info.Deps, last) + *last, ok = readEntryFirstLine(elem) + if !ok { return nil, false } - sum := "" - if len(elem) == 3 { - sum = elem[2] - } - info.Deps = append(info.Deps, &Module{ - Path: elem[0], - Version: elem[1], - Sum: sum, - }) case strings.HasPrefix(line, repLine): elem := strings.Split(line[len(repLine):], "\t") if len(elem) != 3 { return nil, false } - last := len(info.Deps) - 1 - if last < 0 { + if last == nil { return nil, false } - info.Deps[last].Replace = &Module{ + last.Replace = &Module{ Path: elem[0], Version: elem[1], Sum: elem[2], } + last = nil } } return info, true diff --git a/libgo/go/runtime/debuglog.go b/libgo/go/runtime/debuglog.go index 404d0570a0b..d8c87c76462 100644 --- a/libgo/go/runtime/debuglog.go +++ b/libgo/go/runtime/debuglog.go @@ -672,13 +672,17 @@ func (r *debugLogReader) printVal() bool { print("..(", r.uvarint(), " more bytes)..") case debugLogPC: - printDebugLogPC(uintptr(r.uvarint())) + printDebugLogPC(uintptr(r.uvarint()), false) case debugLogTraceback: n := int(r.uvarint()) for i := 0; i < n; i++ { print("\n\t") - printDebugLogPC(uintptr(r.uvarint())) + // gentraceback PCs are always return PCs. + // Convert them to call PCs. + // + // TODO(austin): Expand inlined frames. + printDebugLogPC(uintptr(r.uvarint()), true) } } @@ -801,9 +805,18 @@ func printDebugLog() { printunlock() } -func printDebugLogPC(pc uintptr) { - print(hex(pc)) +// printDebugLogPC prints a single symbolized PC. If returnPC is true, +// pc is a return PC that must first be converted to a call PC. +func printDebugLogPC(pc uintptr, returnPC bool) { name, file, line, _ := funcfileline(pc, -1, false) + entry := funcentry(pc) + if returnPC && (name == "" || (entry != 0 && pc > funcentry(pc))) { + // TODO(austin): Don't back up if the previous frame + // was a sigpanic. + pc-- + } + + print(hex(pc)) if name == "" { print(" [unknown PC]") } else { diff --git a/libgo/go/runtime/defer_test.go b/libgo/go/runtime/defer_test.go index 11436a1f08b..5ac08145646 100644 --- a/libgo/go/runtime/defer_test.go +++ b/libgo/go/runtime/defer_test.go @@ -6,7 +6,6 @@ package runtime_test import ( "fmt" - "os" "reflect" "runtime" "testing" @@ -325,11 +324,13 @@ func recurseFnPanicRec(level int, maxlevel int) { recurseFn(level, maxlevel) } +var saveInt uint32 + func recurseFn(level int, maxlevel int) { a := [40]uint32{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff} if level+1 < maxlevel { - // Need this print statement to keep a around. '_ = a[4]' doesn't do it. - fmt.Fprintln(os.Stderr, "recurseFn", level, a[4]) + // Make sure a array is referenced, so it is not optimized away + saveInt = a[4] recurseFn(level+1, maxlevel) } else { panic("recurseFn panic") @@ -350,12 +351,12 @@ func TestIssue37688(t *testing.T) { type foo struct { } +//go:noinline func (f *foo) method1() { - fmt.Fprintln(os.Stderr, "method1") } +//go:noinline func (f *foo) method2() { - fmt.Fprintln(os.Stderr, "method2") } func g2() { @@ -379,6 +380,10 @@ func g3() { g2() } +var globstruct struct { + a, b, c, d, e, f, g, h, i int +} + func ff1(ap *foo, a, b, c, d, e, f, g, h, i int) { defer ap.method1() @@ -387,9 +392,15 @@ func ff1(ap *foo, a, b, c, d, e, f, g, h, i int) { // defer pool) defer func(ap *foo, a, b, c, d, e, f, g, h, i int) { if v := recover(); v != nil { - fmt.Fprintln(os.Stderr, "did recover") } - fmt.Fprintln(os.Stderr, "debug", ap, a, b, c, d, e, f, g, h) + globstruct.a = a + globstruct.b = b + globstruct.c = c + globstruct.d = d + globstruct.e = e + globstruct.f = f + globstruct.g = g + globstruct.h = h }(ap, a, b, c, d, e, f, g, h, i) panic("ff1 panic") } @@ -397,7 +408,5 @@ func ff1(ap *foo, a, b, c, d, e, f, g, h, i int) { func rec1(max int) { if max > 0 { rec1(max - 1) - } else { - fmt.Fprintln(os.Stderr, "finished recursion", max) } } diff --git a/libgo/go/runtime/env_posix.go b/libgo/go/runtime/env_posix.go index bf8996cd50d..48b9c4a32e1 100644 --- a/libgo/go/runtime/env_posix.go +++ b/libgo/go/runtime/env_posix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris windows +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris windows plan9 package runtime diff --git a/libgo/go/runtime/env_test.go b/libgo/go/runtime/env_test.go index 2399e46faa9..c009d0f31e1 100644 --- a/libgo/go/runtime/env_test.go +++ b/libgo/go/runtime/env_test.go @@ -11,10 +11,6 @@ import ( ) func TestFixedGOROOT(t *testing.T) { - if runtime.GOOS == "plan9" { - t.Skipf("skipping plan9, it is inconsistent by allowing GOROOT to be updated by Setenv") - } - // Restore both the real GOROOT environment variable, and runtime's copies: if orig, ok := syscall.Getenv("GOROOT"); ok { defer syscall.Setenv("GOROOT", orig) diff --git a/libgo/go/runtime/error.go b/libgo/go/runtime/error.go index 6cc46bfc3ee..d91e2dbf507 100644 --- a/libgo/go/runtime/error.go +++ b/libgo/go/runtime/error.go @@ -226,11 +226,6 @@ type stringer interface { String() string } -func typestring(x interface{}) string { - e := efaceOf(&x) - return e._type.string() -} - // printany prints an argument passed to panic. // If panic is called with a value that has a String or Error method, // it has already been converted into a string by preprintpanics. @@ -273,6 +268,50 @@ func printany(i interface{}) { case string: print(v) default: - print("(", typestring(i), ") ", i) + printanycustomtype(i) + } +} + +func printanycustomtype(i interface{}) { + eface := efaceOf(&i) + typestring := eface._type.string() + + switch eface._type.kind & ((1 << 5) - 1) { + case kindString: + print(typestring, `("`, *(*string)(eface.data), `")`) + case kindBool: + print(typestring, "(", *(*bool)(eface.data), ")") + case kindInt: + print(typestring, "(", *(*int)(eface.data), ")") + case kindInt8: + print(typestring, "(", *(*int8)(eface.data), ")") + case kindInt16: + print(typestring, "(", *(*int16)(eface.data), ")") + case kindInt32: + print(typestring, "(", *(*int32)(eface.data), ")") + case kindInt64: + print(typestring, "(", *(*int64)(eface.data), ")") + case kindUint: + print(typestring, "(", *(*uint)(eface.data), ")") + case kindUint8: + print(typestring, "(", *(*uint8)(eface.data), ")") + case kindUint16: + print(typestring, "(", *(*uint16)(eface.data), ")") + case kindUint32: + print(typestring, "(", *(*uint32)(eface.data), ")") + case kindUint64: + print(typestring, "(", *(*uint64)(eface.data), ")") + case kindUintptr: + print(typestring, "(", *(*uintptr)(eface.data), ")") + case kindFloat32: + print(typestring, "(", *(*float32)(eface.data), ")") + case kindFloat64: + print(typestring, "(", *(*float64)(eface.data), ")") + case kindComplex64: + print(typestring, *(*complex64)(eface.data)) + case kindComplex128: + print(typestring, *(*complex128)(eface.data)) + default: + print("(", typestring, ") ", eface.data) } } diff --git a/libgo/go/runtime/export_debug_test.go b/libgo/go/runtime/export_debug_test.go index 769ad55c588..c1cc44f23d0 100644 --- a/libgo/go/runtime/export_debug_test.go +++ b/libgo/go/runtime/export_debug_test.go @@ -49,6 +49,9 @@ func InjectDebugCall(gp *g, fn, args interface{}, tkill func(tid int) error, ret h := new(debugCallHandler) h.gp = gp + // gp may not be running right now, but we can still get the M + // it will run on since it's locked. + h.mp = gp.lockedm.ptr() h.fv, h.argp, h.argSize = fv, argp, argSize h.handleF = h.handle // Avoid allocating closure during signal @@ -87,6 +90,7 @@ func InjectDebugCall(gp *g, fn, args interface{}, tkill func(tid int) error, ret type debugCallHandler struct { gp *g + mp *m fv *funcval argp unsafe.Pointer argSize uintptr @@ -103,8 +107,8 @@ type debugCallHandler struct { func (h *debugCallHandler) inject(info *siginfo, ctxt *sigctxt, gp2 *g) bool { switch h.gp.atomicstatus { case _Grunning: - if getg().m != h.gp.m { - println("trap on wrong M", getg().m, h.gp.m) + if getg().m != h.mp { + println("trap on wrong M", getg().m, h.mp) return false } // Push current PC on the stack. @@ -136,8 +140,8 @@ func (h *debugCallHandler) inject(info *siginfo, ctxt *sigctxt, gp2 *g) bool { func (h *debugCallHandler) handle(info *siginfo, ctxt *sigctxt, gp2 *g) bool { // Sanity check. - if getg().m != h.gp.m { - println("trap on wrong M", getg().m, h.gp.m) + if getg().m != h.mp { + println("trap on wrong M", getg().m, h.mp) return false } f := findfunc(uintptr(ctxt.rip())) diff --git a/libgo/go/runtime/export_test.go b/libgo/go/runtime/export_test.go index ab74e34d611..482d014ad58 100644 --- a/libgo/go/runtime/export_test.go +++ b/libgo/go/runtime/export_test.go @@ -477,6 +477,8 @@ func GetNextArenaHint() uintptr { type G = g +type Sudog = sudog + func Getg() *G { return getg() } @@ -727,9 +729,12 @@ func (p *PageAlloc) Free(base, npages uintptr) { func (p *PageAlloc) Bounds() (ChunkIdx, ChunkIdx) { return ChunkIdx((*pageAlloc)(p).start), ChunkIdx((*pageAlloc)(p).end) } -func (p *PageAlloc) Scavenge(nbytes uintptr, locked bool) (r uintptr) { +func (p *PageAlloc) Scavenge(nbytes uintptr, mayUnlock bool) (r uintptr) { + pp := (*pageAlloc)(p) systemstack(func() { - r = (*pageAlloc)(p).scavenge(nbytes, locked) + lock(pp.mheapLock) + r = pp.scavenge(nbytes, mayUnlock) + unlock(pp.mheapLock) }) return } @@ -737,8 +742,8 @@ func (p *PageAlloc) InUse() []AddrRange { ranges := make([]AddrRange, 0, len(p.inUse.ranges)) for _, r := range p.inUse.ranges { ranges = append(ranges, AddrRange{ - Base: r.base, - Limit: r.limit, + Base: r.base.addr(), + Limit: r.limit.addr(), }) } return ranges @@ -784,6 +789,7 @@ func NewPageAlloc(chunks, scav map[ChunkIdx][]BitRange) *PageAlloc { // We've got an entry, so initialize the pageAlloc. p.init(new(mutex), nil) + lockInit(p.mheapLock, lockRankMheap) p.test = true for i, init := range chunks { @@ -810,7 +816,6 @@ func NewPageAlloc(chunks, scav map[ChunkIdx][]BitRange) *PageAlloc { } } } - p.resetScavengeAddr() // Apply alloc state. for _, s := range init { @@ -824,6 +829,11 @@ func NewPageAlloc(chunks, scav map[ChunkIdx][]BitRange) *PageAlloc { // Update heap metadata for the allocRange calls above. p.update(addr, pallocChunkPages, false, false) } + systemstack(func() { + lock(p.mheapLock) + p.scavengeStartGen() + unlock(p.mheapLock) + }) return (*PageAlloc)(p) } @@ -860,13 +870,9 @@ func FreePageAlloc(pp *PageAlloc) { // 64 bit and 32 bit platforms, allowing the tests to share code // between the two. // -// On AIX, the arenaBaseOffset is 0x0a00000000000000. However, this -// constant can't be used here because it is negative and will cause -// a constant overflow. -// // This should not be higher than 0x100*pallocChunkBytes to support // mips and mipsle, which only have 31-bit address spaces. -var BaseChunkIdx = ChunkIdx(chunkIndex(((0xc000*pageAlloc64Bit + 0x100*pageAlloc32Bit) * pallocChunkBytes) + 0x0a00000000000000*sys.GoosAix*sys.GoarchPpc64)) +var BaseChunkIdx = ChunkIdx(chunkIndex(((0xc000*pageAlloc64Bit + 0x100*pageAlloc32Bit) * pallocChunkBytes) + arenaBaseOffset*sys.GoosAix*sys.GoarchPpc64)) // PageBase returns an address given a chunk index and a page index // relative to that chunk. @@ -970,4 +976,12 @@ func MapHashCheck(m interface{}, k interface{}) (uintptr, uintptr) { return x, y } +func MSpanCountAlloc(bits []byte) int { + s := mspan{ + nelems: uintptr(len(bits) * 8), + gcmarkBits: (*gcBits)(unsafe.Pointer(&bits[0])), + } + return s.countAlloc() +} + var Pusestackmaps = &usestackmaps diff --git a/libgo/go/runtime/extern.go b/libgo/go/runtime/extern.go index 96af6063f82..a85fbb07c00 100644 --- a/libgo/go/runtime/extern.go +++ b/libgo/go/runtime/extern.go @@ -87,9 +87,11 @@ It is a comma-separated list of name=val pairs setting these named variables: When set to 0 memory profiling is disabled. Refer to the description of MemProfileRate for the default value. - memprofilerate: setting memprofilerate=X changes the setting for - runtime.MemProfileRate. Refer to the description of this variable for how - it is used and its default value. + invalidptr: invalidptr=1 (the default) causes the garbage collector and stack + copier to crash the program if an invalid pointer value (for example, 1) + is found in a pointer-typed location. Setting invalidptr=0 disables this check. + This should only be used as a temporary workaround to diagnose buggy code. + The real fix is to not store integers in pointer-typed locations. sbrk: setting sbrk=1 replaces the memory allocator and garbage collector with a trivial allocator that obtains memory from the operating system and @@ -102,10 +104,11 @@ It is a comma-separated list of name=val pairs setting these named variables: scavenger as well as the total amount of memory returned to the operating system and an estimate of physical memory utilization. The format of this line is subject to change, but currently it is: - scav # KiB work, # KiB total, #% util + scav # # KiB work, # KiB total, #% util where the fields are as follows: - # KiB work the amount of memory returned to the OS since the last scav line - # KiB total how much of the heap at this point in time has been released to the OS + scav # the scavenge cycle number + # KiB work the amount of memory returned to the OS since the last line + # KiB total the total amount of memory returned to the OS #% util the fraction of all unscavenged memory which is in-use If the line ends with "(forced)", then scavenging was forced by a debug.FreeOSMemory() call. diff --git a/libgo/go/runtime/gc_test.go b/libgo/go/runtime/gc_test.go index 8f14bf9e51f..f545e4bd3b6 100644 --- a/libgo/go/runtime/gc_test.go +++ b/libgo/go/runtime/gc_test.go @@ -6,10 +6,13 @@ package runtime_test import ( "fmt" + "math/rand" "os" "reflect" "runtime" "runtime/debug" + "sort" + "strings" "sync" "sync/atomic" "testing" @@ -193,6 +196,18 @@ func TestPeriodicGC(t *testing.T) { } */ +func TestGcZombieReporting(t *testing.T) { + if runtime.Compiler == "gccgo" { + t.Skip("gccgo uses partially conservative GC") + } + // This test is somewhat sensitive to how the allocator works. + got := runTestProg(t, "testprog", "GCZombie") + want := "found pointer to free object" + if !strings.Contains(got, want) { + t.Fatalf("expected %q in output, but got %q", want, got) + } +} + func BenchmarkSetTypePtr(b *testing.B) { benchSetType(b, new(*byte)) } @@ -509,6 +524,90 @@ func BenchmarkReadMemStats(b *testing.B) { hugeSink = nil } +func BenchmarkReadMemStatsLatency(b *testing.B) { + // We’ll apply load to the runtime with maxProcs-1 goroutines + // and use one more to actually benchmark. It doesn't make sense + // to try to run this test with only 1 P (that's what + // BenchmarkReadMemStats is for). + maxProcs := runtime.GOMAXPROCS(-1) + if maxProcs == 1 { + b.Skip("This benchmark can only be run with GOMAXPROCS > 1") + } + + // Code to build a big tree with lots of pointers. + type node struct { + children [16]*node + } + var buildTree func(depth int) *node + buildTree = func(depth int) *node { + tree := new(node) + if depth != 0 { + for i := range tree.children { + tree.children[i] = buildTree(depth - 1) + } + } + return tree + } + + // Keep the GC busy by continuously generating large trees. + done := make(chan struct{}) + var wg sync.WaitGroup + for i := 0; i < maxProcs-1; i++ { + wg.Add(1) + go func() { + defer wg.Done() + var hold *node + loop: + for { + hold = buildTree(5) + select { + case <-done: + break loop + default: + } + } + runtime.KeepAlive(hold) + }() + } + + // Spend this much time measuring latencies. + latencies := make([]time.Duration, 0, 1024) + + // Run for timeToBench hitting ReadMemStats continuously + // and measuring the latency. + b.ResetTimer() + var ms runtime.MemStats + for i := 0; i < b.N; i++ { + // Sleep for a bit, otherwise we're just going to keep + // stopping the world and no one will get to do anything. + time.Sleep(100 * time.Millisecond) + start := time.Now() + runtime.ReadMemStats(&ms) + latencies = append(latencies, time.Now().Sub(start)) + } + close(done) + // Make sure to stop the timer before we wait! The goroutines above + // are very heavy-weight and not easy to stop, so we could end up + // confusing the benchmarking framework for small b.N. + b.StopTimer() + wg.Wait() + + // Disable the default */op metrics. + // ns/op doesn't mean anything because it's an average, but we + // have a sleep in our b.N loop above which skews this significantly. + b.ReportMetric(0, "ns/op") + b.ReportMetric(0, "B/op") + b.ReportMetric(0, "allocs/op") + + // Sort latencies then report percentiles. + sort.Slice(latencies, func(i, j int) bool { + return latencies[i] < latencies[j] + }) + b.ReportMetric(float64(latencies[len(latencies)*50/100]), "p50-ns") + b.ReportMetric(float64(latencies[len(latencies)*90/100]), "p90-ns") + b.ReportMetric(float64(latencies[len(latencies)*99/100]), "p99-ns") +} + func TestUserForcedGC(t *testing.T) { // Test that runtime.GC() triggers a GC even if GOGC=off. defer debug.SetGCPercent(debug.SetGCPercent(-1)) @@ -669,6 +768,24 @@ func BenchmarkScanStackNoLocals(b *testing.B) { close(teardown) } +func BenchmarkMSpanCountAlloc(b *testing.B) { + // n is the number of bytes to benchmark against. + // n must always be a multiple of 8, since gcBits is + // always rounded up 8 bytes. + for _, n := range []int{8, 16, 32, 64, 128} { + b.Run(fmt.Sprintf("bits=%d", n*8), func(b *testing.B) { + // Initialize a new byte slice with pseduo-random data. + bits := make([]byte, n) + rand.Read(bits) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + runtime.MSpanCountAlloc(bits) + } + }) + } +} + func countpwg(n *int, ready *sync.WaitGroup, teardown chan bool) { if *n == 0 { ready.Done() diff --git a/libgo/go/runtime/hash_test.go b/libgo/go/runtime/hash_test.go index 522b7febf9b..60a86015f64 100644 --- a/libgo/go/runtime/hash_test.go +++ b/libgo/go/runtime/hash_test.go @@ -152,14 +152,13 @@ func (s *HashSet) addS_seed(x string, seed uintptr) { s.add(StringHash(x, seed)) } func (s *HashSet) check(t *testing.T) { - const SLOP = 10.0 + const SLOP = 50.0 collisions := s.n - len(s.m) - //fmt.Printf("%d/%d\n", len(s.m), s.n) pairs := int64(s.n) * int64(s.n-1) / 2 expected := float64(pairs) / math.Pow(2.0, float64(hashSize)) stddev := math.Sqrt(expected) if float64(collisions) > expected+SLOP*(3*stddev+1) { - t.Errorf("unexpected number of collisions: got=%d mean=%f stddev=%f", collisions, expected, stddev) + t.Errorf("unexpected number of collisions: got=%d mean=%f stddev=%f threshold=%f", collisions, expected, stddev, expected+SLOP*(3*stddev+1)) } } @@ -564,8 +563,11 @@ func avalancheTest1(t *testing.T, k Key) { // All bit rotations of a set of distinct keys func TestSmhasherWindowed(t *testing.T) { + t.Logf("32 bit keys") windowed(t, &Int32Key{}) + t.Logf("64 bit keys") windowed(t, &Int64Key{}) + t.Logf("string keys") windowed(t, &BytesKey{make([]byte, 128)}) } func windowed(t *testing.T, k Key) { diff --git a/libgo/go/runtime/iface.go b/libgo/go/runtime/iface.go index 74b54f5209c..877e191a855 100644 --- a/libgo/go/runtime/iface.go +++ b/libgo/go/runtime/iface.go @@ -296,6 +296,7 @@ func getitab(lhs, rhs *_type, canfail bool) unsafe.Pointer { } // Not found. Grab the lock and try again. + lockInit(&itabLock, lockRankItab) lock(&itabLock) if m = itabTable.find(lhsi, rhs); m != nil { unlock(&itabLock) @@ -514,8 +515,8 @@ func reflectlite_ifaceE2I(inter *interfacetype, e eface, dst *iface) { dst.data = e.data } -// staticbytes is used to avoid convT2E for byte-sized values. -var staticbytes = [...]byte{ +// staticuint64s is used to avoid allocating in convTx for small integer values. +var staticuint64s = [...]uint64{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, diff --git a/libgo/go/runtime/iface_test.go b/libgo/go/runtime/iface_test.go index d63ea796138..43d3698b1d3 100644 --- a/libgo/go/runtime/iface_test.go +++ b/libgo/go/runtime/iface_test.go @@ -95,6 +95,19 @@ func BenchmarkNeIfaceConcrete(b *testing.B) { } } +func BenchmarkConvT2EByteSized(b *testing.B) { + b.Run("bool", func(b *testing.B) { + for i := 0; i < b.N; i++ { + e = yes + } + }) + b.Run("uint8", func(b *testing.B) { + for i := 0; i < b.N; i++ { + e = eight8 + } + }) +} + func BenchmarkConvT2ESmall(b *testing.B) { for i := 0; i < b.N; i++ { e = ts @@ -322,18 +335,22 @@ func TestZeroConvT2x(t *testing.T) { var ( eight8 uint8 = 8 eight8I T8 = 8 + yes bool = true - zero16 uint16 = 0 - zero16I T16 = 0 - one16 uint16 = 1 + zero16 uint16 = 0 + zero16I T16 = 0 + one16 uint16 = 1 + thousand16 uint16 = 1000 - zero32 uint32 = 0 - zero32I T32 = 0 - one32 uint32 = 1 + zero32 uint32 = 0 + zero32I T32 = 0 + one32 uint32 = 1 + thousand32 uint32 = 1000 - zero64 uint64 = 0 - zero64I T64 = 0 - one64 uint64 = 1 + zero64 uint64 = 0 + zero64I T64 = 0 + one64 uint64 = 1 + thousand64 uint64 = 1000 zerostr string = "" zerostrI Tstr = "" @@ -381,6 +398,23 @@ func BenchmarkConvT2Ezero(b *testing.B) { }) }) b.Run("nonzero", func(b *testing.B) { + b.Run("str", func(b *testing.B) { + for i := 0; i < b.N; i++ { + e = nzstr + } + }) + b.Run("slice", func(b *testing.B) { + for i := 0; i < b.N; i++ { + e = nzslice + } + }) + b.Run("big", func(b *testing.B) { + for i := 0; i < b.N; i++ { + e = nzbig + } + }) + }) + b.Run("smallint", func(b *testing.B) { b.Run("16", func(b *testing.B) { for i := 0; i < b.N; i++ { e = one16 @@ -396,19 +430,21 @@ func BenchmarkConvT2Ezero(b *testing.B) { e = one64 } }) - b.Run("str", func(b *testing.B) { + }) + b.Run("largeint", func(b *testing.B) { + b.Run("16", func(b *testing.B) { for i := 0; i < b.N; i++ { - e = nzstr + e = thousand16 } }) - b.Run("slice", func(b *testing.B) { + b.Run("32", func(b *testing.B) { for i := 0; i < b.N; i++ { - e = nzslice + e = thousand32 } }) - b.Run("big", func(b *testing.B) { + b.Run("64", func(b *testing.B) { for i := 0; i < b.N; i++ { - e = nzbig + e = thousand64 } }) }) diff --git a/libgo/go/runtime/lock_futex.go b/libgo/go/runtime/lock_futex.go index f672efdc74c..21d7e0dd943 100644 --- a/libgo/go/runtime/lock_futex.go +++ b/libgo/go/runtime/lock_futex.go @@ -55,6 +55,10 @@ func key32(p *uintptr) *uint32 { } func lock(l *mutex) { + lockWithRank(l, getLockRank(l)) +} + +func lock2(l *mutex) { gp := getg() if gp.m.locks < 0 { @@ -115,6 +119,10 @@ func lock(l *mutex) { } func unlock(l *mutex) { + unlockWithRank(l) +} + +func unlock2(l *mutex) { v := atomic.Xchg(key32(&l.key), mutex_unlocked) if v == mutex_unlocked { throw("unlock of unlocked lock") @@ -241,8 +249,8 @@ func notetsleepg(n *note, ns int64) bool { return ok } -func beforeIdle(int64) bool { - return false +func beforeIdle(int64) (*g, bool) { + return nil, false } func checkTimeouts() {} diff --git a/libgo/go/runtime/lock_js.go b/libgo/go/runtime/lock_js.go index 3168c86d8a0..14bdc76842c 100644 --- a/libgo/go/runtime/lock_js.go +++ b/libgo/go/runtime/lock_js.go @@ -26,6 +26,10 @@ const ( ) func lock(l *mutex) { + lockWithRank(l, getLockRank(l)) +} + +func lock2(l *mutex) { if l.key == mutex_locked { // js/wasm is single-threaded so we should never // observe this. @@ -40,6 +44,10 @@ func lock(l *mutex) { } func unlock(l *mutex) { + unlockWithRank(l) +} + +func unlock2(l *mutex) { if l.key == mutex_unlocked { throw("unlock of unlocked lock") } @@ -165,7 +173,9 @@ var idleID int32 // beforeIdle gets called by the scheduler if no goroutine is awake. // If we are not already handling an event, then we pause for an async event. // If an event handler returned, we resume it and it will pause the execution. -func beforeIdle(delay int64) bool { +// beforeIdle either returns the specific goroutine to schedule next or +// indicates with otherReady that some goroutine became ready. +func beforeIdle(delay int64) (gp *g, otherReady bool) { if delay > 0 { clearIdleID() if delay < 1e6 { @@ -182,15 +192,14 @@ func beforeIdle(delay int64) bool { if len(events) == 0 { go handleAsyncEvent() - return true + return nil, true } e := events[len(events)-1] if e.returned { - goready(e.gp, 1) - return true + return e.gp, false } - return false + return nil, false } func handleAsyncEvent() { diff --git a/libgo/go/runtime/lock_sema.go b/libgo/go/runtime/lock_sema.go index 63a60149db3..fe173843797 100644 --- a/libgo/go/runtime/lock_sema.go +++ b/libgo/go/runtime/lock_sema.go @@ -44,6 +44,10 @@ const ( ) func lock(l *mutex) { + lockWithRank(l, getLockRank(l)) +} + +func lock2(l *mutex) { gp := getg() if gp.m.locks < 0 { throw("runtime·lock: lock count") @@ -100,9 +104,13 @@ Loop: } } +func unlock(l *mutex) { + unlockWithRank(l) +} + //go:nowritebarrier // We might not be holding a p in this code. -func unlock(l *mutex) { +func unlock2(l *mutex) { gp := getg() var mp *m for { @@ -300,8 +308,8 @@ func notetsleepg(n *note, ns int64) bool { return ok } -func beforeIdle(int64) bool { - return false +func beforeIdle(int64) (*g, bool) { + return nil, false } func checkTimeouts() {} diff --git a/libgo/go/runtime/lockrank.go b/libgo/go/runtime/lockrank.go new file mode 100644 index 00000000000..000193585df --- /dev/null +++ b/libgo/go/runtime/lockrank.go @@ -0,0 +1,254 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file records the static ranks of the locks in the runtime. If a lock +// is not given a rank, then it is assumed to be a leaf lock, which means no other +// lock can be acquired while it is held. Therefore, leaf locks do not need to be +// given an explicit rank. We list all of the architecture-independent leaf locks +// for documentation purposes, but don't list any of the architecture-dependent +// locks (which are all leaf locks). debugLock is ignored for ranking, since it is used +// when printing out lock ranking errors. +// +// lockInit(l *mutex, rank int) is used to set the rank of lock before it is used. +// If there is no clear place to initialize a lock, then the rank of a lock can be +// specified during the lock call itself via lockWithrank(l *mutex, rank int). +// +// Besides the static lock ranking (which is a total ordering of the locks), we +// also represent and enforce the actual partial order among the locks in the +// arcs[] array below. That is, if it is possible that lock B can be acquired when +// lock A is the previous acquired lock that is still held, then there should be +// an entry for A in arcs[B][]. We will currently fail not only if the total order +// (the lock ranking) is violated, but also if there is a missing entry in the +// partial order. + +package runtime + +type lockRank int + +// Constants representing the lock rank of the architecture-independent locks in +// the runtime. Locks with lower rank must be taken before locks with higher +// rank. +const ( + lockRankDummy lockRank = iota + + // Locks held above sched + lockRankSysmon + lockRankScavenge + lockRankForcegc + lockRankSweepWaiters + lockRankAssistQueue + lockRankCpuprof + lockRankSweep + + lockRankSched + lockRankDeadlock + lockRankPanic + lockRankAllg + lockRankAllp + lockRankPollDesc + + lockRankTimers // Multiple timers locked simultaneously in destroy() + lockRankItab + lockRankReflectOffs + lockRankHchan // Multiple hchans acquired in lock order in syncadjustsudogs() + lockRankFin + lockRankNotifyList + lockRankTraceBuf + lockRankTraceStrings + lockRankMspanSpecial + lockRankProf + lockRankGcBitsArenas + lockRankRoot + lockRankTrace + lockRankTraceStackTab + lockRankNetpollInit + + lockRankRwmutexW + lockRankRwmutexR + + lockRankMcentral // For !go115NewMCentralImpl + lockRankSpine // For !go115NewMCentralImpl + lockRankSpanSetSpine + lockRankGscan + lockRankStackpool + lockRankStackLarge + lockRankDefer + lockRankSudog + + // Memory-related non-leaf locks + lockRankWbufSpans + lockRankMheap + lockRankMheapSpecial + + // Memory-related leaf locks + lockRankGlobalAlloc + + // Other leaf locks + lockRankGFree + // Generally, hchan must be acquired before gscan. But in one specific + // case (in syncadjustsudogs from markroot after the g has been suspended + // by suspendG), we allow gscan to be acquired, and then an hchan lock. To + // allow this case, we get this lockRankHchanLeaf rank in + // syncadjustsudogs(), rather than lockRankHchan. By using this special + // rank, we don't allow any further locks to be acquired other than more + // hchan locks. + lockRankHchanLeaf + + // Leaf locks with no dependencies, so these constants are not actually used anywhere. + // There are other architecture-dependent leaf locks as well. + lockRankNewmHandoff + lockRankDebugPtrmask + lockRankFaketimeState + lockRankTicks + lockRankRaceFini + lockRankPollCache + lockRankDebug +) + +// lockRankLeafRank is the rank of lock that does not have a declared rank, and hence is +// a leaf lock. +const lockRankLeafRank lockRank = 1000 + +// lockNames gives the names associated with each of the above ranks +var lockNames = []string{ + lockRankDummy: "", + + lockRankSysmon: "sysmon", + lockRankScavenge: "scavenge", + lockRankForcegc: "forcegc", + lockRankSweepWaiters: "sweepWaiters", + lockRankAssistQueue: "assistQueue", + lockRankCpuprof: "cpuprof", + lockRankSweep: "sweep", + + lockRankSched: "sched", + lockRankDeadlock: "deadlock", + lockRankPanic: "panic", + lockRankAllg: "allg", + lockRankAllp: "allp", + lockRankPollDesc: "pollDesc", + + lockRankTimers: "timers", + lockRankItab: "itab", + lockRankReflectOffs: "reflectOffs", + + lockRankHchan: "hchan", + lockRankFin: "fin", + lockRankNotifyList: "notifyList", + lockRankTraceBuf: "traceBuf", + lockRankTraceStrings: "traceStrings", + lockRankMspanSpecial: "mspanSpecial", + lockRankProf: "prof", + lockRankGcBitsArenas: "gcBitsArenas", + lockRankRoot: "root", + lockRankTrace: "trace", + lockRankTraceStackTab: "traceStackTab", + lockRankNetpollInit: "netpollInit", + + lockRankRwmutexW: "rwmutexW", + lockRankRwmutexR: "rwmutexR", + + lockRankMcentral: "mcentral", + lockRankSpine: "spine", + lockRankSpanSetSpine: "spanSetSpine", + lockRankGscan: "gscan", + lockRankStackpool: "stackpool", + lockRankStackLarge: "stackLarge", + lockRankDefer: "defer", + lockRankSudog: "sudog", + + lockRankWbufSpans: "wbufSpans", + lockRankMheap: "mheap", + lockRankMheapSpecial: "mheapSpecial", + + lockRankGlobalAlloc: "globalAlloc.mutex", + + lockRankGFree: "gFree", + lockRankHchanLeaf: "hchanLeaf", + + lockRankNewmHandoff: "newmHandoff.lock", + lockRankDebugPtrmask: "debugPtrmask.lock", + lockRankFaketimeState: "faketimeState.lock", + lockRankTicks: "ticks.lock", + lockRankRaceFini: "raceFiniLock", + lockRankPollCache: "pollCache.lock", + lockRankDebug: "debugLock", +} + +func (rank lockRank) String() string { + if rank == 0 { + return "UNKNOWN" + } + if rank == lockRankLeafRank { + return "LEAF" + } + return lockNames[rank] +} + +// lockPartialOrder is a partial order among the various lock types, listing the immediate +// ordering that has actually been observed in the runtime. Each entry (which +// corresponds to a particular lock rank) specifies the list of locks that can be +// already be held immediately "above" it. +// +// So, for example, the lockRankSched entry shows that all the locks preceding it in +// rank can actually be held. The fin lock shows that only the sched, timers, or +// hchan lock can be held immediately above it when it is acquired. +var lockPartialOrder [][]lockRank = [][]lockRank{ + lockRankDummy: {}, + lockRankSysmon: {}, + lockRankScavenge: {lockRankSysmon}, + lockRankForcegc: {lockRankSysmon}, + lockRankSweepWaiters: {}, + lockRankAssistQueue: {}, + lockRankCpuprof: {}, + lockRankSweep: {}, + lockRankSched: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep}, + lockRankDeadlock: {lockRankDeadlock}, + lockRankPanic: {lockRankDeadlock}, + lockRankAllg: {lockRankSysmon, lockRankSched, lockRankPanic}, + lockRankAllp: {lockRankSysmon, lockRankSched}, + lockRankPollDesc: {}, + lockRankTimers: {lockRankSysmon, lockRankScavenge, lockRankSched, lockRankAllp, lockRankPollDesc, lockRankTimers}, + lockRankItab: {}, + lockRankReflectOffs: {lockRankItab}, + lockRankHchan: {lockRankScavenge, lockRankSweep, lockRankHchan}, + lockRankFin: {lockRankSysmon, lockRankScavenge, lockRankSched, lockRankAllg, lockRankTimers, lockRankHchan}, + lockRankNotifyList: {}, + lockRankTraceBuf: {lockRankSysmon, lockRankScavenge}, + lockRankTraceStrings: {lockRankTraceBuf}, + lockRankMspanSpecial: {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings}, + lockRankProf: {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankHchan}, + lockRankGcBitsArenas: {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankHchan}, + lockRankRoot: {}, + lockRankTrace: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankAssistQueue, lockRankSched, lockRankHchan, lockRankTraceBuf, lockRankTraceStrings, lockRankRoot, lockRankSweep}, + lockRankTraceStackTab: {lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankSched, lockRankAllg, lockRankTimers, lockRankHchan, lockRankFin, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankRoot, lockRankTrace}, + lockRankNetpollInit: {lockRankTimers}, + + lockRankRwmutexW: {}, + lockRankRwmutexR: {lockRankRwmutexW}, + + lockRankMcentral: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankHchan}, + lockRankSpine: {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankHchan}, + lockRankSpanSetSpine: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankHchan}, + lockRankGscan: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankFin, lockRankTraceBuf, lockRankTraceStrings, lockRankRoot, lockRankNotifyList, lockRankProf, lockRankGcBitsArenas, lockRankTrace, lockRankTraceStackTab, lockRankNetpollInit, lockRankMcentral, lockRankSpine, lockRankSpanSetSpine}, + lockRankStackpool: {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankPollDesc, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankFin, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankProf, lockRankGcBitsArenas, lockRankRoot, lockRankTrace, lockRankTraceStackTab, lockRankNetpollInit, lockRankRwmutexR, lockRankMcentral, lockRankSpine, lockRankSpanSetSpine, lockRankGscan}, + lockRankStackLarge: {lockRankSysmon, lockRankAssistQueue, lockRankSched, lockRankItab, lockRankHchan, lockRankProf, lockRankGcBitsArenas, lockRankRoot, lockRankMcentral, lockRankSpanSetSpine, lockRankGscan}, + lockRankDefer: {}, + lockRankSudog: {lockRankNotifyList, lockRankHchan}, + lockRankWbufSpans: {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankSched, lockRankAllg, lockRankPollDesc, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankNotifyList, lockRankTraceStrings, lockRankMspanSpecial, lockRankProf, lockRankRoot, lockRankGscan, lockRankDefer, lockRankSudog}, + lockRankMheap: {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankPollDesc, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankHchan, lockRankMspanSpecial, lockRankProf, lockRankGcBitsArenas, lockRankRoot, lockRankMcentral, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankDefer, lockRankSudog, lockRankWbufSpans, lockRankSpanSetSpine}, + lockRankMheapSpecial: {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankHchan}, + lockRankGlobalAlloc: {lockRankProf, lockRankSpine, lockRankSpanSetSpine, lockRankMheap, lockRankMheapSpecial}, + + lockRankGFree: {lockRankSched}, + lockRankHchanLeaf: {lockRankGscan, lockRankHchanLeaf}, + + lockRankNewmHandoff: {}, + lockRankDebugPtrmask: {}, + lockRankFaketimeState: {}, + lockRankTicks: {}, + lockRankRaceFini: {}, + lockRankPollCache: {}, + lockRankDebug: {}, +} diff --git a/libgo/go/runtime/lockrank_off.go b/libgo/go/runtime/lockrank_off.go new file mode 100644 index 00000000000..891589c0f27 --- /dev/null +++ b/libgo/go/runtime/lockrank_off.go @@ -0,0 +1,32 @@ +// +build !goexperiment.staticlockranking + +package runtime + +// // lockRankStruct is embedded in mutex, but is empty when staticklockranking is +// disabled (the default) +type lockRankStruct struct { +} + +func lockInit(l *mutex, rank lockRank) { +} + +func getLockRank(l *mutex) lockRank { + return 0 +} + +func lockWithRank(l *mutex, rank lockRank) { + lock2(l) +} + +func acquireLockRank(rank lockRank) { +} + +func unlockWithRank(l *mutex) { + unlock2(l) +} + +func releaseLockRank(rank lockRank) { +} + +func lockWithRankMayAcquire(l *mutex, rank lockRank) { +} diff --git a/libgo/go/runtime/lockrank_on.go b/libgo/go/runtime/lockrank_on.go new file mode 100644 index 00000000000..cf4151ff462 --- /dev/null +++ b/libgo/go/runtime/lockrank_on.go @@ -0,0 +1,210 @@ +// +build goexperiment.staticlockranking + +package runtime + +import ( + "unsafe" +) + +// lockRankStruct is embedded in mutex +type lockRankStruct struct { + // static lock ranking of the lock + rank lockRank + // pad field to make sure lockRankStruct is a multiple of 8 bytes, even on + // 32-bit systems. + pad int +} + +// init checks that the partial order in lockPartialOrder fits within the total +// order determined by the order of the lockRank constants. +func init() { + for rank, list := range lockPartialOrder { + for _, entry := range list { + if entry > lockRank(rank) { + println("lockPartial order row", lockRank(rank).String(), "entry", entry.String()) + throw("lockPartialOrder table is inconsistent with total lock ranking order") + } + } + } +} + +func lockInit(l *mutex, rank lockRank) { + l.rank = rank +} + +func getLockRank(l *mutex) lockRank { + return l.rank +} + +// The following functions are the entry-points to record lock +// operations. +// All of these are nosplit and switch to the system stack immediately +// to avoid stack growths. Since a stack growth could itself have lock +// operations, this prevents re-entrant calls. + +// lockWithRank is like lock(l), but allows the caller to specify a lock rank +// when acquiring a non-static lock. +//go:nosplit +func lockWithRank(l *mutex, rank lockRank) { + if l == &debuglock || l == &paniclk { + // debuglock is only used for println/printlock(). Don't do lock + // rank recording for it, since print/println are used when + // printing out a lock ordering problem below. + // + // paniclk has an ordering problem, since it can be acquired + // during a panic with any other locks held (especially if the + // panic is because of a directed segv), and yet also allg is + // acquired after paniclk in tracebackothers()). This is a genuine + // problem, so for now we don't do lock rank recording for paniclk + // either. + lock2(l) + return + } + if rank == 0 { + rank = lockRankLeafRank + } + gp := getg() + // Log the new class. + systemstack(func() { + i := gp.m.locksHeldLen + if i >= len(gp.m.locksHeld) { + throw("too many locks held concurrently for rank checking") + } + gp.m.locksHeld[i].rank = rank + gp.m.locksHeld[i].lockAddr = uintptr(unsafe.Pointer(l)) + gp.m.locksHeldLen++ + + // i is the index of the lock being acquired + if i > 0 { + checkRanks(gp, gp.m.locksHeld[i-1].rank, rank) + } + lock2(l) + }) +} + +// acquireLockRank acquires a rank which is not associated with a mutex lock +//go:nosplit +func acquireLockRank(rank lockRank) { + gp := getg() + // Log the new class. + systemstack(func() { + i := gp.m.locksHeldLen + if i >= len(gp.m.locksHeld) { + throw("too many locks held concurrently for rank checking") + } + gp.m.locksHeld[i].rank = rank + gp.m.locksHeld[i].lockAddr = 0 + gp.m.locksHeldLen++ + + // i is the index of the lock being acquired + if i > 0 { + checkRanks(gp, gp.m.locksHeld[i-1].rank, rank) + } + }) +} + +// checkRanks checks if goroutine g, which has mostly recently acquired a lock +// with rank 'prevRank', can now acquire a lock with rank 'rank'. +func checkRanks(gp *g, prevRank, rank lockRank) { + rankOK := false + if rank < prevRank { + // If rank < prevRank, then we definitely have a rank error + rankOK = false + } else if rank == lockRankLeafRank { + // If new lock is a leaf lock, then the preceding lock can + // be anything except another leaf lock. + rankOK = prevRank < lockRankLeafRank + } else { + // We've now verified the total lock ranking, but we + // also enforce the partial ordering specified by + // lockPartialOrder as well. Two locks with the same rank + // can only be acquired at the same time if explicitly + // listed in the lockPartialOrder table. + list := lockPartialOrder[rank] + for _, entry := range list { + if entry == prevRank { + rankOK = true + break + } + } + } + if !rankOK { + printlock() + println(gp.m.procid, " ======") + for j, held := range gp.m.locksHeld[:gp.m.locksHeldLen] { + println(j, ":", held.rank.String(), held.rank, unsafe.Pointer(gp.m.locksHeld[j].lockAddr)) + } + throw("lock ordering problem") + } +} + +//go:nosplit +func unlockWithRank(l *mutex) { + if l == &debuglock || l == &paniclk { + // See comment at beginning of lockWithRank. + unlock2(l) + return + } + gp := getg() + systemstack(func() { + found := false + for i := gp.m.locksHeldLen - 1; i >= 0; i-- { + if gp.m.locksHeld[i].lockAddr == uintptr(unsafe.Pointer(l)) { + found = true + copy(gp.m.locksHeld[i:gp.m.locksHeldLen-1], gp.m.locksHeld[i+1:gp.m.locksHeldLen]) + gp.m.locksHeldLen-- + break + } + } + if !found { + println(gp.m.procid, ":", l.rank.String(), l.rank, l) + throw("unlock without matching lock acquire") + } + unlock2(l) + }) +} + +// releaseLockRank releases a rank which is not associated with a mutex lock +//go:nosplit +func releaseLockRank(rank lockRank) { + gp := getg() + systemstack(func() { + found := false + for i := gp.m.locksHeldLen - 1; i >= 0; i-- { + if gp.m.locksHeld[i].rank == rank && gp.m.locksHeld[i].lockAddr == 0 { + found = true + copy(gp.m.locksHeld[i:gp.m.locksHeldLen-1], gp.m.locksHeld[i+1:gp.m.locksHeldLen]) + gp.m.locksHeldLen-- + break + } + } + if !found { + println(gp.m.procid, ":", rank.String(), rank) + throw("lockRank release without matching lockRank acquire") + } + }) +} + +//go:nosplit +func lockWithRankMayAcquire(l *mutex, rank lockRank) { + gp := getg() + if gp.m.locksHeldLen == 0 { + // No possibilty of lock ordering problem if no other locks held + return + } + + systemstack(func() { + i := gp.m.locksHeldLen + if i >= len(gp.m.locksHeld) { + throw("too many locks held concurrently for rank checking") + } + // Temporarily add this lock to the locksHeld list, so + // checkRanks() will print out list, including this lock, if there + // is a lock ordering problem. + gp.m.locksHeld[i].rank = rank + gp.m.locksHeld[i].lockAddr = uintptr(unsafe.Pointer(l)) + gp.m.locksHeldLen++ + checkRanks(gp, gp.m.locksHeld[i-1].rank, rank) + gp.m.locksHeldLen-- + }) +} diff --git a/libgo/go/runtime/malloc.go b/libgo/go/runtime/malloc.go index 6df7eaa53bb..81351eefbb7 100644 --- a/libgo/go/runtime/malloc.go +++ b/libgo/go/runtime/malloc.go @@ -312,7 +312,9 @@ const ( // // On other platforms, the user address space is contiguous // and starts at 0, so no offset is necessary. - arenaBaseOffset = sys.GoarchAmd64*(1<<47) + (^0x0a00000000000000+1)&uintptrMask*sys.GoosAix*sys.GoarchPpc64 + arenaBaseOffset = 0xffff800000000000*sys.GoarchAmd64 + 0x0a00000000000000*sys.GoosAix*sys.GoarchPpc64 + // A typed version of this constant that will make it into DWARF (for viewcore). + arenaBaseOffsetUintptr = uintptr(arenaBaseOffset) // Max number of threads to run garbage collection. // 2, 3, and 4 are all plausible maximums depending @@ -476,11 +478,21 @@ func mallocinit() { physHugePageShift++ } } + if pagesPerArena%pagesPerSpanRoot != 0 { + print("pagesPerArena (", pagesPerArena, ") is not divisible by pagesPerSpanRoot (", pagesPerSpanRoot, ")\n") + throw("bad pagesPerSpanRoot") + } + if pagesPerArena%pagesPerReclaimerChunk != 0 { + print("pagesPerArena (", pagesPerArena, ") is not divisible by pagesPerReclaimerChunk (", pagesPerReclaimerChunk, ")\n") + throw("bad pagesPerReclaimerChunk") + } // Initialize the heap. mheap_.init() - _g_ := getg() - _g_.m.mcache = allocmcache() + mcache0 = allocmcache() + lockInit(&gcBitsArenas.lock, lockRankGcBitsArenas) + lockInit(&proflock, lockRankProf) + lockInit(&globalAlloc.mutex, lockRankGlobalAlloc) // Create initial arena growth hints. if sys.PtrSize == 8 { @@ -605,7 +617,7 @@ func mallocinit() { a, size := sysReserveAligned(unsafe.Pointer(p), arenaSize, heapArenaBytes) if a != nil { mheap_.arena.init(uintptr(a), size) - p = uintptr(a) + size // For hint below + p = mheap_.arena.end // For hint below break } } @@ -937,7 +949,7 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer { // but before syscall.CgocallDone. Treat this allocation as a // callback. incallback := false - if gomcache() == nil && getg().m.ncgo > 0 { + if gp := getg(); gp.m.p == 0 && gp.m.ncgo > 0 { exitsyscall() incallback = true } @@ -975,7 +987,20 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer { shouldhelpgc := false dataSize := size - c := gomcache() + var c *mcache + if mp.p != 0 { + c = mp.p.ptr().mcache + } else { + // We will be called without a P while bootstrapping, + // in which case we use mcache0, which is set in mallocinit. + // mcache0 is cleared when bootstrapping is complete, + // by procresize. + c = mcache0 + if c == nil { + throw("malloc called with no P") + } + } + var span *mspan var x unsafe.Pointer noscan := typ == nil || typ.ptrdata == 0 if size <= maxSmallSize { @@ -1031,10 +1056,10 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer { return x } // Allocate a new maxTinySize block. - span := c.alloc[tinySpanClass] + span = c.alloc[tinySpanClass] v := nextFreeFast(span) if v == 0 { - v, _, shouldhelpgc = c.nextFree(tinySpanClass) + v, span, shouldhelpgc = c.nextFree(tinySpanClass) } x = unsafe.Pointer(v) (*[2]uint64)(x)[0] = 0 @@ -1049,13 +1074,13 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer { } else { var sizeclass uint8 if size <= smallSizeMax-8 { - sizeclass = size_to_class8[(size+smallSizeDiv-1)/smallSizeDiv] + sizeclass = size_to_class8[divRoundUp(size, smallSizeDiv)] } else { - sizeclass = size_to_class128[(size-smallSizeMax+largeSizeDiv-1)/largeSizeDiv] + sizeclass = size_to_class128[divRoundUp(size-smallSizeMax, largeSizeDiv)] } size = uintptr(class_to_size[sizeclass]) spc := makeSpanClass(sizeclass, noscan) - span := c.alloc[spc] + span = c.alloc[spc] v := nextFreeFast(span) if v == 0 { v, span, shouldhelpgc = c.nextFree(spc) @@ -1066,15 +1091,14 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer { } } } else { - var s *mspan shouldhelpgc = true systemstack(func() { - s = largeAlloc(size, needzero, noscan) + span = largeAlloc(size, needzero, noscan) }) - s.freeindex = 1 - s.allocCount = 1 - x = unsafe.Pointer(s.base()) - size = s.elemsize + span.freeindex = 1 + span.allocCount = 1 + x = unsafe.Pointer(span.base()) + size = span.elemsize } var scanSize uintptr @@ -1106,7 +1130,7 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer { // This may be racing with GC so do it atomically if there can be // a race marking the bit. if gcphase != _GCoff { - gcmarknewobject(uintptr(x), size, scanSize) + gcmarknewobject(span, uintptr(x), size, scanSize) } if raceenabled { @@ -1174,10 +1198,16 @@ func largeAlloc(size uintptr, needzero bool, noscan bool) *mspan { // pays the debt down to npage pages. deductSweepCredit(npages*_PageSize, npages) - s := mheap_.alloc(npages, makeSpanClass(0, noscan), needzero) + spc := makeSpanClass(0, noscan) + s := mheap_.alloc(npages, spc, needzero) if s == nil { throw("out of memory") } + if go115NewMCentralImpl { + // Put the large span in the mcentral swept list so that it's + // visible to the background sweeper. + mheap_.central[spc].mcentral.fullSwept(mheap_.sweepgen).push(s) + } s.limit = s.base() + size heapBitsForAddr(s.base()).initSpan(s) return s @@ -1218,7 +1248,16 @@ func reflect_unsafe_NewArray(typ *_type, n int) unsafe.Pointer { } func profilealloc(mp *m, x unsafe.Pointer, size uintptr) { - mp.mcache.next_sample = nextSample() + var c *mcache + if mp.p != 0 { + c = mp.p.ptr().mcache + } else { + c = mcache0 + if c == nil { + throw("profilealloc called with no P") + } + } + c.next_sample = nextSample() mProf_Malloc(x, size) } @@ -1411,6 +1450,13 @@ type linearAlloc struct { } func (l *linearAlloc) init(base, size uintptr) { + if base+size < base { + // Chop off the last byte. The runtime isn't prepared + // to deal with situations where the bounds could overflow. + // Leave that memory reserved, though, so we don't map it + // later. + size -= 1 + } l.next, l.mapped = base, base l.end = base + size } diff --git a/libgo/go/runtime/map.go b/libgo/go/runtime/map.go index 6667fe7cfe5..b82977103c0 100644 --- a/libgo/go/runtime/map.go +++ b/libgo/go/runtime/map.go @@ -81,7 +81,7 @@ const ( bucketCnt = 1 << bucketCntBits // Maximum average load of a bucket that triggers growth is 6.5. - // Represent as loadFactorNum/loadFactDen, to allow integer math. + // Represent as loadFactorNum/loadFactorDen, to allow integer math. loadFactorNum = 13 loadFactorDen = 2 diff --git a/libgo/go/runtime/map_benchmark_test.go b/libgo/go/runtime/map_benchmark_test.go index bae1aa0dbd6..893cb6c5b6e 100644 --- a/libgo/go/runtime/map_benchmark_test.go +++ b/libgo/go/runtime/map_benchmark_test.go @@ -513,3 +513,22 @@ func BenchmarkMapInterfacePtr(b *testing.B) { BoolSink = m[key] } } + +var ( + hintLessThan8 = 7 + hintGreaterThan8 = 32 +) + +func BenchmarkNewEmptyMapHintLessThan8(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = make(map[int]int, hintLessThan8) + } +} + +func BenchmarkNewEmptyMapHintGreaterThan8(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = make(map[int]int, hintGreaterThan8) + } +} diff --git a/libgo/go/runtime/mbarrier.go b/libgo/go/runtime/mbarrier.go index a4f9b3c0350..836f85a0330 100644 --- a/libgo/go/runtime/mbarrier.go +++ b/libgo/go/runtime/mbarrier.go @@ -163,8 +163,8 @@ func typedmemmove(typ *_type, dst, src unsafe.Pointer) { if dst == src { return } - if typ.ptrdata != 0 { - bulkBarrierPreWrite(uintptr(dst), uintptr(src), typ.size) + if writeBarrier.needed && typ.ptrdata != 0 { + bulkBarrierPreWrite(uintptr(dst), uintptr(src), typ.ptrdata) } // There's a race here: if some other goroutine can write to // src, it may change some pointer in src after we've @@ -199,17 +199,18 @@ func reflectlite_typedmemmove(typ *_type, dst, src unsafe.Pointer) { // typedmemmovepartial is like typedmemmove but assumes that // dst and src point off bytes into the value and only copies size bytes. +// off must be a multiple of sys.PtrSize. //go:linkname reflect_typedmemmovepartial reflect.typedmemmovepartial func reflect_typedmemmovepartial(typ *_type, dst, src unsafe.Pointer, off, size uintptr) { - if writeBarrier.needed && typ.ptrdata != 0 && size >= sys.PtrSize { - // Pointer-align start address for bulk barrier. - adst, asrc, asize := dst, src, size - if frag := -off & (sys.PtrSize - 1); frag != 0 { - adst = add(dst, frag) - asrc = add(src, frag) - asize -= frag + if writeBarrier.needed && typ.ptrdata > off && size >= sys.PtrSize { + if off&(sys.PtrSize-1) != 0 { + panic("reflect: internal error: misaligned offset") } - bulkBarrierPreWrite(uintptr(adst), uintptr(asrc), asize&^(sys.PtrSize-1)) + pwsize := alignDown(size, sys.PtrSize) + if poff := typ.ptrdata - off; pwsize > poff { + pwsize = poff + } + bulkBarrierPreWrite(uintptr(dst), uintptr(src), pwsize) } memmove(dst, src, size) @@ -257,7 +258,8 @@ func typedslicecopy(typ *_type, dstPtr unsafe.Pointer, dstLen int, srcPtr unsafe // before calling typedslicecopy. size := uintptr(n) * typ.size if writeBarrier.needed { - bulkBarrierPreWrite(uintptr(dstPtr), uintptr(srcPtr), size) + pwsize := size - typ.size + typ.ptrdata + bulkBarrierPreWrite(uintptr(dstPtr), uintptr(srcPtr), pwsize) } // See typedmemmove for a discussion of the race between the // barrier and memmove. @@ -304,8 +306,8 @@ func reflect_typedslicecopy(elemType *_type, dst, src slice) int { // //go:nosplit func typedmemclr(typ *_type, ptr unsafe.Pointer) { - if typ.ptrdata != 0 { - bulkBarrierPreWrite(uintptr(ptr), 0, typ.size) + if writeBarrier.needed && typ.ptrdata != 0 { + bulkBarrierPreWrite(uintptr(ptr), 0, typ.ptrdata) } memclrNoHeapPointers(ptr, typ.size) } @@ -317,7 +319,7 @@ func reflect_typedmemclr(typ *_type, ptr unsafe.Pointer) { //go:linkname reflect_typedmemclrpartial reflect.typedmemclrpartial func reflect_typedmemclrpartial(typ *_type, ptr unsafe.Pointer, off, size uintptr) { - if typ.ptrdata != 0 { + if writeBarrier.needed && typ.ptrdata != 0 { bulkBarrierPreWrite(uintptr(ptr), 0, size) } memclrNoHeapPointers(ptr, size) diff --git a/libgo/go/runtime/mbitmap.go b/libgo/go/runtime/mbitmap.go index be8e00c2025..7acd5d1e07a 100644 --- a/libgo/go/runtime/mbitmap.go +++ b/libgo/go/runtime/mbitmap.go @@ -885,58 +885,22 @@ func (h heapBits) clearCheckmarkSpan(size, n, total uintptr) { } } -// oneBitCount is indexed by byte and produces the -// number of 1 bits in that byte. For example 128 has 1 bit set -// and oneBitCount[128] will holds 1. -var oneBitCount = [256]uint8{ - 0, 1, 1, 2, 1, 2, 2, 3, - 1, 2, 2, 3, 2, 3, 3, 4, - 1, 2, 2, 3, 2, 3, 3, 4, - 2, 3, 3, 4, 3, 4, 4, 5, - 1, 2, 2, 3, 2, 3, 3, 4, - 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, - 3, 4, 4, 5, 4, 5, 5, 6, - 1, 2, 2, 3, 2, 3, 3, 4, - 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, - 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, - 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, - 4, 5, 5, 6, 5, 6, 6, 7, - 1, 2, 2, 3, 2, 3, 3, 4, - 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, - 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, - 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, - 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, - 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, - 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, - 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, - 5, 6, 6, 7, 6, 7, 7, 8} - // countAlloc returns the number of objects allocated in span s by // scanning the allocation bitmap. -// TODO:(rlh) Use popcount intrinsic. func (s *mspan) countAlloc() int { count := 0 - maxIndex := s.nelems / 8 - for i := uintptr(0); i < maxIndex; i++ { - mrkBits := *s.gcmarkBits.bytep(i) - count += int(oneBitCount[mrkBits]) - } - if bitsInLastByte := s.nelems % 8; bitsInLastByte != 0 { - mrkBits := *s.gcmarkBits.bytep(maxIndex) - mask := uint8((1 << bitsInLastByte) - 1) - bits := mrkBits & mask - count += int(oneBitCount[bits]) + bytes := divRoundUp(s.nelems, 8) + // Iterate over each 8-byte chunk and count allocations + // with an intrinsic. Note that newMarkBits guarantees that + // gcmarkBits will be 8-byte aligned, so we don't have to + // worry about edge cases, irrelevant bits will simply be zero. + for i := uintptr(0); i < bytes; i += 8 { + // Extract 64 bits from the byte pointer and get a OnesCount. + // Note that the unsafe cast here doesn't preserve endianness, + // but that's OK. We only care about how many bits are 1, not + // about the order we discover them in. + mrkBits := *(*uint64)(unsafe.Pointer(s.gcmarkBits.bytep(i))) + count += sys.OnesCount64(mrkBits) } return count } diff --git a/libgo/go/runtime/mcache.go b/libgo/go/runtime/mcache.go index 27328e1e31e..ba526247217 100644 --- a/libgo/go/runtime/mcache.go +++ b/libgo/go/runtime/mcache.go @@ -123,7 +123,11 @@ func (c *mcache) refill(spc spanClass) { if s.sweepgen != mheap_.sweepgen+3 { throw("bad sweepgen in refill") } - atomic.Store(&s.sweepgen, mheap_.sweepgen) + if go115NewMCentralImpl { + mheap_.central[spc].mcentral.uncacheSpan(s) + } else { + atomic.Store(&s.sweepgen, mheap_.sweepgen) + } } // Get a new cached span from the central lists. diff --git a/libgo/go/runtime/mcentral.go b/libgo/go/runtime/mcentral.go index 78a3ae6ac19..ed49d86d0c6 100644 --- a/libgo/go/runtime/mcentral.go +++ b/libgo/go/runtime/mcentral.go @@ -20,8 +20,31 @@ import "runtime/internal/atomic" type mcentral struct { lock mutex spanclass spanClass - nonempty mSpanList // list of spans with a free object, ie a nonempty free list - empty mSpanList // list of spans with no free objects (or cached in an mcache) + + // For !go115NewMCentralImpl. + nonempty mSpanList // list of spans with a free object, ie a nonempty free list + empty mSpanList // list of spans with no free objects (or cached in an mcache) + + // partial and full contain two mspan sets: one of swept in-use + // spans, and one of unswept in-use spans. These two trade + // roles on each GC cycle. The unswept set is drained either by + // allocation or by the background sweeper in every GC cycle, + // so only two roles are necessary. + // + // sweepgen is increased by 2 on each GC cycle, so the swept + // spans are in partial[sweepgen/2%2] and the unswept spans are in + // partial[1-sweepgen/2%2]. Sweeping pops spans from the + // unswept set and pushes spans that are still in-use on the + // swept set. Likewise, allocating an in-use span pushes it + // on the swept set. + // + // Some parts of the sweeper can sweep arbitrary spans, and hence + // can't remove them from the unswept set, but will add the span + // to the appropriate swept list. As a result, the parts of the + // sweeper and mcentral that do consume from the unswept list may + // encounter swept spans, and these should be ignored. + partial [2]spanSet // list of spans with a free object + full [2]spanSet // list of spans with no free objects // nmalloc is the cumulative count of objects allocated from // this mcentral, assuming all spans in mcaches are @@ -32,12 +55,168 @@ type mcentral struct { // Initialize a single central free list. func (c *mcentral) init(spc spanClass) { c.spanclass = spc - c.nonempty.init() - c.empty.init() + if go115NewMCentralImpl { + lockInit(&c.partial[0].spineLock, lockRankSpanSetSpine) + lockInit(&c.partial[1].spineLock, lockRankSpanSetSpine) + lockInit(&c.full[0].spineLock, lockRankSpanSetSpine) + lockInit(&c.full[1].spineLock, lockRankSpanSetSpine) + } else { + c.nonempty.init() + c.empty.init() + lockInit(&c.lock, lockRankMcentral) + } +} + +// partialUnswept returns the spanSet which holds partially-filled +// unswept spans for this sweepgen. +func (c *mcentral) partialUnswept(sweepgen uint32) *spanSet { + return &c.partial[1-sweepgen/2%2] +} + +// partialSwept returns the spanSet which holds partially-filled +// swept spans for this sweepgen. +func (c *mcentral) partialSwept(sweepgen uint32) *spanSet { + return &c.partial[sweepgen/2%2] +} + +// fullUnswept returns the spanSet which holds unswept spans without any +// free slots for this sweepgen. +func (c *mcentral) fullUnswept(sweepgen uint32) *spanSet { + return &c.full[1-sweepgen/2%2] +} + +// fullSwept returns the spanSet which holds swept spans without any +// free slots for this sweepgen. +func (c *mcentral) fullSwept(sweepgen uint32) *spanSet { + return &c.full[sweepgen/2%2] } // Allocate a span to use in an mcache. func (c *mcentral) cacheSpan() *mspan { + if !go115NewMCentralImpl { + return c.oldCacheSpan() + } + // Deduct credit for this span allocation and sweep if necessary. + spanBytes := uintptr(class_to_allocnpages[c.spanclass.sizeclass()]) * _PageSize + deductSweepCredit(spanBytes, 0) + + sg := mheap_.sweepgen + + traceDone := false + if trace.enabled { + traceGCSweepStart() + } + + // If we sweep spanBudget spans without finding any free + // space, just allocate a fresh span. This limits the amount + // of time we can spend trying to find free space and + // amortizes the cost of small object sweeping over the + // benefit of having a full free span to allocate from. By + // setting this to 100, we limit the space overhead to 1%. + // + // TODO(austin,mknyszek): This still has bad worst-case + // throughput. For example, this could find just one free slot + // on the 100th swept span. That limits allocation latency, but + // still has very poor throughput. We could instead keep a + // running free-to-used budget and switch to fresh span + // allocation if the budget runs low. + spanBudget := 100 + + var s *mspan + + // Try partial swept spans first. + if s = c.partialSwept(sg).pop(); s != nil { + goto havespan + } + + // Now try partial unswept spans. + for ; spanBudget >= 0; spanBudget-- { + s = c.partialUnswept(sg).pop() + if s == nil { + break + } + if atomic.Load(&s.sweepgen) == sg-2 && atomic.Cas(&s.sweepgen, sg-2, sg-1) { + // We got ownership of the span, so let's sweep it and use it. + s.sweep(true) + goto havespan + } + // We failed to get ownership of the span, which means it's being or + // has been swept by an asynchronous sweeper that just couldn't remove it + // from the unswept list. That sweeper took ownership of the span and + // responsibility for either freeing it to the heap or putting it on the + // right swept list. Either way, we should just ignore it (and it's unsafe + // for us to do anything else). + } + // Now try full unswept spans, sweeping them and putting them into the + // right list if we fail to get a span. + for ; spanBudget >= 0; spanBudget-- { + s = c.fullUnswept(sg).pop() + if s == nil { + break + } + if atomic.Load(&s.sweepgen) == sg-2 && atomic.Cas(&s.sweepgen, sg-2, sg-1) { + // We got ownership of the span, so let's sweep it. + s.sweep(true) + // Check if there's any free space. + freeIndex := s.nextFreeIndex() + if freeIndex != s.nelems { + s.freeindex = freeIndex + goto havespan + } + // Add it to the swept list, because sweeping didn't give us any free space. + c.fullSwept(sg).push(s) + } + // See comment for partial unswept spans. + } + if trace.enabled { + traceGCSweepDone() + traceDone = true + } + + // We failed to get a span from the mcentral so get one from mheap. + s = c.grow() + if s == nil { + return nil + } + + // At this point s is a span that should have free slots. +havespan: + if trace.enabled && !traceDone { + traceGCSweepDone() + } + n := int(s.nelems) - int(s.allocCount) + if n == 0 || s.freeindex == s.nelems || uintptr(s.allocCount) == s.nelems { + throw("span has no free objects") + } + // Assume all objects from this span will be allocated in the + // mcache. If it gets uncached, we'll adjust this. + atomic.Xadd64(&c.nmalloc, int64(n)) + usedBytes := uintptr(s.allocCount) * s.elemsize + atomic.Xadd64(&memstats.heap_live, int64(spanBytes)-int64(usedBytes)) + if trace.enabled { + // heap_live changed. + traceHeapAlloc() + } + if gcBlackenEnabled != 0 { + // heap_live changed. + gcController.revise() + } + freeByteBase := s.freeindex &^ (64 - 1) + whichByte := freeByteBase / 8 + // Init alloc bits cache. + s.refillAllocCache(whichByte) + + // Adjust the allocCache so that s.freeindex corresponds to the low bit in + // s.allocCache. + s.allocCache >>= s.freeindex % 64 + + return s +} + +// Allocate a span to use in an mcache. +// +// For !go115NewMCentralImpl. +func (c *mcentral) oldCacheSpan() *mspan { // Deduct credit for this span allocation and sweep if necessary. spanBytes := uintptr(class_to_allocnpages[c.spanclass.sizeclass()]) * _PageSize deductSweepCredit(spanBytes, 0) @@ -147,7 +326,77 @@ havespan: } // Return span from an mcache. +// +// s must have a span class corresponding to this +// mcentral and it must not be empty. func (c *mcentral) uncacheSpan(s *mspan) { + if !go115NewMCentralImpl { + c.oldUncacheSpan(s) + return + } + if s.allocCount == 0 { + throw("uncaching span but s.allocCount == 0") + } + + sg := mheap_.sweepgen + stale := s.sweepgen == sg+1 + + // Fix up sweepgen. + if stale { + // Span was cached before sweep began. It's our + // responsibility to sweep it. + // + // Set sweepgen to indicate it's not cached but needs + // sweeping and can't be allocated from. sweep will + // set s.sweepgen to indicate s is swept. + atomic.Store(&s.sweepgen, sg-1) + } else { + // Indicate that s is no longer cached. + atomic.Store(&s.sweepgen, sg) + } + n := int(s.nelems) - int(s.allocCount) + + // Fix up statistics. + if n > 0 { + // cacheSpan updated alloc assuming all objects on s + // were going to be allocated. Adjust for any that + // weren't. We must do this before potentially + // sweeping the span. + atomic.Xadd64(&c.nmalloc, -int64(n)) + + if !stale { + // (*mcentral).cacheSpan conservatively counted + // unallocated slots in heap_live. Undo this. + // + // If this span was cached before sweep, then + // heap_live was totally recomputed since + // caching this span, so we don't do this for + // stale spans. + atomic.Xadd64(&memstats.heap_live, -int64(n)*int64(s.elemsize)) + } + } + + // Put the span in the appropriate place. + if stale { + // It's stale, so just sweep it. Sweeping will put it on + // the right list. + s.sweep(false) + } else { + if n > 0 { + // Put it back on the partial swept list. + c.partialSwept(sg).push(s) + } else { + // There's no free space and it's not stale, so put it on the + // full swept list. + c.fullSwept(sg).push(s) + } + } +} + +// Return span from an mcache. +// +// For !go115NewMCentralImpl. +func (c *mcentral) oldUncacheSpan(s *mspan) { if s.allocCount == 0 { throw("uncaching span but s.allocCount == 0") } @@ -206,6 +455,8 @@ func (c *mcentral) uncacheSpan(s *mspan) { // freeSpan reports whether s was returned to the heap. // If preserve=true, it does not move s (the caller // must take care of it). +// +// For !go115NewMCentralImpl. func (c *mcentral) freeSpan(s *mspan, preserve bool, wasempty bool) bool { if sg := mheap_.sweepgen; s.sweepgen == sg+1 || s.sweepgen == sg+3 { throw("freeSpan given cached span") diff --git a/libgo/go/runtime/mgc.go b/libgo/go/runtime/mgc.go index 24043cfb2e2..9dd7bff8a80 100644 --- a/libgo/go/runtime/mgc.go +++ b/libgo/go/runtime/mgc.go @@ -191,6 +191,9 @@ func gcinit() { work.startSema = 1 work.markDoneSema = 1 + lockInit(&work.sweepWaiters.lock, lockRankSweepWaiters) + lockInit(&work.assistQueue.lock, lockRankAssistQueue) + lockInit(&work.wbufSpans.lock, lockRankWbufSpans) } func readgogc() int32 { @@ -235,8 +238,6 @@ func setGCPercent(in int32) (out int32) { gcSetTriggerRatio(memstats.triggerRatio) unlock(&mheap_.lock) }) - // Pacing changed, so the scavenger should be awoken. - wakeScavenger() // If we just disabled GC, wait for any concurrent GC mark to // finish so we always return with no GC running. @@ -1279,6 +1280,7 @@ func gcStart(trigger gcTrigger) { } // Ok, we're doing it! Stop everybody else + semacquire(&gcsema) semacquire(&worldsema) if trace.enabled { @@ -1318,6 +1320,7 @@ func gcStart(trigger gcTrigger) { systemstack(func() { finishsweep_m() }) + // clearpools before we start the GC. If we wait they memory will not be // reclaimed until the next GC cycle. clearpools() @@ -1371,15 +1374,26 @@ func gcStart(trigger gcTrigger) { // the world. gcController.markStartTime = now + // In STW mode, we could block the instant systemstack + // returns, so make sure we're not preemptible. + mp = acquirem() + // Concurrent mark. systemstack(func() { now = startTheWorldWithSema(trace.enabled) work.pauseNS += now - work.pauseStart work.tMark = now }) - // In STW mode, we could block the instant systemstack - // returns, so don't do anything important here. Make sure we - // block rather than returning to user code. + + // Release the world sema before Gosched() in STW mode + // because we will need to reacquire it later but before + // this goroutine becomes runnable again, and we could + // self-deadlock otherwise. + semrelease(&worldsema) + releasem(mp) + + // Make sure we block instead of returning to user code + // in STW mode. if mode != gcBackgroundMode { Gosched() } @@ -1446,6 +1460,10 @@ top: return } + // forEachP needs worldsema to execute, and we'll need it to + // stop the world later, so acquire worldsema now. + semacquire(&worldsema) + // Flush all local buffers and collect flushedWork flags. gcMarkDoneFlushed = 0 systemstack(func() { @@ -1506,6 +1524,7 @@ top: // work to do. Keep going. It's possible the // transition condition became true again during the // ragged barrier, so re-check it. + semrelease(&worldsema) goto top } @@ -1582,6 +1601,7 @@ top: now := startTheWorldWithSema(true) work.pauseNS += now - work.pauseStart }) + semrelease(&worldsema) goto top } } @@ -1687,9 +1707,6 @@ func gcMarkTermination(nextTriggerRatio float64) { // Update GC trigger and pacing for the next cycle. gcSetTriggerRatio(nextTriggerRatio) - // Pacing changed, so the scavenger should be awoken. - wakeScavenger() - // Update timing memstats now := nanotime() sec, nsec, _ := time_now() @@ -1796,6 +1813,7 @@ func gcMarkTermination(nextTriggerRatio float64) { } semrelease(&worldsema) + semrelease(&gcsema) // Careful: another GC cycle may start now. releasem(mp) @@ -2121,6 +2139,9 @@ func gcMark(start_time int64) { // gcSweep must be called on the system stack because it acquires the heap // lock. See mheap for details. +// +// The world must be stopped. +// //go:systemstack func gcSweep(mode gcMode) { if gcphase != _GCoff { @@ -2130,7 +2151,7 @@ func gcSweep(mode gcMode) { lock(&mheap_.lock) mheap_.sweepgen += 2 mheap_.sweepdone = 0 - if mheap_.sweepSpans[mheap_.sweepgen/2%2].index != 0 { + if !go115NewMCentralImpl && mheap_.sweepSpans[mheap_.sweepgen/2%2].index != 0 { // We should have drained this list during the last // sweep phase. We certainly need to start this phase // with an empty swept list. @@ -2142,6 +2163,10 @@ func gcSweep(mode gcMode) { mheap_.reclaimCredit = 0 unlock(&mheap_.lock) + if go115NewMCentralImpl { + sweep.centralIndex.clear() + } + if !_ConcurrentSweep || mode == gcForceBlockMode { // Special case synchronous sweep. // Record that no proportional sweeping has to happen. diff --git a/libgo/go/runtime/mgcmark.go b/libgo/go/runtime/mgcmark.go index a5af5d2446c..4e4d1314060 100644 --- a/libgo/go/runtime/mgcmark.go +++ b/libgo/go/runtime/mgcmark.go @@ -21,10 +21,6 @@ const ( // BSS root. rootBlockBytes = 256 << 10 - // rootBlockSpans is the number of spans to scan per span - // root. - rootBlockSpans = 8 * 1024 // 64MB worth of spans - // maxObletBytes is the maximum bytes of an object to scan at // once. Larger objects will be split up into "oblets" of at // most this size. Since we can scan 1–2 MB/ms, 128 KB bounds @@ -41,14 +37,26 @@ const ( // a syscall, so its overhead is nontrivial). Higher values // make the system less responsive to incoming work. drainCheckThreshold = 100000 + + // pagesPerSpanRoot indicates how many pages to scan from a span root + // at a time. Used by special root marking. + // + // Higher values improve throughput by increasing locality, but + // increase the minimum latency of a marking operation. + // + // Must be a multiple of the pageInUse bitmap element size and + // must also evenly divide pagesPerArena. + pagesPerSpanRoot = 512 + + // go115NewMarkrootSpans is a feature flag that indicates whether + // to use the new bitmap-based markrootSpans implementation. + go115NewMarkrootSpans = true ) // gcMarkRootPrepare queues root scanning jobs (stacks, globals, and // some miscellany) and initializes scanning-related state. // // The world must be stopped. -// -//go:nowritebarrier func gcMarkRootPrepare() { work.nFlushCacheRoots = 0 @@ -65,13 +73,24 @@ func gcMarkRootPrepare() { // // We depend on addfinalizer to mark objects that get // finalizers after root marking. - // - // We're only interested in scanning the in-use spans, - // which will all be swept at this point. More spans - // may be added to this list during concurrent GC, but - // we only care about spans that were allocated before - // this mark phase. - work.nSpanRoots = mheap_.sweepSpans[mheap_.sweepgen/2%2].numBlocks() + if go115NewMarkrootSpans { + // We're going to scan the whole heap (that was available at the time the + // mark phase started, i.e. markArenas) for in-use spans which have specials. + // + // Break up the work into arenas, and further into chunks. + // + // Snapshot allArenas as markArenas. This snapshot is safe because allArenas + // is append-only. + mheap_.markArenas = mheap_.allArenas[:len(mheap_.allArenas):len(mheap_.allArenas)] + work.nSpanRoots = len(mheap_.markArenas) * (pagesPerArena / pagesPerSpanRoot) + } else { + // We're only interested in scanning the in-use spans, + // which will all be swept at this point. More spans + // may be added to this list during concurrent GC, but + // we only care about spans that were allocated before + // this mark phase. + work.nSpanRoots = mheap_.sweepSpans[mheap_.sweepgen/2%2].numBlocks() + } // Scan stacks. // @@ -229,10 +248,96 @@ func markrootBlock(roots *gcRootList, gcw *gcWork) { } } -// markrootSpans marks roots for one shard of work.spans. +// markrootSpans marks roots for one shard of markArenas. // //go:nowritebarrier func markrootSpans(gcw *gcWork, shard int) { + if !go115NewMarkrootSpans { + oldMarkrootSpans(gcw, shard) + return + } + // Objects with finalizers have two GC-related invariants: + // + // 1) Everything reachable from the object must be marked. + // This ensures that when we pass the object to its finalizer, + // everything the finalizer can reach will be retained. + // + // 2) Finalizer specials (which are not in the garbage + // collected heap) are roots. In practice, this means the fn + // field must be scanned. + sg := mheap_.sweepgen + + // Find the arena and page index into that arena for this shard. + ai := mheap_.markArenas[shard/(pagesPerArena/pagesPerSpanRoot)] + ha := mheap_.arenas[ai.l1()][ai.l2()] + arenaPage := uint(uintptr(shard) * pagesPerSpanRoot % pagesPerArena) + + // Construct slice of bitmap which we'll iterate over. + specialsbits := ha.pageSpecials[arenaPage/8:] + specialsbits = specialsbits[:pagesPerSpanRoot/8] + for i := range specialsbits { + // Find set bits, which correspond to spans with specials. + specials := atomic.Load8(&specialsbits[i]) + if specials == 0 { + continue + } + for j := uint(0); j < 8; j++ { + if specials&(1<= work.markrootJobs { break @@ -808,7 +916,8 @@ func gcDrain(gcw *gcWork, flags gcDrainFlags) { } // Drain heap marking jobs. - for !(preemptible && gp.preempt) { + // Stop if we're preemptible or if someone wants to STW. + for !(gp.preempt && (preemptible || atomic.Load(&sched.gcwaiting) != 0)) { // Try to keep work available on the global queue. We used to // check if there were waiting workers, but it's better to // just keep work available than to make workers wait. In the @@ -1301,11 +1410,21 @@ func gcDumpObject(label string, obj, off uintptr) { // //go:nowritebarrier //go:nosplit -func gcmarknewobject(obj, size, scanSize uintptr) { +func gcmarknewobject(span *mspan, obj, size, scanSize uintptr) { if useCheckmark { // The world should be stopped so this should not happen. throw("gcmarknewobject called while doing checkmark") } - markBitsForAddr(obj).setMarked() + + // Mark object. + objIndex := span.objIndex(obj) + span.markBitsForIndex(objIndex).setMarked() + + // Mark span. + arena, pageIdx, pageMask := pageIndexOf(span.base()) + if arena.pageMarks[pageIdx]&pageMask == 0 { + atomic.Or8(&arena.pageMarks[pageIdx], pageMask) + } + gcw := &getg().m.p.ptr().gcw gcw.bytesMarked += uint64(size) gcw.scanWork += int64(scanSize) diff --git a/libgo/go/runtime/mgcscavenge.go b/libgo/go/runtime/mgcscavenge.go index d4b527c0713..326e6ee079e 100644 --- a/libgo/go/runtime/mgcscavenge.go +++ b/libgo/go/runtime/mgcscavenge.go @@ -91,6 +91,11 @@ const ( // This ratio is used as part of multiplicative factor to help the scavenger account // for the additional costs of using scavenged memory in its pacing. scavengeCostRatio = 0.7 * sys.GoosDarwin + + // scavengeReservationShards determines the amount of memory the scavenger + // should reserve for scavenging at a time. Specifically, the amount of + // memory reserved is (heap size in bytes) / scavengeReservationShards. + scavengeReservationShards = 64 ) // heapRetained returns an estimate of the current heap RSS. @@ -150,24 +155,39 @@ func gcPaceScavenger() { return } mheap_.scavengeGoal = retainedGoal - mheap_.pages.resetScavengeAddr() } // Sleep/wait state of the background scavenger. var scavenge struct { - lock mutex - g *g - parked bool - timer *timer + lock mutex + g *g + parked bool + timer *timer + sysmonWake uint32 // Set atomically. } -// wakeScavenger unparks the scavenger if necessary. It must be called -// after any pacing update. +// readyForScavenger signals sysmon to wake the scavenger because +// there may be new work to do. +// +// There may be a significant delay between when this function runs +// and when the scavenger is kicked awake, but it may be safely invoked +// in contexts where wakeScavenger is unsafe to call directly. +func readyForScavenger() { + atomic.Store(&scavenge.sysmonWake, 1) +} + +// wakeScavenger immediately unparks the scavenger if necessary. +// +// May run without a P, but it may allocate, so it must not be called +// on any allocation path. // -// mheap_.lock and scavenge.lock must not be held. +// mheap_.lock, scavenge.lock, and sched.lock must not be held. func wakeScavenger() { lock(&scavenge.lock) if scavenge.parked { + // Notify sysmon that it shouldn't bother waking up the scavenger. + atomic.Store(&scavenge.sysmonWake, 0) + // Try to stop the timer but we don't really care if we succeed. // It's possible that either a timer was never started, or that // we're racing with it. @@ -183,9 +203,16 @@ func wakeScavenger() { // scavenger at a "lower priority" but that's OK because it'll // catch up on the work it missed when it does get scheduled. scavenge.parked = false - systemstack(func() { - ready(scavenge.g, 0, false) - }) + + // Ready the goroutine by injecting it. We use injectglist instead + // of ready or goready in order to allow us to run this function + // without a P. injectglist also avoids placing the goroutine in + // the current P's runnext slot, which is desireable to prevent + // the scavenger from interfering with user goroutine scheduling + // too much. + var list gList + list.push(scavenge.g) + injectglist(&list) } unlock(&scavenge.lock) } @@ -227,6 +254,7 @@ func bgscavenge(c chan int) { scavenge.g = getg() + lockInit(&scavenge.lock, lockRankScavenge) lock(&scavenge.lock) scavenge.parked = true @@ -272,13 +300,14 @@ func bgscavenge(c chan int) { unlock(&mheap_.lock) return } - unlock(&mheap_.lock) // Scavenge one page, and measure the amount of time spent scavenging. start := nanotime() - released = mheap_.pages.scavengeOne(physPageSize, false) - atomic.Xadduintptr(&mheap_.pages.scavReleased, released) + released = mheap_.pages.scavenge(physPageSize, true) + mheap_.pages.scav.released += released crit = float64(nanotime() - start) + + unlock(&mheap_.lock) }) if released == 0 { @@ -358,28 +387,36 @@ func bgscavenge(c chan int) { // scavenge scavenges nbytes worth of free pages, starting with the // highest address first. Successive calls continue from where it left -// off until the heap is exhausted. Call resetScavengeAddr to bring it +// off until the heap is exhausted. Call scavengeStartGen to bring it // back to the top of the heap. // // Returns the amount of memory scavenged in bytes. // -// If locked == false, s.mheapLock must not be locked. If locked == true, -// s.mheapLock must be locked. +// s.mheapLock must be held, but may be temporarily released if +// mayUnlock == true. // -// Must run on the system stack because scavengeOne must run on the -// system stack. +// Must run on the system stack because s.mheapLock must be held. // //go:systemstack -func (s *pageAlloc) scavenge(nbytes uintptr, locked bool) uintptr { +func (s *pageAlloc) scavenge(nbytes uintptr, mayUnlock bool) uintptr { + var ( + addrs addrRange + gen uint32 + ) released := uintptr(0) for released < nbytes { - r := s.scavengeOne(nbytes-released, locked) - if r == 0 { - // Nothing left to scavenge! Give up. - break + if addrs.size() == 0 { + if addrs, gen = s.scavengeReserve(); addrs.size() == 0 { + break + } } + r, a := s.scavengeOne(addrs, nbytes-released, mayUnlock) released += r + addrs = a } + // Only unreserve the space which hasn't been scavenged or searched + // to ensure we always make progress. + s.scavengeUnreserve(addrs, gen) return released } @@ -388,9 +425,9 @@ func (s *pageAlloc) scavenge(nbytes uintptr, locked bool) uintptr { // released should be the amount of memory released since the last time this // was called, and forced indicates whether the scavenge was forced by the // application. -func printScavTrace(released uintptr, forced bool) { +func printScavTrace(gen uint32, released uintptr, forced bool) { printlock() - print("scav ", + print("scav ", gen, " ", released>>10, " KiB work, ", atomic.Load64(&memstats.heap_released)>>10, " KiB total, ", (atomic.Load64(&memstats.heap_inuse)*100)/heapRetained(), "% util", @@ -402,39 +439,131 @@ func printScavTrace(released uintptr, forced bool) { printunlock() } -// resetScavengeAddr sets the scavenge start address to the top of the heap's -// address space. This should be called each time the scavenger's pacing -// changes. +// scavengeStartGen starts a new scavenge generation, resetting +// the scavenger's search space to the full in-use address space. // // s.mheapLock must be held. -func (s *pageAlloc) resetScavengeAddr() { - released := atomic.Loaduintptr(&s.scavReleased) +// +// Must run on the system stack because s.mheapLock must be held. +// +//go:systemstack +func (s *pageAlloc) scavengeStartGen() { if debug.scavtrace > 0 { - printScavTrace(released, false) + printScavTrace(s.scav.gen, s.scav.released, false) + } + s.inUse.cloneInto(&s.scav.inUse) + + // Pick the new starting address for the scavenger cycle. + var startAddr offAddr + if s.scav.scavLWM.lessThan(s.scav.freeHWM) { + // The "free" high watermark exceeds the "scavenged" low watermark, + // so there are free scavengable pages in parts of the address space + // that the scavenger already searched, the high watermark being the + // highest one. Pick that as our new starting point to ensure we + // see those pages. + startAddr = s.scav.freeHWM + } else { + // The "free" high watermark does not exceed the "scavenged" low + // watermark. This means the allocator didn't free any memory in + // the range we scavenged last cycle, so we might as well continue + // scavenging from where we were. + startAddr = s.scav.scavLWM } - // Subtract from scavReleased instead of just setting it to zero because - // the scavenger could have increased scavReleased concurrently with the - // load above, and we may miss an update by just blindly zeroing the field. - atomic.Xadduintptr(&s.scavReleased, -released) - s.scavAddr = chunkBase(s.end) - 1 + s.scav.inUse.removeGreaterEqual(startAddr.addr()) + + // reservationBytes may be zero if s.inUse.totalBytes is small, or if + // scavengeReservationShards is large. This case is fine as the scavenger + // will simply be turned off, but it does mean that scavengeReservationShards, + // in concert with pallocChunkBytes, dictates the minimum heap size at which + // the scavenger triggers. In practice this minimum is generally less than an + // arena in size, so virtually every heap has the scavenger on. + s.scav.reservationBytes = alignUp(s.inUse.totalBytes, pallocChunkBytes) / scavengeReservationShards + s.scav.gen++ + s.scav.released = 0 + s.scav.freeHWM = minOffAddr + s.scav.scavLWM = maxOffAddr } -// scavengeOne starts from s.scavAddr and walks down the heap until it finds -// a contiguous run of pages to scavenge. It will try to scavenge at most -// max bytes at once, but may scavenge more to avoid breaking huge pages. Once -// it scavenges some memory it returns how much it scavenged and updates s.scavAddr -// appropriately. s.scavAddr must be reset manually and externally. +// scavengeReserve reserves a contiguous range of the address space +// for scavenging. The maximum amount of space it reserves is proportional +// to the size of the heap. The ranges are reserved from the high addresses +// first. +// +// Returns the reserved range and the scavenge generation number for it. +// +// s.mheapLock must be held. +// +// Must run on the system stack because s.mheapLock must be held. // -// Should it exhaust the heap, it will return 0 and set s.scavAddr to minScavAddr. +//go:systemstack +func (s *pageAlloc) scavengeReserve() (addrRange, uint32) { + // Start by reserving the minimum. + r := s.scav.inUse.removeLast(s.scav.reservationBytes) + + // Return early if the size is zero; we don't want to use + // the bogus address below. + if r.size() == 0 { + return r, s.scav.gen + } + + // The scavenger requires that base be aligned to a + // palloc chunk because that's the unit of operation for + // the scavenger, so align down, potentially extending + // the range. + newBase := alignDown(r.base.addr(), pallocChunkBytes) + + // Remove from inUse however much extra we just pulled out. + s.scav.inUse.removeGreaterEqual(newBase) + r.base = offAddr{newBase} + return r, s.scav.gen +} + +// scavengeUnreserve returns an unscavenged portion of a range that was +// previously reserved with scavengeReserve. // -// If locked == false, s.mheapLock must not be locked. -// If locked == true, s.mheapLock must be locked. +// s.mheapLock must be held. // -// Must be run on the system stack because it either acquires the heap lock -// or executes with the heap lock acquired. +// Must run on the system stack because s.mheapLock must be held. // //go:systemstack -func (s *pageAlloc) scavengeOne(max uintptr, locked bool) uintptr { +func (s *pageAlloc) scavengeUnreserve(r addrRange, gen uint32) { + if r.size() == 0 || gen != s.scav.gen { + return + } + if r.base.addr()%pallocChunkBytes != 0 { + throw("unreserving unaligned region") + } + s.scav.inUse.add(r) +} + +// scavengeOne walks over address range work until it finds +// a contiguous run of pages to scavenge. It will try to scavenge +// at most max bytes at once, but may scavenge more to avoid +// breaking huge pages. Once it scavenges some memory it returns +// how much it scavenged in bytes. +// +// Returns the number of bytes scavenged and the part of work +// which was not yet searched. +// +// work's base address must be aligned to pallocChunkBytes. +// +// s.mheapLock must be held, but may be temporarily released if +// mayUnlock == true. +// +// Must run on the system stack because s.mheapLock must be held. +// +//go:systemstack +func (s *pageAlloc) scavengeOne(work addrRange, max uintptr, mayUnlock bool) (uintptr, addrRange) { + // Defensively check if we've recieved an empty address range. + // If so, just return. + if work.size() == 0 { + // Nothing to do. + return 0, work + } + // Check the prerequisites of work. + if work.base.addr()%pallocChunkBytes != 0 { + throw("scavengeOne called with unaligned work region") + } // Calculate the maximum number of pages to scavenge. // // This should be alignUp(max, pageSize) / pageSize but max can and will @@ -456,84 +585,49 @@ func (s *pageAlloc) scavengeOne(max uintptr, locked bool) uintptr { minPages = 1 } - // Helpers for locking and unlocking only if locked == false. + // Helpers for locking and unlocking only if mayUnlock == true. lockHeap := func() { - if !locked { + if mayUnlock { lock(s.mheapLock) } } unlockHeap := func() { - if !locked { + if mayUnlock { unlock(s.mheapLock) } } - lockHeap() - ci := chunkIndex(s.scavAddr) - if ci < s.start { - unlockHeap() - return 0 - } - - // Check the chunk containing the scav addr, starting at the addr - // and see if there are any free and unscavenged pages. + // Fast path: check the chunk containing the top-most address in work, + // starting at that address's page index in the chunk. // - // Only check this if s.scavAddr is covered by any address range - // in s.inUse, so that we know our check of the summary is safe. - if s.inUse.contains(s.scavAddr) && s.summary[len(s.summary)-1][ci].max() >= uint(minPages) { + // Note that work.end() is exclusive, so get the chunk we care about + // by subtracting 1. + maxAddr := work.limit.addr() - 1 + maxChunk := chunkIndex(maxAddr) + if s.summary[len(s.summary)-1][maxChunk].max() >= uint(minPages) { // We only bother looking for a candidate if there at least - // minPages free pages at all. It's important that we only - // continue if the summary says we can because that's how - // we can tell if parts of the address space are unused. - // See the comment on s.chunks in mpagealloc.go. - base, npages := s.chunkOf(ci).findScavengeCandidate(chunkPageIndex(s.scavAddr), minPages, maxPages) + // minPages free pages at all. + base, npages := s.chunkOf(maxChunk).findScavengeCandidate(chunkPageIndex(maxAddr), minPages, maxPages) // If we found something, scavenge it and return! if npages != 0 { - s.scavengeRangeLocked(ci, base, npages) - unlockHeap() - return uintptr(npages) * pageSize + work.limit = offAddr{s.scavengeRangeLocked(maxChunk, base, npages)} + return uintptr(npages) * pageSize, work } } + // Update the limit to reflect the fact that we checked maxChunk already. + work.limit = offAddr{chunkBase(maxChunk)} - // getInUseRange returns the highest range in the - // intersection of [0, addr] and s.inUse. + // findCandidate finds the next scavenge candidate in work optimistically. // - // s.mheapLock must be held. - getInUseRange := func(addr uintptr) addrRange { - top := s.inUse.findSucc(addr) - if top == 0 { - return addrRange{} - } - r := s.inUse.ranges[top-1] - // addr is inclusive, so treat it as such when - // updating the limit, which is exclusive. - if r.limit > addr+1 { - r.limit = addr + 1 - } - return r - } - - // Slow path: iterate optimistically over the in-use address space - // looking for any free and unscavenged page. If we think we see something, - // lock and verify it! + // Returns the candidate chunk index and true on success, and false on failure. // - // We iterate over the address space by taking ranges from inUse. -newRange: - for { - r := getInUseRange(s.scavAddr) - if r.size() == 0 { - break - } - unlockHeap() - - // Iterate over all of the chunks described by r. - // Note that r.limit is the exclusive upper bound, but what - // we want is the top chunk instead, inclusive, so subtract 1. - bot, top := chunkIndex(r.base), chunkIndex(r.limit-1) - for i := top; i >= bot; i-- { + // The heap need not be locked. + findCandidate := func(work addrRange) (chunkIdx, bool) { + // Iterate over this work's chunks. + for i := chunkIndex(work.limit.addr() - 1); i >= chunkIndex(work.base.addr()); i-- { // If this chunk is totally in-use or has no unscavenged pages, don't bother - // doing a more sophisticated check. + // doing a more sophisticated check. // // Note we're accessing the summary and the chunks without a lock, but // that's fine. We're being optimistic anyway. @@ -550,70 +644,77 @@ newRange: // see a nil pointer in this case if we do race with heap growth, but // just defensively ignore the nils. This operation is optimistic anyway. l2 := (*[1 << pallocChunksL2Bits]pallocData)(atomic.Loadp(unsafe.Pointer(&s.chunks[i.l1()]))) - if l2 == nil || !l2[i.l2()].hasScavengeCandidate(minPages) { - continue + if l2 != nil && l2[i.l2()].hasScavengeCandidate(minPages) { + return i, true } + } + return 0, false + } - // We found a candidate, so let's lock and verify it. - lockHeap() - - // Find, verify, and scavenge if we can. - chunk := s.chunkOf(i) - base, npages := chunk.findScavengeCandidate(pallocChunkPages-1, minPages, maxPages) - if npages > 0 { - // We found memory to scavenge! Mark the bits and report that up. - // scavengeRangeLocked will update scavAddr for us, also. - s.scavengeRangeLocked(i, base, npages) - unlockHeap() - return uintptr(npages) * pageSize - } + // Slow path: iterate optimistically over the in-use address space + // looking for any free and unscavenged page. If we think we see something, + // lock and verify it! + for work.size() != 0 { + unlockHeap() - // We were fooled, let's take this opportunity to move the scavAddr - // all the way down to where we searched as scavenged for future calls - // and keep iterating. Then, go get a new range. - s.scavAddr = chunkBase(i-1) + pallocChunkPages*pageSize - 1 - continue newRange - } + // Search for the candidate. + candidateChunkIdx, ok := findCandidate(work) + + // Lock the heap. We need to do this now if we found a candidate or not. + // If we did, we'll verify it. If not, we need to lock before returning + // anyway. lockHeap() - // Move the scavenger down the heap, past everything we just searched. - // Since we don't check if scavAddr moved while twe let go of the heap lock, - // it's possible that it moved down and we're moving it up here. This - // raciness could result in us searching parts of the heap unnecessarily. - // TODO(mknyszek): Remove this racy behavior through explicit address - // space reservations, which are difficult to do with just scavAddr. - s.scavAddr = r.base - 1 - } - // We reached the end of the in-use address space and couldn't find anything, - // so signal that there's nothing left to scavenge. - s.scavAddr = minScavAddr - unlockHeap() + if !ok { + // We didn't find a candidate, so we're done. + work.limit = work.base + break + } + + // Find, verify, and scavenge if we can. + chunk := s.chunkOf(candidateChunkIdx) + base, npages := chunk.findScavengeCandidate(pallocChunkPages-1, minPages, maxPages) + if npages > 0 { + work.limit = offAddr{s.scavengeRangeLocked(candidateChunkIdx, base, npages)} + return uintptr(npages) * pageSize, work + } - return 0 + // We were fooled, so let's continue from where we left off. + work.limit = offAddr{chunkBase(candidateChunkIdx)} + } + return 0, work } // scavengeRangeLocked scavenges the given region of memory. +// The region of memory is described by its chunk index (ci), +// the starting page index of the region relative to that +// chunk (base), and the length of the region in pages (npages). +// +// Returns the base address of the scavenged region. // // s.mheapLock must be held. -func (s *pageAlloc) scavengeRangeLocked(ci chunkIdx, base, npages uint) { +func (s *pageAlloc) scavengeRangeLocked(ci chunkIdx, base, npages uint) uintptr { s.chunkOf(ci).scavenged.setRange(base, npages) // Compute the full address for the start of the range. addr := chunkBase(ci) + uintptr(base)*pageSize - // Update the scav pointer. - s.scavAddr = addr - 1 + // Update the scavenge low watermark. + if oAddr := (offAddr{addr}); oAddr.lessThan(s.scav.scavLWM) { + s.scav.scavLWM = oAddr + } // Only perform the actual scavenging if we're not in a test. // It's dangerous to do so otherwise. if s.test { - return + return addr } sysUnused(unsafe.Pointer(addr), uintptr(npages)*pageSize) // Update global accounting only when not in test, otherwise // the runtime's accounting will be wrong. mSysStatInc(&memstats.heap_released, uintptr(npages)*pageSize) + return addr } // fillAligned returns x but with all zeroes in m-aligned diff --git a/libgo/go/runtime/mgcscavenge_test.go b/libgo/go/runtime/mgcscavenge_test.go index 58f9e3a80d3..7f619b1e7db 100644 --- a/libgo/go/runtime/mgcscavenge_test.go +++ b/libgo/go/runtime/mgcscavenge_test.go @@ -419,12 +419,12 @@ func TestPageAllocScavenge(t *testing.T) { } for name, v := range tests { v := v - runTest := func(t *testing.T, locked bool) { + runTest := func(t *testing.T, mayUnlock bool) { b := NewPageAlloc(v.beforeAlloc, v.beforeScav) defer FreePageAlloc(b) for iter, h := range v.expect { - if got := b.Scavenge(h.request, locked); got != h.expect { + if got := b.Scavenge(h.request, mayUnlock); got != h.expect { t.Fatalf("bad scavenge #%d: want %d, got %d", iter+1, h.expect, got) } } @@ -436,7 +436,7 @@ func TestPageAllocScavenge(t *testing.T) { t.Run(name, func(t *testing.T) { runTest(t, false) }) - t.Run(name+"Locked", func(t *testing.T) { + t.Run(name+"MayUnlock", func(t *testing.T) { runTest(t, true) }) } diff --git a/libgo/go/runtime/mgcsweep.go b/libgo/go/runtime/mgcsweep.go index 1e959a4ad2d..6877649edbb 100644 --- a/libgo/go/runtime/mgcsweep.go +++ b/libgo/go/runtime/mgcsweep.go @@ -10,7 +10,7 @@ // can free a whole span if none of the objects are marked, but that // isn't its goal. This can be driven either synchronously by // mcentral.cacheSpan for mcentral spans, or asynchronously by -// sweepone from the list of all in-use spans in mheap_.sweepSpans. +// sweepone, which looks at all the mcentral lists. // // * The span reclaimer looks for spans that contain no marked objects // and frees whole spans. This is a separate algorithm because @@ -40,6 +40,80 @@ type sweepdata struct { nbgsweep uint32 npausesweep uint32 + + // centralIndex is the current unswept span class. + // It represents an index into the mcentral span + // sets. Accessed and updated via its load and + // update methods. Not protected by a lock. + // + // Reset at mark termination. + // Used by mheap.nextSpanForSweep. + centralIndex sweepClass +} + +// sweepClass is a spanClass and one bit to represent whether we're currently +// sweeping partial or full spans. +type sweepClass uint32 + +const ( + numSweepClasses = numSpanClasses * 2 + sweepClassDone sweepClass = sweepClass(^uint32(0)) +) + +func (s *sweepClass) load() sweepClass { + return sweepClass(atomic.Load((*uint32)(s))) +} + +func (s *sweepClass) update(sNew sweepClass) { + // Only update *s if its current value is less than sNew, + // since *s increases monotonically. + sOld := s.load() + for sOld < sNew && !atomic.Cas((*uint32)(s), uint32(sOld), uint32(sNew)) { + sOld = s.load() + } + // TODO(mknyszek): This isn't the only place we have + // an atomic monotonically increasing counter. It would + // be nice to have an "atomic max" which is just implemented + // as the above on most architectures. Some architectures + // like RISC-V however have native support for an atomic max. +} + +func (s *sweepClass) clear() { + atomic.Store((*uint32)(s), 0) +} + +// split returns the underlying span class as well as +// whether we're interested in the full or partial +// unswept lists for that class, indicated as a boolean +// (true means "full"). +func (s sweepClass) split() (spc spanClass, full bool) { + return spanClass(s >> 1), s&1 == 0 +} + +// nextSpanForSweep finds and pops the next span for sweeping from the +// central sweep buffers. It returns ownership of the span to the caller. +// Returns nil if no such span exists. +func (h *mheap) nextSpanForSweep() *mspan { + sg := h.sweepgen + for sc := sweep.centralIndex.load(); sc < numSweepClasses; sc++ { + spc, full := sc.split() + c := &h.central[spc].mcentral + var s *mspan + if full { + s = c.fullUnswept(sg).pop() + } else { + s = c.partialUnswept(sg).pop() + } + if s != nil { + // Write down that we found something so future sweepers + // can start from here. + sweep.centralIndex.update(sc) + return s + } + } + // Write down that we found nothing. + sweep.centralIndex.update(sweepClassDone) + return nil } // finishsweep_m ensures that all spans are swept. @@ -58,6 +132,24 @@ func finishsweep_m() { sweep.npausesweep++ } + if go115NewMCentralImpl { + // Reset all the unswept buffers, which should be empty. + // Do this in sweep termination as opposed to mark termination + // so that we can catch unswept spans and reclaim blocks as + // soon as possible. + sg := mheap_.sweepgen + for i := range mheap_.central { + c := &mheap_.central[i].mcentral + c.partialUnswept(sg).reset() + c.fullUnswept(sg).reset() + } + } + + // Sweeping is done, so if the scavenger isn't already awake, + // wake it up. There's definitely work for it to do at this + // point. + wakeScavenger() + nextMarkBitArenaEpoch() } @@ -66,6 +158,7 @@ func bgsweep(c chan int) { sweep.g = getg() + lockInit(&sweep.lock, lockRankSweep) lock(&sweep.lock) sweep.parked = true c <- 1 @@ -111,7 +204,11 @@ func sweepone() uintptr { var s *mspan sg := mheap_.sweepgen for { - s = mheap_.sweepSpans[1-sg/2%2].pop() + if go115NewMCentralImpl { + s = mheap_.nextSpanForSweep() + } else { + s = mheap_.sweepSpans[1-sg/2%2].pop() + } if s == nil { atomic.Store(&mheap_.sweepdone, 1) break @@ -151,6 +248,27 @@ func sweepone() uintptr { // Decrement the number of active sweepers and if this is the // last one print trace information. if atomic.Xadd(&mheap_.sweepers, -1) == 0 && atomic.Load(&mheap_.sweepdone) != 0 { + // Since the sweeper is done, move the scavenge gen forward (signalling + // that there's new work to do) and wake the scavenger. + // + // The scavenger is signaled by the last sweeper because once + // sweeping is done, we will definitely have useful work for + // the scavenger to do, since the scavenger only runs over the + // heap once per GC cyle. This update is not done during sweep + // termination because in some cases there may be a long delay + // between sweep done and sweep termination (e.g. not enough + // allocations to trigger a GC) which would be nice to fill in + // with scavenging work. + systemstack(func() { + lock(&mheap_.lock) + mheap_.pages.scavengeStartGen() + unlock(&mheap_.lock) + }) + // Since we might sweep in an allocation path, it's not possible + // for us to wake the scavenger directly via wakeScavenger, since + // it could allocate. Ask sysmon to do it for us instead. + readyForScavenger() + if debug.gcpacertrace > 0 { print("pacer: sweep done at heap size ", memstats.heap_live>>20, "MB; allocated ", (memstats.heap_live-mheap_.sweepHeapLiveBasis)>>20, "MB during sweep; swept ", mheap_.pagesSwept, " pages at ", sweepRatio, " pages/byte\n") } @@ -206,6 +324,260 @@ func (s *mspan) ensureSwept() { // If preserve=true, don't return it to heap nor relink in mcentral lists; // caller takes care of it. func (s *mspan) sweep(preserve bool) bool { + if !go115NewMCentralImpl { + return s.oldSweep(preserve) + } + // It's critical that we enter this function with preemption disabled, + // GC must not start while we are in the middle of this function. + _g_ := getg() + if _g_.m.locks == 0 && _g_.m.mallocing == 0 && _g_ != _g_.m.g0 { + throw("mspan.sweep: m is not locked") + } + sweepgen := mheap_.sweepgen + if state := s.state.get(); state != mSpanInUse || s.sweepgen != sweepgen-1 { + print("mspan.sweep: state=", state, " sweepgen=", s.sweepgen, " mheap.sweepgen=", sweepgen, "\n") + throw("mspan.sweep: bad span state") + } + + if trace.enabled { + traceGCSweepSpan(s.npages * _PageSize) + } + + atomic.Xadd64(&mheap_.pagesSwept, int64(s.npages)) + + spc := s.spanclass + size := s.elemsize + + c := _g_.m.p.ptr().mcache + + // The allocBits indicate which unmarked objects don't need to be + // processed since they were free at the end of the last GC cycle + // and were not allocated since then. + // If the allocBits index is >= s.freeindex and the bit + // is not marked then the object remains unallocated + // since the last GC. + // This situation is analogous to being on a freelist. + + // Unlink & free special records for any objects we're about to free. + // Two complications here: + // 1. An object can have both finalizer and profile special records. + // In such case we need to queue finalizer for execution, + // mark the object as live and preserve the profile special. + // 2. A tiny object can have several finalizers setup for different offsets. + // If such object is not marked, we need to queue all finalizers at once. + // Both 1 and 2 are possible at the same time. + hadSpecials := s.specials != nil + specialp := &s.specials + special := *specialp + for special != nil { + // A finalizer can be set for an inner byte of an object, find object beginning. + objIndex := uintptr(special.offset) / size + p := s.base() + objIndex*size + mbits := s.markBitsForIndex(objIndex) + if !mbits.isMarked() { + // This object is not marked and has at least one special record. + // Pass 1: see if it has at least one finalizer. + hasFin := false + endOffset := p - s.base() + size + for tmp := special; tmp != nil && uintptr(tmp.offset) < endOffset; tmp = tmp.next { + if tmp.kind == _KindSpecialFinalizer { + // Stop freeing of object if it has a finalizer. + mbits.setMarkedNonAtomic() + hasFin = true + break + } + } + // Pass 2: queue all finalizers _or_ handle profile record. + for special != nil && uintptr(special.offset) < endOffset { + // Find the exact byte for which the special was setup + // (as opposed to object beginning). + p := s.base() + uintptr(special.offset) + if special.kind == _KindSpecialFinalizer || !hasFin { + // Splice out special record. + y := special + special = special.next + *specialp = special + freespecial(y, unsafe.Pointer(p), size) + } else { + // This is profile record, but the object has finalizers (so kept alive). + // Keep special record. + specialp = &special.next + special = *specialp + } + } + } else { + // object is still live: keep special record + specialp = &special.next + special = *specialp + } + } + if hadSpecials && s.specials == nil { + spanHasNoSpecials(s) + } + + if debug.allocfreetrace != 0 || debug.clobberfree != 0 || raceenabled || msanenabled { + // Find all newly freed objects. This doesn't have to + // efficient; allocfreetrace has massive overhead. + mbits := s.markBitsForBase() + abits := s.allocBitsForIndex(0) + for i := uintptr(0); i < s.nelems; i++ { + if !mbits.isMarked() && (abits.index < s.freeindex || abits.isMarked()) { + x := s.base() + i*s.elemsize + if debug.allocfreetrace != 0 { + tracefree(unsafe.Pointer(x), size) + } + if debug.clobberfree != 0 { + clobberfree(unsafe.Pointer(x), size) + } + if raceenabled { + racefree(unsafe.Pointer(x), size) + } + if msanenabled { + msanfree(unsafe.Pointer(x), size) + } + } + mbits.advance() + abits.advance() + } + } + + // Check for zombie objects. + if s.freeindex < s.nelems { + // Everything < freeindex is allocated and hence + // cannot be zombies. + // + // Check the first bitmap byte, where we have to be + // careful with freeindex. + obj := s.freeindex + if (*s.gcmarkBits.bytep(obj / 8)&^*s.allocBits.bytep(obj / 8))>>(obj%8) != 0 { + s.reportZombies() + } + // Check remaining bytes. + for i := obj/8 + 1; i < divRoundUp(s.nelems, 8); i++ { + if *s.gcmarkBits.bytep(i)&^*s.allocBits.bytep(i) != 0 { + s.reportZombies() + } + } + } + + // Count the number of free objects in this span. + nalloc := uint16(s.countAlloc()) + nfreed := s.allocCount - nalloc + if nalloc > s.allocCount { + // The zombie check above should have caught this in + // more detail. + print("runtime: nelems=", s.nelems, " nalloc=", nalloc, " previous allocCount=", s.allocCount, " nfreed=", nfreed, "\n") + throw("sweep increased allocation count") + } + + s.allocCount = nalloc + s.freeindex = 0 // reset allocation index to start of span. + if trace.enabled { + getg().m.p.ptr().traceReclaimed += uintptr(nfreed) * s.elemsize + } + + // gcmarkBits becomes the allocBits. + // get a fresh cleared gcmarkBits in preparation for next GC + s.allocBits = s.gcmarkBits + s.gcmarkBits = newMarkBits(s.nelems) + + // Initialize alloc bits cache. + s.refillAllocCache(0) + + // The span must be in our exclusive ownership until we update sweepgen, + // check for potential races. + if state := s.state.get(); state != mSpanInUse || s.sweepgen != sweepgen-1 { + print("mspan.sweep: state=", state, " sweepgen=", s.sweepgen, " mheap.sweepgen=", sweepgen, "\n") + throw("mspan.sweep: bad span state after sweep") + } + if s.sweepgen == sweepgen+1 || s.sweepgen == sweepgen+3 { + throw("swept cached span") + } + + // We need to set s.sweepgen = h.sweepgen only when all blocks are swept, + // because of the potential for a concurrent free/SetFinalizer. + // + // But we need to set it before we make the span available for allocation + // (return it to heap or mcentral), because allocation code assumes that a + // span is already swept if available for allocation. + // + // Serialization point. + // At this point the mark bits are cleared and allocation ready + // to go so release the span. + atomic.Store(&s.sweepgen, sweepgen) + + if spc.sizeclass() != 0 { + // Handle spans for small objects. + if nfreed > 0 { + // Only mark the span as needing zeroing if we've freed any + // objects, because a fresh span that had been allocated into, + // wasn't totally filled, but then swept, still has all of its + // free slots zeroed. + s.needzero = 1 + c.local_nsmallfree[spc.sizeclass()] += uintptr(nfreed) + } + if !preserve { + // The caller may not have removed this span from whatever + // unswept set its on but taken ownership of the span for + // sweeping by updating sweepgen. If this span still is in + // an unswept set, then the mcentral will pop it off the + // set, check its sweepgen, and ignore it. + if nalloc == 0 { + // Free totally free span directly back to the heap. + mheap_.freeSpan(s) + return true + } + // Return span back to the right mcentral list. + if uintptr(nalloc) == s.nelems { + mheap_.central[spc].mcentral.fullSwept(sweepgen).push(s) + } else { + mheap_.central[spc].mcentral.partialSwept(sweepgen).push(s) + } + } + } else if !preserve { + // Handle spans for large objects. + if nfreed != 0 { + // Free large object span to heap. + + // NOTE(rsc,dvyukov): The original implementation of efence + // in CL 22060046 used sysFree instead of sysFault, so that + // the operating system would eventually give the memory + // back to us again, so that an efence program could run + // longer without running out of memory. Unfortunately, + // calling sysFree here without any kind of adjustment of the + // heap data structures means that when the memory does + // come back to us, we have the wrong metadata for it, either in + // the mspan structures or in the garbage collection bitmap. + // Using sysFault here means that the program will run out of + // memory fairly quickly in efence mode, but at least it won't + // have mysterious crashes due to confused memory reuse. + // It should be possible to switch back to sysFree if we also + // implement and then call some kind of mheap.deleteSpan. + if debug.efence > 0 { + s.limit = 0 // prevent mlookup from finding this span + sysFault(unsafe.Pointer(s.base()), size) + } else { + mheap_.freeSpan(s) + } + c.local_nlargefree++ + c.local_largefree += size + return true + } + + // Add a large span directly onto the full+swept list. + mheap_.central[spc].mcentral.fullSwept(sweepgen).push(s) + } + return false +} + +// Sweep frees or collects finalizers for blocks not marked in the mark phase. +// It clears the mark bits in preparation for the next GC round. +// Returns true if the span was returned to heap. +// If preserve=true, don't return it to heap nor relink in mcentral lists; +// caller takes care of it. +// +// For !go115NewMCentralImpl. +func (s *mspan) oldSweep(preserve bool) bool { // It's critical that we enter this function with preemption disabled, // GC must not start while we are in the middle of this function. _g_ := getg() @@ -228,7 +600,7 @@ func (s *mspan) sweep(preserve bool) bool { size := s.elemsize res := false - c := _g_.m.mcache + c := _g_.m.p.ptr().mcache freeToHeap := false // The allocBits indicate which unmarked objects don't need to be @@ -247,6 +619,7 @@ func (s *mspan) sweep(preserve bool) bool { // 2. A tiny object can have several finalizers setup for different offsets. // If such object is not marked, we need to queue all finalizers at once. // Both 1 and 2 are possible at the same time. + hadSpecials := s.specials != nil specialp := &s.specials special := *specialp for special != nil { @@ -291,6 +664,9 @@ func (s *mspan) sweep(preserve bool) bool { special = *specialp } } + if go115NewMarkrootSpans && hadSpecials && s.specials == nil { + spanHasNoSpecials(s) + } if debug.allocfreetrace != 0 || debug.clobberfree != 0 || raceenabled || msanenabled { // Find all newly freed objects. This doesn't have to @@ -402,6 +778,57 @@ func (s *mspan) sweep(preserve bool) bool { return res } +// reportZombies reports any marked but free objects in s and throws. +// +// This generally means one of the following: +// +// 1. User code converted a pointer to a uintptr and then back +// unsafely, and a GC ran while the uintptr was the only reference to +// an object. +// +// 2. User code (or a compiler bug) constructed a bad pointer that +// points to a free slot, often a past-the-end pointer. +// +// 3. The GC two cycles ago missed a pointer and freed a live object, +// but it was still live in the last cycle, so this GC cycle found a +// pointer to that object and marked it. +func (s *mspan) reportZombies() { + printlock() + print("runtime: marked free object in span ", s, ", elemsize=", s.elemsize, " freeindex=", s.freeindex, " (bad use of unsafe.Pointer? try -d=checkptr)\n") + mbits := s.markBitsForBase() + abits := s.allocBitsForIndex(0) + for i := uintptr(0); i < s.nelems; i++ { + addr := s.base() + i*s.elemsize + print(hex(addr)) + alloc := i < s.freeindex || abits.isMarked() + if alloc { + print(" alloc") + } else { + print(" free ") + } + if mbits.isMarked() { + print(" marked ") + } else { + print(" unmarked") + } + zombie := mbits.isMarked() && !alloc + if zombie { + print(" zombie") + } + print("\n") + if zombie { + length := s.elemsize + if length > 1024 { + length = 1024 + } + hexdumpWords(addr, addr+length, nil) + } + mbits.advance() + abits.advance() + } + throw("found pointer to free object") +} + // deductSweepCredit deducts sweep credit for allocating a span of // size spanBytes. This must be performed *before* the span is // allocated to ensure the system has enough credit. If necessary, it diff --git a/libgo/go/runtime/mgcsweepbuf.go b/libgo/go/runtime/mgcsweepbuf.go index 78288229c83..1f722c3d585 100644 --- a/libgo/go/runtime/mgcsweepbuf.go +++ b/libgo/go/runtime/mgcsweepbuf.go @@ -144,7 +144,7 @@ func (b *gcSweepBuf) pop() *mspan { // intervening pops. Spans that are pushed after the call may also // appear in these blocks. func (b *gcSweepBuf) numBlocks() int { - return int((atomic.Load(&b.index) + gcSweepBlockEntries - 1) / gcSweepBlockEntries) + return int(divRoundUp(uintptr(atomic.Load(&b.index)), gcSweepBlockEntries)) } // block returns the spans in the i'th block of buffer b. block is diff --git a/libgo/go/runtime/mgcwork.go b/libgo/go/runtime/mgcwork.go index a1b61add9b5..d23d64060ec 100644 --- a/libgo/go/runtime/mgcwork.go +++ b/libgo/go/runtime/mgcwork.go @@ -177,6 +177,10 @@ func (w *gcWork) put(obj uintptr) { flushed := false wbuf := w.wbuf1 + // Record that this may acquire the wbufSpans or heap lock to + // allocate a workbuf. + lockWithRankMayAcquire(&work.wbufSpans.lock, lockRankWbufSpans) + lockWithRankMayAcquire(&mheap_.lock, lockRankMheap) if wbuf == nil { w.init() wbuf = w.wbuf1 @@ -422,6 +426,10 @@ func getempty() *workbuf { b.checkempty() } } + // Record that this may acquire the wbufSpans or heap lock to + // allocate a workbuf. + lockWithRankMayAcquire(&work.wbufSpans.lock, lockRankWbufSpans) + lockWithRankMayAcquire(&mheap_.lock, lockRankMheap) if b == nil { // Allocate more workbufs. var s *mspan diff --git a/libgo/go/runtime/mheap.go b/libgo/go/runtime/mheap.go index c40c9e26628..e73ee32efd4 100644 --- a/libgo/go/runtime/mheap.go +++ b/libgo/go/runtime/mheap.go @@ -27,6 +27,32 @@ const ( // maxPhysHugePageSize sets an upper-bound on the maximum huge page size // that the runtime supports. maxPhysHugePageSize = pallocChunkBytes + + // pagesPerReclaimerChunk indicates how many pages to scan from the + // pageInUse bitmap at a time. Used by the page reclaimer. + // + // Higher values reduce contention on scanning indexes (such as + // h.reclaimIndex), but increase the minimum latency of the + // operation. + // + // The time required to scan this many pages can vary a lot depending + // on how many spans are actually freed. Experimentally, it can + // scan for pages at ~300 GB/ms on a 2.6GHz Core i7, but can only + // free spans at ~32 MB/ms. Using 512 pages bounds this at + // roughly 100µs. + // + // Must be a multiple of the pageInUse bitmap element size and + // must also evenly divid pagesPerArena. + pagesPerReclaimerChunk = 512 + + // go115NewMCentralImpl is a feature flag for the new mcentral implementation. + // + // This flag depends on go115NewMarkrootSpans because the new mcentral + // implementation requires that markroot spans no longer rely on mgcsweepbufs. + // The definition of this flag helps ensure that if there's a problem with + // the new markroot spans implementation and it gets turned off, that the new + // mcentral implementation also gets turned off so the runtime isn't broken. + go115NewMCentralImpl = true && go115NewMarkrootSpans ) // Main malloc heap. @@ -68,9 +94,11 @@ type mheap struct { // unswept stack and pushes spans that are still in-use on the // swept stack. Likewise, allocating an in-use span pushes it // on the swept stack. + // + // For !go115NewMCentralImpl. sweepSpans [2]gcSweepBuf - // _ uint32 // align uint64 fields on 32-bit for atomics + _ uint32 // align uint64 fields on 32-bit for atomics // Proportional sweep // @@ -180,13 +208,19 @@ type mheap struct { // simply blocking GC (by disabling preemption). sweepArenas []arenaIdx + // markArenas is a snapshot of allArenas taken at the beginning + // of the mark cycle. Because allArenas is append-only, neither + // this slice nor its contents will change during the mark, so + // it can be read safely. + markArenas []arenaIdx + // curArena is the arena that the heap is currently growing // into. This should always be physPageSize-aligned. curArena struct { base, end uintptr } - _ uint32 // ensure 64-bit alignment of central + // _ uint32 // ensure 64-bit alignment of central // central free lists for small size classes. // the padding makes sure that the mcentrals are @@ -256,6 +290,16 @@ type heapArena struct { // operations. pageMarks [pagesPerArena / 8]uint8 + // pageSpecials is a bitmap that indicates which spans have + // specials (finalizers or other). Like pageInUse, only the bit + // corresponding to the first page in each span is used. + // + // Writes are done atomically whenever a special is added to + // a span and whenever the last special is removed from a span. + // Reads are done atomically to find spans containing specials + // during marking. + pageSpecials [pagesPerArena / 8]uint8 + // zeroedBase marks the first byte of the first page in this // arena which hasn't been used yet and is therefore already // zero. zeroedBase is relative to the arena base. @@ -532,13 +576,13 @@ func (sc spanClass) noscan() bool { // //go:nosplit func arenaIndex(p uintptr) arenaIdx { - return arenaIdx((p + arenaBaseOffset) / heapArenaBytes) + return arenaIdx((p - arenaBaseOffset) / heapArenaBytes) } // arenaBase returns the low address of the region covered by heap // arena i. func arenaBase(i arenaIdx) uintptr { - return uintptr(i)*heapArenaBytes - arenaBaseOffset + return uintptr(i)*heapArenaBytes + arenaBaseOffset } type arenaIdx uint @@ -670,6 +714,11 @@ func pageIndexOf(p uintptr) (arena *heapArena, pageIdx uintptr, pageMask uint8) // Initialize the heap. func (h *mheap) init() { + lockInit(&h.lock, lockRankMheap) + lockInit(&h.sweepSpans[0].spineLock, lockRankSpine) + lockInit(&h.sweepSpans[1].spineLock, lockRankSpine) + lockInit(&h.speciallock, lockRankMheapSpecial) + h.spanalloc.init(unsafe.Sizeof(mspan{}), recordspan, unsafe.Pointer(h), &memstats.mspan_sys) h.cachealloc.init(unsafe.Sizeof(mcache{}), nil, nil, &memstats.mcache_sys) h.specialfinalizeralloc.init(unsafe.Sizeof(specialfinalizer{}), nil, nil, &memstats.other_sys) @@ -701,23 +750,10 @@ func (h *mheap) init() { // // h must NOT be locked. func (h *mheap) reclaim(npage uintptr) { - // This scans pagesPerChunk at a time. Higher values reduce - // contention on h.reclaimPos, but increase the minimum - // latency of performing a reclaim. - // - // Must be a multiple of the pageInUse bitmap element size. - // - // The time required by this can vary a lot depending on how - // many spans are actually freed. Experimentally, it can scan - // for pages at ~300 GB/ms on a 2.6GHz Core i7, but can only - // free spans at ~32 MB/ms. Using 512 pages bounds this at - // roughly 100µs. - // // TODO(austin): Half of the time spent freeing spans is in // locking/unlocking the heap (even with low contention). We // could make the slow path here several times faster by // batching heap frees. - const pagesPerChunk = 512 // Bail early if there's no more reclaim work. if atomic.Load64(&h.reclaimIndex) >= 1<<63 { @@ -750,7 +786,7 @@ func (h *mheap) reclaim(npage uintptr) { } // Claim a chunk of work. - idx := uintptr(atomic.Xadd64(&h.reclaimIndex, pagesPerChunk) - pagesPerChunk) + idx := uintptr(atomic.Xadd64(&h.reclaimIndex, pagesPerReclaimerChunk) - pagesPerReclaimerChunk) if idx/pagesPerArena >= uintptr(len(arenas)) { // Page reclaiming is done. atomic.Store64(&h.reclaimIndex, 1<<63) @@ -764,7 +800,7 @@ func (h *mheap) reclaim(npage uintptr) { } // Scan this chunk. - nfound := h.reclaimChunk(arenas, idx, pagesPerChunk) + nfound := h.reclaimChunk(arenas, idx, pagesPerReclaimerChunk) if nfound <= npage { npage -= nfound } else { @@ -1141,10 +1177,21 @@ func (h *mheap) allocSpan(npages uintptr, manual bool, spanclass spanClass, sysS // which may only be done with the heap locked. // Transfer stats from mcache to global. - memstats.heap_scan += uint64(gp.m.mcache.local_scan) - gp.m.mcache.local_scan = 0 - memstats.tinyallocs += uint64(gp.m.mcache.local_tinyallocs) - gp.m.mcache.local_tinyallocs = 0 + var c *mcache + if gp.m.p != 0 { + c = gp.m.p.ptr().mcache + } else { + // This case occurs while bootstrapping. + // See the similar code in mallocgc. + c = mcache0 + if c == nil { + throw("mheap.allocSpan called with no P") + } + } + memstats.heap_scan += uint64(c.local_scan) + c.local_scan = 0 + memstats.tinyallocs += uint64(c.local_tinyallocs) + c.local_tinyallocs = 0 // Do some additional accounting if it's a large allocation. if spanclass.sizeclass() == 0 { @@ -1236,19 +1283,22 @@ HaveSpan: // Publish the span in various locations. // This is safe to call without the lock held because the slots - // related to this span will only every be read or modified by - // this thread until pointers into the span are published or - // pageInUse is updated. + // related to this span will only ever be read or modified by + // this thread until pointers into the span are published (and + // we execute a publication barrier at the end of this function + // before that happens) or pageInUse is updated. h.setSpans(s.base(), npages, s) if !manual { - // Add to swept in-use list. - // - // This publishes the span to root marking. - // - // h.sweepgen is guaranteed to only change during STW, - // and preemption is disabled in the page allocator. - h.sweepSpans[h.sweepgen/2%2].push(s) + if !go115NewMCentralImpl { + // Add to swept in-use list. + // + // This publishes the span to root marking. + // + // h.sweepgen is guaranteed to only change during STW, + // and preemption is disabled in the page allocator. + h.sweepSpans[h.sweepgen/2%2].push(s) + } // Mark in-use span in arena page bitmap. // @@ -1266,6 +1316,11 @@ HaveSpan: traceHeapAlloc() } } + + // Make sure the newly allocated span will be observed + // by the GC before pointers into the span are published. + publicationBarrier() + return s } @@ -1278,8 +1333,11 @@ func (h *mheap) grow(npage uintptr) bool { ask := alignUp(npage, pallocChunkPages) * pageSize totalGrowth := uintptr(0) - nBase := alignUp(h.curArena.base+ask, physPageSize) - if nBase > h.curArena.end { + // This may overflow because ask could be very large + // and is otherwise unrelated to h.curArena.base. + end := h.curArena.base + ask + nBase := alignUp(end, physPageSize) + if nBase > h.curArena.end || /* overflow */ end < h.curArena.base { // Not enough room in the current arena. Allocate more // arena space. This may not be contiguous with the // current arena, so we have to request the full ask. @@ -1315,7 +1373,10 @@ func (h *mheap) grow(npage uintptr) bool { mSysStatInc(&memstats.heap_released, asize) mSysStatInc(&memstats.heap_idle, asize) - // Recalculate nBase + // Recalculate nBase. + // We know this won't overflow, because sysAlloc returned + // a valid region starting at h.curArena.base which is at + // least ask bytes in size. nBase = alignUp(h.curArena.base+ask, physPageSize) } @@ -1334,7 +1395,7 @@ func (h *mheap) grow(npage uintptr) bool { if overage := uintptr(retained + uint64(totalGrowth) - h.scavengeGoal); todo > overage { todo = overage } - h.pages.scavenge(todo, true) + h.pages.scavenge(todo, false) } return true } @@ -1342,12 +1403,12 @@ func (h *mheap) grow(npage uintptr) bool { // Free the span back into the heap. func (h *mheap) freeSpan(s *mspan) { systemstack(func() { - mp := getg().m + c := getg().m.p.ptr().mcache lock(&h.lock) - memstats.heap_scan += uint64(mp.mcache.local_scan) - mp.mcache.local_scan = 0 - memstats.tinyallocs += uint64(mp.mcache.local_tinyallocs) - mp.mcache.local_tinyallocs = 0 + memstats.heap_scan += uint64(c.local_scan) + c.local_scan = 0 + memstats.tinyallocs += uint64(c.local_tinyallocs) + c.local_tinyallocs = 0 if msanenabled { // Tell msan that this entire span is no longer in use. base := unsafe.Pointer(s.base()) @@ -1418,9 +1479,9 @@ func (h *mheap) freeSpanLocked(s *mspan, acctinuse, acctidle bool) { h.freeMSpanLocked(s) } -// scavengeAll visits each node in the free treap and scavenges the -// treapNode's span. It then removes the scavenged span from -// unscav and adds it into scav before continuing. +// scavengeAll acquires the heap lock (blocking any additional +// manipulation of the page allocator) and iterates over the whole +// heap, scavenging every free page available. func (h *mheap) scavengeAll() { // Disallow malloc or panic while holding the heap lock. We do // this here because this is a non-mallocgc entry-point to @@ -1428,14 +1489,16 @@ func (h *mheap) scavengeAll() { gp := getg() gp.m.mallocing++ lock(&h.lock) - // Reset the scavenger address so we have access to the whole heap. - h.pages.resetScavengeAddr() - released := h.pages.scavenge(^uintptr(0), true) + // Start a new scavenge generation so we have a chance to walk + // over the whole heap. + h.pages.scavengeStartGen() + released := h.pages.scavenge(^uintptr(0), false) + gen := h.pages.scav.gen unlock(&h.lock) gp.m.mallocing-- if debug.scavtrace > 0 { - printScavTrace(released, true) + printScavTrace(gen, released, true) } } @@ -1463,6 +1526,7 @@ func (span *mspan) init(base uintptr, npages uintptr) { span.allocBits = nil span.gcmarkBits = nil span.state.set(mSpanDead) + lockInit(&span.speciallock, lockRankMspanSpecial) } func (span *mspan) inList() bool { @@ -1576,6 +1640,22 @@ type special struct { kind byte // kind of special } +// spanHasSpecials marks a span as having specials in the arena bitmap. +func spanHasSpecials(s *mspan) { + arenaPage := (s.base() / pageSize) % pagesPerArena + ai := arenaIndex(s.base()) + ha := mheap_.arenas[ai.l1()][ai.l2()] + atomic.Or8(&ha.pageSpecials[arenaPage/8], uint8(1)<<(arenaPage%8)) +} + +// spanHasNoSpecials marks a span as having no specials in the arena bitmap. +func spanHasNoSpecials(s *mspan) { + arenaPage := (s.base() / pageSize) % pagesPerArena + ai := arenaIndex(s.base()) + ha := mheap_.arenas[ai.l1()][ai.l2()] + atomic.And8(&ha.pageSpecials[arenaPage/8], ^(uint8(1) << (arenaPage % 8))) +} + // Adds the special record s to the list of special records for // the object p. All fields of s should be filled in except for // offset & next, which this routine will fill in. @@ -1621,6 +1701,9 @@ func addspecial(p unsafe.Pointer, s *special) bool { s.offset = uint16(offset) s.next = *t *t = s + if go115NewMarkrootSpans { + spanHasSpecials(span) + } unlock(&span.speciallock) releasem(mp) @@ -1644,6 +1727,7 @@ func removespecial(p unsafe.Pointer, kind uint8) *special { offset := uintptr(p) - span.base() + var result *special lock(&span.speciallock) t := &span.specials for { @@ -1655,15 +1739,17 @@ func removespecial(p unsafe.Pointer, kind uint8) *special { // "interior" specials (p must be exactly equal to s->offset). if offset == uintptr(s.offset) && kind == s.kind { *t = s.next - unlock(&span.speciallock) - releasem(mp) - return s + result = s + break } t = &s.next } + if go115NewMarkrootSpans && span.specials == nil { + spanHasNoSpecials(span) + } unlock(&span.speciallock) releasem(mp) - return nil + return result } // The described object has a finalizer set for it. diff --git a/libgo/go/runtime/mkpreempt.go b/libgo/go/runtime/mkpreempt.go index 35ed42871f1..1fe77663b9c 100644 --- a/libgo/go/runtime/mkpreempt.go +++ b/libgo/go/runtime/mkpreempt.go @@ -502,8 +502,33 @@ func genPPC64() { } func genRISCV64() { - p("// No async preemption on riscv64 - see issue 36711") - p("UNDEF") + // X0 (zero), X1 (LR), X2 (SP), X4 (g), X31 (TMP) are special. + var l = layout{sp: "X2", stack: 8} + + // Add integer registers (X3, X5-X30). + for i := 3; i < 31; i++ { + if i == 4 { + continue + } + reg := fmt.Sprintf("X%d", i) + l.add("MOV", reg, 8) + } + + // Add floating point registers (F0-F31). + for i := 0; i <= 31; i++ { + reg := fmt.Sprintf("F%d", i) + l.add("MOVD", reg, 8) + } + + p("MOV X1, -%d(X2)", l.stack) + p("ADD $-%d, X2", l.stack) + l.save() + p("CALL ·asyncPreempt2(SB)") + l.restore() + p("MOV %d(X2), X1", l.stack) + p("MOV (X2), X31") + p("ADD $%d, X2", l.stack+8) + p("JMP (X31)") } func genS390X() { diff --git a/libgo/go/runtime/mpagealloc.go b/libgo/go/runtime/mpagealloc.go index bb751f1f8ed..60f7f9ff58e 100644 --- a/libgo/go/runtime/mpagealloc.go +++ b/libgo/go/runtime/mpagealloc.go @@ -81,20 +81,14 @@ const ( // there should this change. pallocChunksL2Bits = heapAddrBits - logPallocChunkBytes - pallocChunksL1Bits pallocChunksL1Shift = pallocChunksL2Bits - - // Maximum searchAddr value, which indicates that the heap has no free space. - // - // We subtract arenaBaseOffset because we want this to represent the maximum - // value in the shifted address space, but searchAddr is stored as a regular - // memory address. See arenaBaseOffset for details. - maxSearchAddr = ^uintptr(0) - arenaBaseOffset - - // Minimum scavAddr value, which indicates that the scavenger is done. - // - // minScavAddr + arenaBaseOffset == 0 - minScavAddr = (^arenaBaseOffset + 1) & uintptrMask ) +// Maximum searchAddr value, which indicates that the heap has no free space. +// +// We alias maxOffAddr just to make it clear that this is the maximum address +// for the page allocator's search space. See maxOffAddr for details. +var maxSearchAddr = maxOffAddr + // Global chunk index. // // Represents an index into the leaf level of the radix tree. @@ -105,12 +99,12 @@ type chunkIdx uint // chunkIndex returns the global index of the palloc chunk containing the // pointer p. func chunkIndex(p uintptr) chunkIdx { - return chunkIdx((p + arenaBaseOffset) / pallocChunkBytes) + return chunkIdx((p - arenaBaseOffset) / pallocChunkBytes) } // chunkIndex returns the base address of the palloc chunk at index ci. func chunkBase(ci chunkIdx) uintptr { - return uintptr(ci)*pallocChunkBytes - arenaBaseOffset + return uintptr(ci)*pallocChunkBytes + arenaBaseOffset } // chunkPageIndex computes the index of the page that contains p, @@ -139,6 +133,18 @@ func (i chunkIdx) l2() uint { } } +// offAddrToLevelIndex converts an address in the offset address space +// to the index into summary[level] containing addr. +func offAddrToLevelIndex(level int, addr offAddr) int { + return int((addr.a - arenaBaseOffset) >> levelShift[level]) +} + +// levelIndexToOffAddr converts an index into summary[level] into +// the corresponding address in the offset address space. +func levelIndexToOffAddr(level, idx int) offAddr { + return offAddr{(uintptr(idx) << levelShift[level]) + arenaBaseOffset} +} + // addrsToSummaryRange converts base and limit pointers into a range // of entries for the given summary level. // @@ -153,8 +159,8 @@ func addrsToSummaryRange(level int, base, limit uintptr) (lo int, hi int) { // of a summary's max page count boundary for this level // (1 << levelLogPages[level]). So, make limit an inclusive upper bound // then shift, then add 1, so we get an exclusive upper bound at the end. - lo = int((base + arenaBaseOffset) >> levelShift[level]) - hi = int(((limit-1)+arenaBaseOffset)>>levelShift[level]) + 1 + lo = int((base - arenaBaseOffset) >> levelShift[level]) + hi = int(((limit-1)-arenaBaseOffset)>>levelShift[level]) + 1 return } @@ -237,16 +243,7 @@ type pageAlloc struct { // Note that adding in arenaBaseOffset transforms addresses // to a new address space with a linear view of the full address // space on architectures with segmented address spaces. - searchAddr uintptr - - // The address to start a scavenge candidate search with. It - // need not point to memory contained in inUse. - scavAddr uintptr - - // The amount of memory scavenged since the last scavtrace print. - // - // Read and updated atomically. - scavReleased uintptr + searchAddr offAddr // start and end represent the chunk indices // which pageAlloc knows about. It assumes @@ -267,6 +264,33 @@ type pageAlloc struct { // All access is protected by the mheapLock. inUse addrRanges + // scav stores the scavenger state. + // + // All fields are protected by mheapLock. + scav struct { + // inUse is a slice of ranges of address space which have not + // yet been looked at by the scavenger. + inUse addrRanges + + // gen is the scavenge generation number. + gen uint32 + + // reservationBytes is how large of a reservation should be made + // in bytes of address space for each scavenge iteration. + reservationBytes uintptr + + // released is the amount of memory released this generation. + released uintptr + + // scavLWM is the lowest (offset) address that the scavenger reached this + // scavenge generation. + scavLWM offAddr + + // freeHWM is the highest (offset) address of a page that was freed to + // the page allocator this scavenge generation. + freeHWM offAddr + } + // mheap_.lock. This level of indirection makes it possible // to test pageAlloc indepedently of the runtime allocator. mheapLock *mutex @@ -299,34 +323,11 @@ func (s *pageAlloc) init(mheapLock *mutex, sysStat *uint64) { // Start with the searchAddr in a state indicating there's no free memory. s.searchAddr = maxSearchAddr - // Start with the scavAddr in a state indicating there's nothing more to do. - s.scavAddr = minScavAddr - // Set the mheapLock. s.mheapLock = mheapLock -} -// compareSearchAddrTo compares an address against s.searchAddr in a linearized -// view of the address space on systems with discontinuous process address spaces. -// This linearized view is the same one generated by chunkIndex and arenaIndex, -// done by adding arenaBaseOffset. -// -// On systems without a discontinuous address space, it's just a normal comparison. -// -// Returns < 0 if addr is less than s.searchAddr in the linearized address space. -// Returns > 0 if addr is greater than s.searchAddr in the linearized address space. -// Returns 0 if addr and s.searchAddr are equal. -func (s *pageAlloc) compareSearchAddrTo(addr uintptr) int { - // Compare with arenaBaseOffset added because it gives us a linear, contiguous view - // of the heap on architectures with signed address spaces. - lAddr := addr + arenaBaseOffset - lSearchAddr := s.searchAddr + arenaBaseOffset - if lAddr < lSearchAddr { - return -1 - } else if lAddr > lSearchAddr { - return 1 - } - return 0 + // Initialize scavenge tracking state. + s.scav.scavLWM = maxSearchAddr } // chunkOf returns the chunk at the given chunk index. @@ -362,13 +363,13 @@ func (s *pageAlloc) grow(base, size uintptr) { // Note that [base, limit) will never overlap with any existing // range inUse because grow only ever adds never-used memory // regions to the page allocator. - s.inUse.add(addrRange{base, limit}) + s.inUse.add(makeAddrRange(base, limit)) // A grow operation is a lot like a free operation, so if our - // chunk ends up below the (linearized) s.searchAddr, update - // s.searchAddr to the new address, just like in free. - if s.compareSearchAddrTo(base) < 0 { - s.searchAddr = base + // chunk ends up below s.searchAddr, update s.searchAddr to the + // new address, just like in free. + if b := (offAddr{base}); b.lessThan(s.searchAddr) { + s.searchAddr = b } // Add entries into chunks, which is sparse, if needed. Then, @@ -532,7 +533,7 @@ func (s *pageAlloc) allocRange(base, npages uintptr) uintptr { // searchAddr returned is invalid and must be ignored. // // s.mheapLock must be held. -func (s *pageAlloc) find(npages uintptr) (uintptr, uintptr) { +func (s *pageAlloc) find(npages uintptr) (uintptr, offAddr) { // Search algorithm. // // This algorithm walks each level l of the radix tree from the root level @@ -572,13 +573,13 @@ func (s *pageAlloc) find(npages uintptr) (uintptr, uintptr) { // firstFree is updated by calling foundFree each time free space in the // heap is discovered. // - // At the end of the search, base-arenaBaseOffset is the best new + // At the end of the search, base.addr() is the best new // searchAddr we could deduce in this search. firstFree := struct { - base, bound uintptr + base, bound offAddr }{ - base: 0, - bound: (1< firstFree.bound) { + firstFree.bound = addr.add(size - 1) + } else if !(addr.add(size-1).lessThan(firstFree.base) || firstFree.bound.lessThan(addr)) { // This range only partially overlaps with the firstFree range, // so throw. - print("runtime: addr = ", hex(addr), ", size = ", size, "\n") - print("runtime: base = ", hex(firstFree.base), ", bound = ", hex(firstFree.bound), "\n") + print("runtime: addr = ", hex(addr.addr()), ", size = ", size, "\n") + print("runtime: base = ", hex(firstFree.base.addr()), ", bound = ", hex(firstFree.bound.addr()), "\n") throw("range partially overlaps") } } @@ -629,7 +630,7 @@ nextLevel: // searchAddr on the previous level or we're on the root leve, in which // case the searchAddr should be the same as i after levelShift. j0 := 0 - if searchIdx := int((s.searchAddr + arenaBaseOffset) >> levelShift[l]); searchIdx&^(entriesPerBlock-1) == i { + if searchIdx := offAddrToLevelIndex(l, s.searchAddr); searchIdx&^(entriesPerBlock-1) == i { j0 = searchIdx & (entriesPerBlock - 1) } @@ -655,7 +656,7 @@ nextLevel: // We've encountered a non-zero summary which means // free memory, so update firstFree. - foundFree(uintptr((i+j)<= uint(npages) { @@ -693,8 +694,8 @@ nextLevel: if size >= uint(npages) { // We found a sufficiently large run of free pages straddling // some boundary, so compute the address and return it. - addr := uintptr(i<= s.end { + if chunkIndex(s.searchAddr.addr()) >= s.end { return 0, 0 } // If npages has a chance of fitting in the chunk where the searchAddr is, // search it directly. - searchAddr := uintptr(0) - if pallocChunkPages-chunkPageIndex(s.searchAddr) >= uint(npages) { + searchAddr := minOffAddr + if pallocChunkPages-chunkPageIndex(s.searchAddr.addr()) >= uint(npages) { // npages is guaranteed to be no greater than pallocChunkPages here. - i := chunkIndex(s.searchAddr) + i := chunkIndex(s.searchAddr.addr()) if max := s.summary[len(s.summary)-1][i].max(); max >= uint(npages) { - j, searchIdx := s.chunkOf(i).find(npages, chunkPageIndex(s.searchAddr)) - if j < 0 { + j, searchIdx := s.chunkOf(i).find(npages, chunkPageIndex(s.searchAddr.addr())) + if j == ^uint(0) { print("runtime: max = ", max, ", npages = ", npages, "\n") - print("runtime: searchIdx = ", chunkPageIndex(s.searchAddr), ", s.searchAddr = ", hex(s.searchAddr), "\n") + print("runtime: searchIdx = ", chunkPageIndex(s.searchAddr.addr()), ", s.searchAddr = ", hex(s.searchAddr.addr()), "\n") throw("bad summary data") } addr = chunkBase(i) + uintptr(j)*pageSize - searchAddr = chunkBase(i) + uintptr(searchIdx)*pageSize + searchAddr = offAddr{chunkBase(i) + uintptr(searchIdx)*pageSize} goto Found } } @@ -794,10 +795,10 @@ Found: // Go ahead and actually mark the bits now that we have an address. scav = s.allocRange(addr, npages) - // If we found a higher (linearized) searchAddr, we know that all the - // heap memory before that searchAddr in a linear address space is + // If we found a higher searchAddr, we know that all the + // heap memory before that searchAddr in an offset address space is // allocated, so bump s.searchAddr up to the new one. - if s.compareSearchAddrTo(searchAddr) > 0 { + if s.searchAddr.lessThan(searchAddr) { s.searchAddr = searchAddr } return addr, scav @@ -807,9 +808,14 @@ Found: // // s.mheapLock must be held. func (s *pageAlloc) free(base, npages uintptr) { - // If we're freeing pages below the (linearized) s.searchAddr, update searchAddr. - if s.compareSearchAddrTo(base) < 0 { - s.searchAddr = base + // If we're freeing pages below the s.searchAddr, update searchAddr. + if b := (offAddr{base}); b.lessThan(s.searchAddr) { + s.searchAddr = b + } + // Update the free high watermark for the scavenger. + limit := base + npages*pageSize - 1 + if offLimit := (offAddr{limit}); s.scav.freeHWM.lessThan(offLimit) { + s.scav.freeHWM = offLimit } if npages == 1 { // Fast path: we're clearing a single bit, and we know exactly @@ -818,7 +824,6 @@ func (s *pageAlloc) free(base, npages uintptr) { s.chunkOf(i).free1(chunkPageIndex(base)) } else { // Slow path: we're clearing more bits so we may need to iterate. - limit := base + npages*pageSize - 1 sc, ec := chunkIndex(base), chunkIndex(limit) si, ei := chunkPageIndex(base), chunkPageIndex(limit) diff --git a/libgo/go/runtime/mpagealloc_64bit.go b/libgo/go/runtime/mpagealloc_64bit.go index 385b7b3e7a7..ac599463ce7 100644 --- a/libgo/go/runtime/mpagealloc_64bit.go +++ b/libgo/go/runtime/mpagealloc_64bit.go @@ -106,7 +106,7 @@ func (s *pageAlloc) sysGrow(base, limit uintptr) { // of summary indices which must be mapped to support those addresses // in the summary range. addrRangeToSummaryRange := func(level int, r addrRange) (int, int) { - sumIdxBase, sumIdxLimit := addrsToSummaryRange(level, r.base, r.limit) + sumIdxBase, sumIdxLimit := addrsToSummaryRange(level, r.base.addr(), r.limit.addr()) return blockAlignSummaryRange(level, sumIdxBase, sumIdxLimit) } @@ -118,8 +118,8 @@ func (s *pageAlloc) sysGrow(base, limit uintptr) { limitOffset := alignUp(uintptr(sumIdxLimit)*pallocSumBytes, physPageSize) base := unsafe.Pointer(&s.summary[level][0]) return addrRange{ - uintptr(add(base, baseOffset)), - uintptr(add(base, limitOffset)), + offAddr{uintptr(add(base, baseOffset))}, + offAddr{uintptr(add(base, limitOffset))}, } } @@ -145,7 +145,7 @@ func (s *pageAlloc) sysGrow(base, limit uintptr) { // Walk up the radix tree and map summaries in as needed. for l := range s.summary { // Figure out what part of the summary array this new address space needs. - needIdxBase, needIdxLimit := addrRangeToSummaryRange(l, addrRange{base, limit}) + needIdxBase, needIdxLimit := addrRangeToSummaryRange(l, makeAddrRange(base, limit)) // Update the summary slices with a new upper-bound. This ensures // we get tight bounds checks on at least the top bound. @@ -174,7 +174,7 @@ func (s *pageAlloc) sysGrow(base, limit uintptr) { } // Map and commit need. - sysMap(unsafe.Pointer(need.base), need.size(), s.sysStat) - sysUsed(unsafe.Pointer(need.base), need.size()) + sysMap(unsafe.Pointer(need.base.addr()), need.size(), s.sysStat) + sysUsed(unsafe.Pointer(need.base.addr()), need.size()) } } diff --git a/libgo/go/runtime/mpagecache.go b/libgo/go/runtime/mpagecache.go index a0749618405..683a9971368 100644 --- a/libgo/go/runtime/mpagecache.go +++ b/libgo/go/runtime/mpagecache.go @@ -91,8 +91,8 @@ func (c *pageCache) flush(s *pageAlloc) { } // Since this is a lot like a free, we need to make sure // we update the searchAddr just like free does. - if s.compareSearchAddrTo(c.base) < 0 { - s.searchAddr = c.base + if b := (offAddr{c.base}); b.lessThan(s.searchAddr) { + s.searchAddr = b } s.update(c.base, pageCachePages, false, false) *c = pageCache{} @@ -106,16 +106,16 @@ func (c *pageCache) flush(s *pageAlloc) { func (s *pageAlloc) allocToCache() pageCache { // If the searchAddr refers to a region which has a higher address than // any known chunk, then we know we're out of memory. - if chunkIndex(s.searchAddr) >= s.end { + if chunkIndex(s.searchAddr.addr()) >= s.end { return pageCache{} } c := pageCache{} - ci := chunkIndex(s.searchAddr) // chunk index + ci := chunkIndex(s.searchAddr.addr()) // chunk index if s.summary[len(s.summary)-1][ci] != 0 { // Fast path: there's free pages at or near the searchAddr address. chunk := s.chunkOf(ci) - j, _ := chunk.find(1, chunkPageIndex(s.searchAddr)) - if j < 0 { + j, _ := chunk.find(1, chunkPageIndex(s.searchAddr.addr())) + if j == ^uint(0) { throw("bad summary data") } c = pageCache{ @@ -156,6 +156,6 @@ func (s *pageAlloc) allocToCache() pageCache { // However, s.searchAddr is not allowed to point into unmapped heap memory // unless it is maxSearchAddr, so make it the last page as opposed to // the page after. - s.searchAddr = c.base + pageSize*(pageCachePages-1) + s.searchAddr = offAddr{c.base + pageSize*(pageCachePages-1)} return c } diff --git a/libgo/go/runtime/mprof.go b/libgo/go/runtime/mprof.go index dd257d1b06f..a4b135d90d0 100644 --- a/libgo/go/runtime/mprof.go +++ b/libgo/go/runtime/mprof.go @@ -942,13 +942,16 @@ func ThreadCreateProfile(p []StackRecord) (n int, ok bool) { return } -// GoroutineProfile returns n, the number of records in the active goroutine stack profile. -// If len(p) >= n, GoroutineProfile copies the profile into p and returns n, true. -// If len(p) < n, GoroutineProfile does not change p and returns n, false. -// -// Most clients should use the runtime/pprof package instead -// of calling GoroutineProfile directly. -func GoroutineProfile(p []StackRecord) (n int, ok bool) { +//go:linkname runtime_goroutineProfileWithLabels runtime..z2fpprof.runtime_goroutineProfileWithLabels +func runtime_goroutineProfileWithLabels(p []StackRecord, labels []unsafe.Pointer) (n int, ok bool) { + return goroutineProfileWithLabels(p, labels) +} + +// labels may be nil. If labels is non-nil, it must have the same length as p. +func goroutineProfileWithLabels(p []StackRecord, labels []unsafe.Pointer) (n int, ok bool) { + if labels != nil && len(labels) != len(p) { + labels = nil + } gp := getg() isOK := func(gp1 *g) bool { @@ -968,12 +971,18 @@ func GoroutineProfile(p []StackRecord) (n int, ok bool) { if n <= len(p) { ok = true - r := p + r, lbl := p, labels // Save current goroutine. saveg(gp, &r[0]) r = r[1:] + // If we have a place to put our goroutine labelmap, insert it there. + if labels != nil { + lbl[0] = gp.labels + lbl = lbl[1:] + } + // Save other goroutines. for _, gp1 := range allgs { if isOK(gp1) { @@ -983,16 +992,30 @@ func GoroutineProfile(p []StackRecord) (n int, ok bool) { break } saveg(gp1, &r[0]) + if labels != nil { + lbl[0] = gp1.labels + lbl = lbl[1:] + } r = r[1:] } } } startTheWorld() - return n, ok } +// GoroutineProfile returns n, the number of records in the active goroutine stack profile. +// If len(p) >= n, GoroutineProfile copies the profile into p and returns n, true. +// If len(p) < n, GoroutineProfile does not change p and returns n, false. +// +// Most clients should use the runtime/pprof package instead +// of calling GoroutineProfile directly. +func GoroutineProfile(p []StackRecord) (n int, ok bool) { + + return goroutineProfileWithLabels(p, nil) +} + func saveg(gp *g, r *StackRecord) { if gp == getg() { var locbuf [32]location diff --git a/libgo/go/runtime/mranges.go b/libgo/go/runtime/mranges.go index b13385165b3..e23d0778eb9 100644 --- a/libgo/go/runtime/mranges.go +++ b/libgo/go/runtime/mranges.go @@ -15,23 +15,41 @@ import ( ) // addrRange represents a region of address space. +// +// An addrRange must never span a gap in the address space. type addrRange struct { // base and limit together represent the region of address space // [base, limit). That is, base is inclusive, limit is exclusive. - base, limit uintptr + // These are address over an offset view of the address space on + // platforms with a segmented address space, that is, on platforms + // where arenaBaseOffset != 0. + base, limit offAddr +} + +// makeAddrRange creates a new address range from two virtual addresses. +// +// Throws if the base and limit are not in the same memory segment. +func makeAddrRange(base, limit uintptr) addrRange { + r := addrRange{offAddr{base}, offAddr{limit}} + if (base-arenaBaseOffset >= base) != (limit-arenaBaseOffset >= limit) { + throw("addr range base and limit are not in the same memory segment") + } + return r } // size returns the size of the range represented in bytes. func (a addrRange) size() uintptr { - if a.limit <= a.base { + if !a.base.lessThan(a.limit) { return 0 } - return a.limit - a.base + // Subtraction is safe because limit and base must be in the same + // segment of the address space. + return a.limit.diff(a.base) } // contains returns whether or not the range contains a given address. func (a addrRange) contains(addr uintptr) bool { - return addr >= a.base && addr < a.limit + return a.base.lessEqual(offAddr{addr}) && (offAddr{addr}).lessThan(a.limit) } // subtract takes the addrRange toPrune and cuts out any overlap with @@ -39,18 +57,90 @@ func (a addrRange) contains(addr uintptr) bool { // either don't overlap at all, only overlap on one side, or are equal. // If b is strictly contained in a, thus forcing a split, it will throw. func (a addrRange) subtract(b addrRange) addrRange { - if a.base >= b.base && a.limit <= b.limit { + if b.base.lessEqual(a.base) && a.limit.lessEqual(b.limit) { return addrRange{} - } else if a.base < b.base && a.limit > b.limit { + } else if a.base.lessThan(b.base) && b.limit.lessThan(a.limit) { throw("bad prune") - } else if a.limit > b.limit && a.base < b.limit { + } else if b.limit.lessThan(a.limit) && a.base.lessThan(b.limit) { a.base = b.limit - } else if a.base < b.base && a.limit > b.base { + } else if a.base.lessThan(b.base) && b.base.lessThan(a.limit) { a.limit = b.base } return a } +// removeGreaterEqual removes all addresses in a greater than or equal +// to addr and returns the new range. +func (a addrRange) removeGreaterEqual(addr uintptr) addrRange { + if (offAddr{addr}).lessEqual(a.base) { + return addrRange{} + } + if a.limit.lessEqual(offAddr{addr}) { + return a + } + return makeAddrRange(a.base.addr(), addr) +} + +var ( + // minOffAddr is the minimum address in the offset space, and + // it corresponds to the virtual address arenaBaseOffset. + minOffAddr = offAddr{arenaBaseOffset} + + // maxOffAddr is the maximum address in the offset address + // space. It corresponds to the highest virtual address representable + // by the page alloc chunk and heap arena maps. + maxOffAddr = offAddr{(((1 << heapAddrBits) - 1) + arenaBaseOffset) & uintptrMask} +) + +// offAddr represents an address in a contiguous view +// of the address space on systems where the address space is +// segmented. On other systems, it's just a normal address. +type offAddr struct { + // a is just the virtual address, but should never be used + // directly. Call addr() to get this value instead. + a uintptr +} + +// add adds a uintptr offset to the offAddr. +func (l offAddr) add(bytes uintptr) offAddr { + return offAddr{a: l.a + bytes} +} + +// sub subtracts a uintptr offset from the offAddr. +func (l offAddr) sub(bytes uintptr) offAddr { + return offAddr{a: l.a - bytes} +} + +// diff returns the amount of bytes in between the +// two offAddrs. +func (l1 offAddr) diff(l2 offAddr) uintptr { + return l1.a - l2.a +} + +// lessThan returns true if l1 is less than l2 in the offset +// address space. +func (l1 offAddr) lessThan(l2 offAddr) bool { + return (l1.a - arenaBaseOffset) < (l2.a - arenaBaseOffset) +} + +// lessEqual returns true if l1 is less than or equal to l2 in +// the offset address space. +func (l1 offAddr) lessEqual(l2 offAddr) bool { + return (l1.a - arenaBaseOffset) <= (l2.a - arenaBaseOffset) +} + +// equal returns true if the two offAddr values are equal. +func (l1 offAddr) equal(l2 offAddr) bool { + // No need to compare in the offset space, it + // means the same thing. + return l1 == l2 +} + +// addr returns the virtual address for this offset address. +func (l offAddr) addr() uintptr { + return l.a +} + // addrRanges is a data structure holding a collection of ranges of // address space. // @@ -65,6 +155,10 @@ type addrRanges struct { // ranges is a slice of ranges sorted by base. ranges []addrRange + // totalBytes is the total amount of address space in bytes counted by + // this addrRanges. + totalBytes uintptr + // sysStat is the stat to track allocations by this type sysStat *uint64 } @@ -75,17 +169,19 @@ func (a *addrRanges) init(sysStat *uint64) { ranges.cap = 16 ranges.array = (*notInHeap)(persistentalloc(unsafe.Sizeof(addrRange{})*uintptr(ranges.cap), sys.PtrSize, sysStat)) a.sysStat = sysStat + a.totalBytes = 0 } // findSucc returns the first index in a such that base is // less than the base of the addrRange at that index. -func (a *addrRanges) findSucc(base uintptr) int { +func (a *addrRanges) findSucc(addr uintptr) int { // TODO(mknyszek): Consider a binary search for large arrays. // While iterating over these ranges is potentially expensive, // the expected number of ranges is small, ideally just 1, // since Go heaps are usually mostly contiguous. + base := offAddr{addr} for i := range a.ranges { - if base < a.ranges[i].base { + if base.lessThan(a.ranges[i].base) { return i } } @@ -116,9 +212,9 @@ func (a *addrRanges) add(r addrRange) { // Because we assume r is not currently represented in a, // findSucc gives us our insertion index. - i := a.findSucc(r.base) - coalescesDown := i > 0 && a.ranges[i-1].limit == r.base - coalescesUp := i < len(a.ranges) && r.limit == a.ranges[i].base + i := a.findSucc(r.base.addr()) + coalescesDown := i > 0 && a.ranges[i-1].limit.equal(r.base) + coalescesUp := i < len(a.ranges) && r.limit.equal(a.ranges[i].base) if coalescesUp && coalescesDown { // We have neighbors and they both border us. // Merge a.ranges[i-1], r, and a.ranges[i] together into a.ranges[i-1]. @@ -158,4 +254,68 @@ func (a *addrRanges) add(r addrRange) { } a.ranges[i] = r } + a.totalBytes += r.size() +} + +// removeLast removes and returns the highest-addressed contiguous range +// of a, or the last nBytes of that range, whichever is smaller. If a is +// empty, it returns an empty range. +func (a *addrRanges) removeLast(nBytes uintptr) addrRange { + if len(a.ranges) == 0 { + return addrRange{} + } + r := a.ranges[len(a.ranges)-1] + size := r.size() + if size > nBytes { + newEnd := r.limit.sub(nBytes) + a.ranges[len(a.ranges)-1].limit = newEnd + a.totalBytes -= nBytes + return addrRange{newEnd, r.limit} + } + a.ranges = a.ranges[:len(a.ranges)-1] + a.totalBytes -= size + return r +} + +// removeGreaterEqual removes the ranges of a which are above addr, and additionally +// splits any range containing addr. +func (a *addrRanges) removeGreaterEqual(addr uintptr) { + pivot := a.findSucc(addr) + if pivot == 0 { + // addr is before all ranges in a. + a.totalBytes = 0 + a.ranges = a.ranges[:0] + return + } + removed := uintptr(0) + for _, r := range a.ranges[pivot:] { + removed += r.size() + } + if r := a.ranges[pivot-1]; r.contains(addr) { + removed += r.size() + r = r.removeGreaterEqual(addr) + if r.size() == 0 { + pivot-- + } else { + removed -= r.size() + a.ranges[pivot-1] = r + } + } + a.ranges = a.ranges[:pivot] + a.totalBytes -= removed +} + +// cloneInto makes a deep clone of a's state into b, re-using +// b's ranges if able. +func (a *addrRanges) cloneInto(b *addrRanges) { + if len(a.ranges) > cap(b.ranges) { + // Grow the array. + ranges := (*notInHeapSlice)(unsafe.Pointer(&b.ranges)) + ranges.len = 0 + ranges.cap = cap(a.ranges) + ranges.array = (*notInHeap)(persistentalloc(unsafe.Sizeof(addrRange{})*uintptr(ranges.cap), sys.PtrSize, b.sysStat)) + } + b.ranges = b.ranges[:len(a.ranges)] + b.totalBytes = a.totalBytes + copy(b.ranges, a.ranges) } diff --git a/libgo/go/runtime/msize.go b/libgo/go/runtime/msize.go index 11d06ce0251..c56aa5a7b2c 100644 --- a/libgo/go/runtime/msize.go +++ b/libgo/go/runtime/msize.go @@ -13,9 +13,9 @@ package runtime func roundupsize(size uintptr) uintptr { if size < _MaxSmallSize { if size <= smallSizeMax-8 { - return uintptr(class_to_size[size_to_class8[(size+smallSizeDiv-1)/smallSizeDiv]]) + return uintptr(class_to_size[size_to_class8[divRoundUp(size, smallSizeDiv)]]) } else { - return uintptr(class_to_size[size_to_class128[(size-smallSizeMax+largeSizeDiv-1)/largeSizeDiv]]) + return uintptr(class_to_size[size_to_class128[divRoundUp(size-smallSizeMax, largeSizeDiv)]]) } } if size+_PageSize < size { diff --git a/libgo/go/runtime/mspanset.go b/libgo/go/runtime/mspanset.go new file mode 100644 index 00000000000..c872c11d1fb --- /dev/null +++ b/libgo/go/runtime/mspanset.go @@ -0,0 +1,358 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime + +import ( + "internal/cpu" + "runtime/internal/atomic" + "runtime/internal/sys" + "unsafe" +) + +// A spanSet is a set of *mspans. +// +// spanSet is safe for concurrent push and pop operations. +type spanSet struct { + // A spanSet is a two-level data structure consisting of a + // growable spine that points to fixed-sized blocks. The spine + // can be accessed without locks, but adding a block or + // growing it requires taking the spine lock. + // + // Because each mspan covers at least 8K of heap and takes at + // most 8 bytes in the spanSet, the growth of the spine is + // quite limited. + // + // The spine and all blocks are allocated off-heap, which + // allows this to be used in the memory manager and avoids the + // need for write barriers on all of these. spanSetBlocks are + // managed in a pool, though never freed back to the operating + // system. We never release spine memory because there could be + // concurrent lock-free access and we're likely to reuse it + // anyway. (In principle, we could do this during STW.) + + spineLock mutex + spine unsafe.Pointer // *[N]*spanSetBlock, accessed atomically + spineLen uintptr // Spine array length, accessed atomically + spineCap uintptr // Spine array cap, accessed under lock + + // index is the head and tail of the spanSet in a single field. + // The head and the tail both represent an index into the logical + // concatenation of all blocks, with the head always behind or + // equal to the tail (indicating an empty set). This field is + // always accessed atomically. + // + // The head and the tail are only 32 bits wide, which means we + // can only support up to 2^32 pushes before a reset. If every + // span in the heap were stored in this set, and each span were + // the minimum size (1 runtime page, 8 KiB), then roughly the + // smallest heap which would be unrepresentable is 32 TiB in size. + index headTailIndex +} + +const ( + spanSetBlockEntries = 512 // 4KB on 64-bit + spanSetInitSpineCap = 256 // Enough for 1GB heap on 64-bit +) + +type spanSetBlock struct { + // Free spanSetBlocks are managed via a lock-free stack. + lfnode + + // popped is the number of pop operations that have occurred on + // this block. This number is used to help determine when a block + // may be safely recycled. + popped uint32 + + // spans is the set of spans in this block. + spans [spanSetBlockEntries]*mspan +} + +// push adds span s to buffer b. push is safe to call concurrently +// with other push and pop operations. +func (b *spanSet) push(s *mspan) { + // Obtain our slot. + cursor := uintptr(b.index.incTail().tail() - 1) + top, bottom := cursor/spanSetBlockEntries, cursor%spanSetBlockEntries + + // Do we need to add a block? + spineLen := atomic.Loaduintptr(&b.spineLen) + var block *spanSetBlock +retry: + if top < spineLen { + spine := atomic.Loadp(unsafe.Pointer(&b.spine)) + blockp := add(spine, sys.PtrSize*top) + block = (*spanSetBlock)(atomic.Loadp(blockp)) + } else { + // Add a new block to the spine, potentially growing + // the spine. + lock(&b.spineLock) + // spineLen cannot change until we release the lock, + // but may have changed while we were waiting. + spineLen = atomic.Loaduintptr(&b.spineLen) + if top < spineLen { + unlock(&b.spineLock) + goto retry + } + + if spineLen == b.spineCap { + // Grow the spine. + newCap := b.spineCap * 2 + if newCap == 0 { + newCap = spanSetInitSpineCap + } + newSpine := persistentalloc(newCap*sys.PtrSize, cpu.CacheLineSize, &memstats.gc_sys) + if b.spineCap != 0 { + // Blocks are allocated off-heap, so + // no write barriers. + memmove(newSpine, b.spine, b.spineCap*sys.PtrSize) + } + // Spine is allocated off-heap, so no write barrier. + atomic.StorepNoWB(unsafe.Pointer(&b.spine), newSpine) + b.spineCap = newCap + // We can't immediately free the old spine + // since a concurrent push with a lower index + // could still be reading from it. We let it + // leak because even a 1TB heap would waste + // less than 2MB of memory on old spines. If + // this is a problem, we could free old spines + // during STW. + } + + // Allocate a new block from the pool. + block = spanSetBlockPool.alloc() + + // Add it to the spine. + blockp := add(b.spine, sys.PtrSize*top) + // Blocks are allocated off-heap, so no write barrier. + atomic.StorepNoWB(blockp, unsafe.Pointer(block)) + atomic.Storeuintptr(&b.spineLen, spineLen+1) + unlock(&b.spineLock) + } + + // We have a block. Insert the span atomically, since there may be + // concurrent readers via the block API. + atomic.StorepNoWB(unsafe.Pointer(&block.spans[bottom]), unsafe.Pointer(s)) +} + +// pop removes and returns a span from buffer b, or nil if b is empty. +// pop is safe to call concurrently with other pop and push operations. +func (b *spanSet) pop() *mspan { + var head, tail uint32 +claimLoop: + for { + headtail := b.index.load() + head, tail = headtail.split() + if head >= tail { + // The buf is empty, as far as we can tell. + return nil + } + // Check if the head position we want to claim is actually + // backed by a block. + spineLen := atomic.Loaduintptr(&b.spineLen) + if spineLen <= uintptr(head)/spanSetBlockEntries { + // We're racing with a spine growth and the allocation of + // a new block (and maybe a new spine!), and trying to grab + // the span at the index which is currently being pushed. + // Instead of spinning, let's just notify the caller that + // there's nothing currently here. Spinning on this is + // almost definitely not worth it. + return nil + } + // Try to claim the current head by CASing in an updated head. + // This may fail transiently due to a push which modifies the + // tail, so keep trying while the head isn't changing. + want := head + for want == head { + if b.index.cas(headtail, makeHeadTailIndex(want+1, tail)) { + break claimLoop + } + headtail = b.index.load() + head, tail = headtail.split() + } + // We failed to claim the spot we were after and the head changed, + // meaning a popper got ahead of us. Try again from the top because + // the buf may not be empty. + } + top, bottom := head/spanSetBlockEntries, head%spanSetBlockEntries + + // We may be reading a stale spine pointer, but because the length + // grows monotonically and we've already verified it, we'll definitely + // be reading from a valid block. + spine := atomic.Loadp(unsafe.Pointer(&b.spine)) + blockp := add(spine, sys.PtrSize*uintptr(top)) + + // Given that the spine length is correct, we know we will never + // see a nil block here, since the length is always updated after + // the block is set. + block := (*spanSetBlock)(atomic.Loadp(blockp)) + s := (*mspan)(atomic.Loadp(unsafe.Pointer(&block.spans[bottom]))) + for s == nil { + // We raced with the span actually being set, but given that we + // know a block for this span exists, the race window here is + // extremely small. Try again. + s = (*mspan)(atomic.Loadp(unsafe.Pointer(&block.spans[bottom]))) + } + // Clear the pointer. This isn't strictly necessary, but defensively + // avoids accidentally re-using blocks which could lead to memory + // corruption. This way, we'll get a nil pointer access instead. + atomic.StorepNoWB(unsafe.Pointer(&block.spans[bottom]), nil) + + // Increase the popped count. If we are the last possible popper + // in the block (note that bottom need not equal spanSetBlockEntries-1 + // due to races) then it's our resposibility to free the block. + // + // If we increment popped to spanSetBlockEntries, we can be sure that + // we're the last popper for this block, and it's thus safe to free it. + // Every other popper must have crossed this barrier (and thus finished + // popping its corresponding mspan) by the time we get here. Because + // we're the last popper, we also don't have to worry about concurrent + // pushers (there can't be any). Note that we may not be the popper + // which claimed the last slot in the block, we're just the last one + // to finish popping. + if atomic.Xadd(&block.popped, 1) == spanSetBlockEntries { + // Clear the block's pointer. + atomic.StorepNoWB(blockp, nil) + + // Return the block to the block pool. + spanSetBlockPool.free(block) + } + return s +} + +// reset resets a spanSet which is empty. It will also clean up +// any left over blocks. +// +// Throws if the buf is not empty. +// +// reset may not be called concurrently with any other operations +// on the span set. +func (b *spanSet) reset() { + head, tail := b.index.load().split() + if head < tail { + print("head = ", head, ", tail = ", tail, "\n") + throw("attempt to clear non-empty span set") + } + top := head / spanSetBlockEntries + if uintptr(top) < b.spineLen { + // If the head catches up to the tail and the set is empty, + // we may not clean up the block containing the head and tail + // since it may be pushed into again. In order to avoid leaking + // memory since we're going to reset the head and tail, clean + // up such a block now, if it exists. + blockp := (**spanSetBlock)(add(b.spine, sys.PtrSize*uintptr(top))) + block := *blockp + if block != nil { + // Sanity check the popped value. + if block.popped == 0 { + // popped should never be zero because that means we have + // pushed at least one value but not yet popped if this + // block pointer is not nil. + throw("span set block with unpopped elements found in reset") + } + if block.popped == spanSetBlockEntries { + // popped should also never be equal to spanSetBlockEntries + // because the last popper should have made the block pointer + // in this slot nil. + throw("fully empty unfreed span set block found in reset") + } + + // Clear the pointer to the block. + atomic.StorepNoWB(unsafe.Pointer(blockp), nil) + + // Return the block to the block pool. + spanSetBlockPool.free(block) + } + } + b.index.reset() + atomic.Storeuintptr(&b.spineLen, 0) +} + +// gccgoAlignment is used to get spanSetBlockPool aligned on a 64-bit +// boundary on 32-bit x86. +var gccgoAlignment uint64 + +// spanSetBlockPool is a global pool of spanSetBlocks. +var spanSetBlockPool = (*spanSetBlockAlloc)(unsafe.Pointer(&gccgoAlignment)) + +// spanSetBlockAlloc represents a concurrent pool of spanSetBlocks. +type spanSetBlockAlloc struct { + stack lfstack +} + +// alloc tries to grab a spanSetBlock out of the pool, and if it fails +// persistentallocs a new one and returns it. +func (p *spanSetBlockAlloc) alloc() *spanSetBlock { + if s := (*spanSetBlock)(p.stack.pop()); s != nil { + return s + } + return (*spanSetBlock)(persistentalloc(unsafe.Sizeof(spanSetBlock{}), cpu.CacheLineSize, &memstats.gc_sys)) +} + +// free returns a spanSetBlock back to the pool. +func (p *spanSetBlockAlloc) free(block *spanSetBlock) { + atomic.Store(&block.popped, 0) + p.stack.push(&block.lfnode) +} + +// haidTailIndex represents a combined 32-bit head and 32-bit tail +// of a queue into a single 64-bit value. +type headTailIndex uint64 + +// makeHeadTailIndex creates a headTailIndex value from a separate +// head and tail. +func makeHeadTailIndex(head, tail uint32) headTailIndex { + return headTailIndex(uint64(head)<<32 | uint64(tail)) +} + +// head returns the head of a headTailIndex value. +func (h headTailIndex) head() uint32 { + return uint32(h >> 32) +} + +// tail returns the tail of a headTailIndex value. +func (h headTailIndex) tail() uint32 { + return uint32(h) +} + +// split splits the headTailIndex value into its parts. +func (h headTailIndex) split() (head uint32, tail uint32) { + return h.head(), h.tail() +} + +// load atomically reads a headTailIndex value. +func (h *headTailIndex) load() headTailIndex { + return headTailIndex(atomic.Load64((*uint64)(h))) +} + +// cas atomically compares-and-swaps a headTailIndex value. +func (h *headTailIndex) cas(old, new headTailIndex) bool { + return atomic.Cas64((*uint64)(h), uint64(old), uint64(new)) +} + +// incHead atomically increments the head of a headTailIndex. +func (h *headTailIndex) incHead() headTailIndex { + return headTailIndex(atomic.Xadd64((*uint64)(h), (1 << 32))) +} + +// decHead atomically decrements the head of a headTailIndex. +func (h *headTailIndex) decHead() headTailIndex { + return headTailIndex(atomic.Xadd64((*uint64)(h), -(1 << 32))) +} + +// incTail atomically increments the tail of a headTailIndex. +func (h *headTailIndex) incTail() headTailIndex { + ht := headTailIndex(atomic.Xadd64((*uint64)(h), +1)) + // Check for overflow. + if ht.tail() == 0 { + print("runtime: head = ", ht.head(), ", tail = ", ht.tail(), "\n") + throw("headTailIndex overflow") + } + return ht +} + +// reset clears the headTailIndex to (0, 0). +func (h *headTailIndex) reset() { + atomic.Store64((*uint64)(h), 0) +} diff --git a/libgo/go/runtime/mstats.go b/libgo/go/runtime/mstats.go index 2d4cdbe042c..4e2c66cea1f 100644 --- a/libgo/go/runtime/mstats.go +++ b/libgo/go/runtime/mstats.go @@ -513,6 +513,12 @@ func readGCStats_m(pauses *[]uint64) { //go:nowritebarrier func updatememstats() { + // Flush mcaches to mcentral before doing anything else. + // + // Flushing to the mcentral may in general cause stats to + // change as mcentral data structures are manipulated. + systemstack(flushallmcaches) + memstats.mcache_inuse = uint64(mheap_.cachealloc.inuse) memstats.mspan_inuse = uint64(mheap_.spanalloc.inuse) memstats.sys = memstats.heap_sys + memstats.stacks_sys + memstats.mspan_sys + @@ -523,7 +529,7 @@ func updatememstats() { // Calculate memory allocator stats. // During program execution we only count number of frees and amount of freed memory. - // Current number of alive object in the heap and amount of alive heap memory + // Current number of alive objects in the heap and amount of alive heap memory // are calculated by scanning all spans. // Total number of mallocs is calculated as number of frees plus number of alive objects. // Similarly, total amount of allocated memory is calculated as amount of freed memory @@ -537,9 +543,6 @@ func updatememstats() { memstats.by_size[i].nfree = 0 } - // Flush mcache's to mcentral. - systemstack(flushallmcaches) - // Aggregate local stats. cachestats() diff --git a/libgo/go/runtime/mwbbuf.go b/libgo/go/runtime/mwbbuf.go index a27406e2987..548d4c51074 100644 --- a/libgo/go/runtime/mwbbuf.go +++ b/libgo/go/runtime/mwbbuf.go @@ -303,6 +303,13 @@ func wbBufFlush1(_p_ *p) { continue } mbits.setMarked() + + // Mark span. + arena, pageIdx, pageMask := pageIndexOf(span.base()) + if arena.pageMarks[pageIdx]&pageMask == 0 { + atomic.Or8(&arena.pageMarks[pageIdx], pageMask) + } + if span.spanclass.noscan() { gcw.bytesMarked += uint64(span.elemsize) continue diff --git a/libgo/go/runtime/netpoll.go b/libgo/go/runtime/netpoll.go index d2fb77569d6..5157e4dd9e2 100644 --- a/libgo/go/runtime/netpoll.go +++ b/libgo/go/runtime/netpoll.go @@ -36,18 +36,27 @@ import ( // func netpollIsPollDescriptor(fd uintptr) bool // Reports whether fd is a file descriptor used by the poller. +// Error codes returned by runtime_pollReset and runtime_pollWait. +// These must match the values in internal/poll/fd_poll_runtime.go. +const ( + pollNoError = 0 // no error + pollErrClosing = 1 // descriptor is closed + pollErrTimeout = 2 // I/O timeout + pollErrNotPollable = 3 // general error polling descriptor +) + // pollDesc contains 2 binary semaphores, rg and wg, to park reader and writer // goroutines respectively. The semaphore can be in the following states: // pdReady - io readiness notification is pending; // a goroutine consumes the notification by changing the state to nil. // pdWait - a goroutine prepares to park on the semaphore, but not yet parked; // the goroutine commits to park by changing the state to G pointer, -// or, alternatively, concurrent io notification changes the state to READY, +// or, alternatively, concurrent io notification changes the state to pdReady, // or, alternatively, concurrent timeout/close changes the state to nil. // G pointer - the goroutine is blocked on the semaphore; -// io notification or timeout/close changes the state to READY or nil respectively +// io notification or timeout/close changes the state to pdReady or nil respectively // and unparks the goroutine. -// nil - nothing of the above. +// nil - none of the above. const ( pdReady uintptr = 1 pdWait uintptr = 2 @@ -110,6 +119,7 @@ func poll_runtime_pollServerInit() { func netpollGenericInit() { if atomic.Load(&netpollInited) == 0 { + lockInit(&netpollInitLock, lockRankNetpollInit) lock(&netpollInitLock) if netpollInited == 0 { netpollinit() @@ -180,42 +190,49 @@ func (c *pollCache) free(pd *pollDesc) { unlock(&c.lock) } +// poll_runtime_pollReset, which is internal/poll.runtime_pollReset, +// prepares a descriptor for polling in mode, which is 'r' or 'w'. +// This returns an error code; the codes are defined above. //go:linkname poll_runtime_pollReset internal..z2fpoll.runtime_pollReset func poll_runtime_pollReset(ctx uintptr, mode int) int { pd := (*pollDesc)(unsafe.Pointer(ctx)) - err := netpollcheckerr(pd, int32(mode)) - if err != 0 { - return err + errcode := netpollcheckerr(pd, int32(mode)) + if errcode != pollNoError { + return errcode } if mode == 'r' { pd.rg = 0 } else if mode == 'w' { pd.wg = 0 } - return 0 + return pollNoError } +// poll_runtime_pollWait, which is internal/poll.runtime_pollWait, +// waits for a descriptor to be ready for reading or writing, +// according to mode, which is 'r' or 'w'. +// This returns an error code; the codes are defined above. //go:linkname poll_runtime_pollWait internal..z2fpoll.runtime_pollWait func poll_runtime_pollWait(ctx uintptr, mode int) int { pd := (*pollDesc)(unsafe.Pointer(ctx)) - err := netpollcheckerr(pd, int32(mode)) - if err != 0 { - return err + errcode := netpollcheckerr(pd, int32(mode)) + if errcode != pollNoError { + return errcode } // As for now only Solaris, illumos, and AIX use level-triggered IO. if GOOS == "solaris" || GOOS == "illumos" || GOOS == "aix" || GOOS == "hurd" { netpollarm(pd, mode) } for !netpollblock(pd, int32(mode), false) { - err = netpollcheckerr(pd, int32(mode)) - if err != 0 { - return err + errcode = netpollcheckerr(pd, int32(mode)) + if errcode != pollNoError { + return errcode } // Can happen if timeout has fired and unblocked us, // but before we had a chance to run, timeout has been reset. // Pretend it has not happened and retry. } - return 0 + return pollNoError } //go:linkname poll_runtime_pollWaitCanceled internal..z2fpoll.runtime_pollWaitCanceled @@ -368,18 +385,18 @@ func netpollready(toRun *gList, pd *pollDesc, mode int32) { func netpollcheckerr(pd *pollDesc, mode int32) int { if pd.closing { - return 1 // ErrFileClosing or ErrNetClosing + return pollErrClosing } if (mode == 'r' && pd.rd < 0) || (mode == 'w' && pd.wd < 0) { - return 2 // ErrTimeout + return pollErrTimeout } // Report an event scanning error only on a read event. // An error on a write event will be captured in a subsequent // write call that is able to report a more specific error. if mode == 'r' && pd.everr { - return 3 // ErrNotPollable + return pollErrNotPollable } - return 0 + return pollNoError } func netpollblockcommit(gp *g, gpp unsafe.Pointer) bool { @@ -406,7 +423,7 @@ func netpollblock(pd *pollDesc, mode int32, waitio bool) bool { gpp = &pd.wg } - // set the gpp semaphore to WAIT + // set the gpp semaphore to pdWait for { old := *gpp if old == pdReady { @@ -421,13 +438,13 @@ func netpollblock(pd *pollDesc, mode int32, waitio bool) bool { } } - // need to recheck error states after setting gpp to WAIT + // need to recheck error states after setting gpp to pdWait // this is necessary because runtime_pollUnblock/runtime_pollSetDeadline/deadlineimpl // do the opposite: store to closing/rd/wd, membarrier, load of rg/wg if waitio || netpollcheckerr(pd, mode) == 0 { gopark(netpollblockcommit, unsafe.Pointer(gpp), waitReasonIOWait, traceEvGoBlockNet, 5) } - // be careful to not lose concurrent READY notification + // be careful to not lose concurrent pdReady notification old := atomic.Xchguintptr(gpp, 0) if old > pdWait { throw("runtime: corrupted polldesc") @@ -447,7 +464,7 @@ func netpollunblock(pd *pollDesc, mode int32, ioready bool) *g { return nil } if old == 0 && !ioready { - // Only set READY for ioready. runtime_pollWait + // Only set pdReady for ioready. runtime_pollWait // will check for timeout/cancel before waiting. return nil } @@ -456,7 +473,7 @@ func netpollunblock(pd *pollDesc, mode int32, ioready bool) *g { new = pdReady } if atomic.Casuintptr(gpp, old, new) { - if old == pdReady || old == pdWait { + if old == pdWait { old = 0 } return (*g)(unsafe.Pointer(old)) @@ -535,6 +552,7 @@ func (c *pollCache) alloc() *pollDesc { } pd := c.first c.first = pd.link + lockInit(&pd.lock, lockRankPollDesc) unlock(&c.lock) return pd } diff --git a/libgo/go/runtime/netpoll_aix.go b/libgo/go/runtime/netpoll_aix.go index a00742e39ae..bb6ce375475 100644 --- a/libgo/go/runtime/netpoll_aix.go +++ b/libgo/go/runtime/netpoll_aix.go @@ -4,7 +4,10 @@ package runtime -import "unsafe" +import ( + "runtime/internal/atomic" + "unsafe" +) // This is based on the former libgo/runtime/netpoll_select.c implementation // except that it uses poll instead of select and is written in Go. @@ -34,6 +37,8 @@ var ( rdwake int32 wrwake int32 pendingUpdates int32 + + netpollWakeSig uint32 // used to avoid duplicate calls of netpollBreak ) func netpollinit() { @@ -121,9 +126,12 @@ func netpollarm(pd *pollDesc, mode int) { unlock(&mtxset) } -// netpollBreak interrupts an epollwait. +// netpollBreak interrupts a poll. func netpollBreak() { - netpollwakeup() + if atomic.Cas(&netpollWakeSig, 0, 1) { + b := [1]byte{0} + write(uintptr(wrwake), unsafe.Pointer(&b[0]), 1) + } } // netpoll checks for ready network connections. @@ -178,6 +186,7 @@ retry: var b [1]byte for read(rdwake, unsafe.Pointer(&b[0]), 1) == 1 { } + atomic.Store(&netpollWakeSig, 0) } // Still look at the other fds even if the mode may have // changed, as netpollBreak might have been called. diff --git a/libgo/go/runtime/netpoll_epoll.go b/libgo/go/runtime/netpoll_epoll.go index 7b215f31871..9c5d33851cb 100644 --- a/libgo/go/runtime/netpoll_epoll.go +++ b/libgo/go/runtime/netpoll_epoll.go @@ -6,7 +6,10 @@ package runtime -import "unsafe" +import ( + "runtime/internal/atomic" + "unsafe" +) //extern epoll_create func epollcreate(size int32) int32 @@ -26,6 +29,8 @@ var ( epfd int32 = -1 // epoll descriptor netpollBreakRd, netpollBreakWr uintptr // for netpollBreak + + netpollWakeSig uint32 // used to avoid duplicate calls of netpollBreak ) func netpollinit() { @@ -86,20 +91,22 @@ func netpollarm(pd *pollDesc, mode int) { // netpollBreak interrupts an epollwait. func netpollBreak() { - for { - var b byte - n := write(netpollBreakWr, unsafe.Pointer(&b), 1) - if n == 1 { - break - } - if n == -_EINTR { - continue - } - if n == -_EAGAIN { - return + if atomic.Cas(&netpollWakeSig, 0, 1) { + for { + var b byte + n := write(netpollBreakWr, unsafe.Pointer(&b), 1) + if n == 1 { + break + } + if n == -_EINTR { + continue + } + if n == -_EAGAIN { + return + } + println("runtime: netpollBreak write failed with", -n) + throw("runtime: netpollBreak write failed") } - println("runtime: netpollBreak write failed with", -n) - throw("runtime: netpollBreak write failed") } } @@ -160,6 +167,7 @@ retry: // if blocking. var tmp [16]byte read(int32(netpollBreakRd), noescape(unsafe.Pointer(&tmp[0])), int32(len(tmp))) + atomic.Store(&netpollWakeSig, 0) } continue } diff --git a/libgo/go/runtime/netpoll_kqueue.go b/libgo/go/runtime/netpoll_kqueue.go index 94504613787..c41a7d03097 100644 --- a/libgo/go/runtime/netpoll_kqueue.go +++ b/libgo/go/runtime/netpoll_kqueue.go @@ -8,7 +8,10 @@ package runtime // Integrated network poller (kqueue-based implementation). -import "unsafe" +import ( + "runtime/internal/atomic" + "unsafe" +) //extern kqueue func kqueue() int32 @@ -21,6 +24,8 @@ var ( kq int32 = -1 netpollBreakRd, netpollBreakWr uintptr // for netpollBreak + + netpollWakeSig uint32 // used to avoid duplicate calls of netpollBreak ) func netpollinit() { @@ -83,19 +88,21 @@ func netpollarm(pd *pollDesc, mode int) { throw("runtime: unused") } -// netpollBreak interrupts an epollwait. +// netpollBreak interrupts a kevent. func netpollBreak() { - for { - var b byte - n := write(netpollBreakWr, unsafe.Pointer(&b), 1) - if n == 1 || n == -_EAGAIN { - break - } - if n == -_EINTR { - continue + if atomic.Cas(&netpollWakeSig, 0, 1) { + for { + var b byte + n := write(netpollBreakWr, unsafe.Pointer(&b), 1) + if n == 1 || n == -_EAGAIN { + break + } + if n == -_EINTR { + continue + } + println("runtime: netpollBreak write failed with", -n) + throw("runtime: netpollBreak write failed") } - println("runtime: netpollBreak write failed with", -n) - throw("runtime: netpollBreak write failed") } } @@ -153,6 +160,7 @@ retry: // if blocking. var tmp [16]byte read(int32(netpollBreakRd), noescape(unsafe.Pointer(&tmp[0])), int32(len(tmp))) + atomic.Store(&netpollWakeSig, 0) } continue } diff --git a/libgo/go/runtime/netpoll_os_test.go b/libgo/go/runtime/netpoll_os_test.go new file mode 100644 index 00000000000..b96b9f3ee38 --- /dev/null +++ b/libgo/go/runtime/netpoll_os_test.go @@ -0,0 +1,28 @@ +package runtime_test + +import ( + "runtime" + "sync" + "testing" +) + +var wg sync.WaitGroup + +func init() { + runtime.NetpollGenericInit() +} + +func BenchmarkNetpollBreak(b *testing.B) { + b.StartTimer() + for i := 0; i < b.N; i++ { + for j := 0; j < 10; j++ { + wg.Add(1) + go func() { + runtime.NetpollBreak() + wg.Done() + }() + } + } + wg.Wait() + b.StopTimer() +} diff --git a/libgo/go/runtime/netpoll_solaris.go b/libgo/go/runtime/netpoll_solaris.go index acb8bab77b6..d5302b59365 100644 --- a/libgo/go/runtime/netpoll_solaris.go +++ b/libgo/go/runtime/netpoll_solaris.go @@ -4,7 +4,10 @@ package runtime -import "unsafe" +import ( + "runtime/internal/atomic" + "unsafe" +) // Solaris runtime-integrated network poller. // @@ -83,6 +86,10 @@ func port_getn(port int32, evs *portevent, max uint32, nget *uint32, timeout *ti //extern port_alert func port_alert(port int32, flags, events uint32, user uintptr) int32 +var ( + netpollWakeSig uint32 // used to avoid duplicate calls of netpollBreak +) + var portfd int32 = -1 func netpollinit() { @@ -161,15 +168,17 @@ func netpollarm(pd *pollDesc, mode int) { // netpollBreak interrupts a port_getn wait. func netpollBreak() { - // Use port_alert to put portfd into alert mode. - // This will wake up all threads sleeping in port_getn on portfd, - // and cause their calls to port_getn to return immediately. - // Further, until portfd is taken out of alert mode, - // all calls to port_getn will return immediately. - if port_alert(portfd, _PORT_ALERT_UPDATE, _POLLHUP, uintptr(unsafe.Pointer(&portfd))) < 0 { - if e := errno(); e != _EBUSY { - println("runtime: port_alert failed with", e) - throw("runtime: netpoll: port_alert failed") + if atomic.Cas(&netpollWakeSig, 0, 1) { + // Use port_alert to put portfd into alert mode. + // This will wake up all threads sleeping in port_getn on portfd, + // and cause their calls to port_getn to return immediately. + // Further, until portfd is taken out of alert mode, + // all calls to port_getn will return immediately. + if port_alert(portfd, _PORT_ALERT_UPDATE, _POLLHUP, uintptr(unsafe.Pointer(&portfd))) < 0 { + if e := errno(); e != _EBUSY { + println("runtime: port_alert failed with", e) + throw("runtime: netpoll: port_alert failed") + } } } } @@ -242,6 +251,7 @@ retry: println("runtime: port_alert failed with", e) throw("runtime: netpoll: port_alert failed") } + atomic.Store(&netpollWakeSig, 0) } continue } diff --git a/libgo/go/runtime/netpoll_stub.go b/libgo/go/runtime/netpoll_stub.go index f86f2f61748..3599f2d01b7 100644 --- a/libgo/go/runtime/netpoll_stub.go +++ b/libgo/go/runtime/netpoll_stub.go @@ -49,6 +49,9 @@ func netpoll(delay int64) gList { notetsleep(&netpollNote, delay) unlock(&netpollStubLock) + // Guard against starvation in case the lock is contended + // (eg when running TestNetpollBreak). + osyield() } return gList{} } diff --git a/libgo/go/runtime/netpoll_windows.go b/libgo/go/runtime/netpoll_windows.go index ced52cbd3a3..4c1cd2633a8 100644 --- a/libgo/go/runtime/netpoll_windows.go +++ b/libgo/go/runtime/netpoll_windows.go @@ -5,6 +5,7 @@ package runtime import ( + "runtime/internal/atomic" "unsafe" ) @@ -31,7 +32,11 @@ type overlappedEntry struct { qty uint32 } -var iocphandle uintptr = _INVALID_HANDLE_VALUE // completion port io handle +var ( + iocphandle uintptr = _INVALID_HANDLE_VALUE // completion port io handle + + netpollWakeSig uint32 // used to avoid duplicate calls of netpollBreak +) func netpollinit() { iocphandle = stdcall4(_CreateIoCompletionPort, _INVALID_HANDLE_VALUE, 0, 0, _DWORD_MAX) @@ -62,9 +67,11 @@ func netpollarm(pd *pollDesc, mode int) { } func netpollBreak() { - if stdcall4(_PostQueuedCompletionStatus, iocphandle, 0, 0, 0) == 0 { - println("runtime: netpoll: PostQueuedCompletionStatus failed (errno=", getlasterror(), ")") - throw("runtime: netpoll: PostQueuedCompletionStatus failed") + if atomic.Cas(&netpollWakeSig, 0, 1) { + if stdcall4(_PostQueuedCompletionStatus, iocphandle, 0, 0, 0) == 0 { + println("runtime: netpoll: PostQueuedCompletionStatus failed (errno=", getlasterror(), ")") + throw("runtime: netpoll: PostQueuedCompletionStatus failed") + } } } @@ -75,7 +82,7 @@ func netpollBreak() { // delay > 0: block for up to that many nanoseconds func netpoll(delay int64) gList { var entries [64]overlappedEntry - var wait, qty, key, flags, n, i uint32 + var wait, qty, flags, n, i uint32 var errno int32 var op *net_op var toRun gList @@ -99,82 +106,48 @@ func netpoll(delay int64) gList { wait = 1e9 } - if _GetQueuedCompletionStatusEx != nil { - n = uint32(len(entries) / int(gomaxprocs)) - if n < 8 { - n = 8 - } - if delay != 0 { - mp.blocked = true - } - if stdcall6(_GetQueuedCompletionStatusEx, iocphandle, uintptr(unsafe.Pointer(&entries[0])), uintptr(n), uintptr(unsafe.Pointer(&n)), uintptr(wait), 0) == 0 { - mp.blocked = false - errno = int32(getlasterror()) - if errno == _WAIT_TIMEOUT { - return gList{} - } - println("runtime: GetQueuedCompletionStatusEx failed (errno=", errno, ")") - throw("runtime: netpoll failed") - } + n = uint32(len(entries) / int(gomaxprocs)) + if n < 8 { + n = 8 + } + if delay != 0 { + mp.blocked = true + } + if stdcall6(_GetQueuedCompletionStatusEx, iocphandle, uintptr(unsafe.Pointer(&entries[0])), uintptr(n), uintptr(unsafe.Pointer(&n)), uintptr(wait), 0) == 0 { mp.blocked = false - for i = 0; i < n; i++ { - op = entries[i].op - if op != nil { - errno = 0 - qty = 0 - if stdcall5(_WSAGetOverlappedResult, op.pd.fd, uintptr(unsafe.Pointer(op)), uintptr(unsafe.Pointer(&qty)), 0, uintptr(unsafe.Pointer(&flags))) == 0 { - errno = int32(getlasterror()) - } - handlecompletion(&toRun, op, errno, qty) - } else { - if delay == 0 { - // Forward the notification to the - // blocked poller. - netpollBreak() - } - } - } - } else { - op = nil - errno = 0 - qty = 0 - if delay != 0 { - mp.blocked = true + errno = int32(getlasterror()) + if errno == _WAIT_TIMEOUT { + return gList{} } - if stdcall5(_GetQueuedCompletionStatus, iocphandle, uintptr(unsafe.Pointer(&qty)), uintptr(unsafe.Pointer(&key)), uintptr(unsafe.Pointer(&op)), uintptr(wait)) == 0 { - mp.blocked = false - errno = int32(getlasterror()) - if errno == _WAIT_TIMEOUT { - return gList{} - } - if op == nil { - println("runtime: GetQueuedCompletionStatus failed (errno=", errno, ")") - throw("runtime: netpoll failed") + println("runtime: GetQueuedCompletionStatusEx failed (errno=", errno, ")") + throw("runtime: netpoll failed") + } + mp.blocked = false + for i = 0; i < n; i++ { + op = entries[i].op + if op != nil { + errno = 0 + qty = 0 + if stdcall5(_WSAGetOverlappedResult, op.pd.fd, uintptr(unsafe.Pointer(op)), uintptr(unsafe.Pointer(&qty)), 0, uintptr(unsafe.Pointer(&flags))) == 0 { + errno = int32(getlasterror()) } - // dequeued failed IO packet, so report that - } - mp.blocked = false - if op == nil { + handlecompletion(&toRun, op, errno, qty) + } else { + atomic.Store(&netpollWakeSig, 0) if delay == 0 { // Forward the notification to the // blocked poller. netpollBreak() } - return gList{} } - handlecompletion(&toRun, op, errno, qty) } return toRun } func handlecompletion(toRun *gList, op *net_op, errno int32, qty uint32) { - if op == nil { - println("runtime: GetQueuedCompletionStatus returned op == nil") - throw("runtime: netpoll failed") - } mode := op.mode if mode != 'r' && mode != 'w' { - println("runtime: GetQueuedCompletionStatus returned invalid mode=", mode) + println("runtime: GetQueuedCompletionStatusEx returned invalid mode=", mode) throw("runtime: netpoll failed") } op.errno = errno diff --git a/libgo/go/runtime/os_linux_mips64x.go b/libgo/go/runtime/os_linux_mips64x.go index 2b59dcbf17c..f9059382757 100644 --- a/libgo/go/runtime/os_linux_mips64x.go +++ b/libgo/go/runtime/os_linux_mips64x.go @@ -7,5 +7,11 @@ package runtime +import "internal/cpu" + func archauxv(tag, val uintptr) { + switch tag { + case _AT_HWCAP: + cpu.HWCap = uint(val) + } } diff --git a/libgo/go/runtime/panic_test.go b/libgo/go/runtime/panic_test.go new file mode 100644 index 00000000000..b8a300f6b10 --- /dev/null +++ b/libgo/go/runtime/panic_test.go @@ -0,0 +1,48 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime_test + +import ( + "strings" + "testing" +) + +// Test that panics print out the underlying value +// when the underlying kind is directly printable. +// Issue: https://golang.org/issues/37531 +func TestPanicWithDirectlyPrintableCustomTypes(t *testing.T) { + tests := []struct { + name string + wantPanicPrefix string + }{ + {"panicCustomBool", `panic: main.MyBool(true)`}, + {"panicCustomComplex128", `panic: main.MyComplex128(+3.210000e+001+1.000000e+001i)`}, + {"panicCustomComplex64", `panic: main.MyComplex64(+1.100000e-001+3.000000e+000i)`}, + {"panicCustomFloat32", `panic: main.MyFloat32(-9.370000e+001)`}, + {"panicCustomFloat64", `panic: main.MyFloat64(-9.370000e+001)`}, + {"panicCustomInt", `panic: main.MyInt(93)`}, + {"panicCustomInt8", `panic: main.MyInt8(93)`}, + {"panicCustomInt16", `panic: main.MyInt16(93)`}, + {"panicCustomInt32", `panic: main.MyInt32(93)`}, + {"panicCustomInt64", `panic: main.MyInt64(93)`}, + {"panicCustomString", `panic: main.MyString("Panic")`}, + {"panicCustomUint", `panic: main.MyUint(93)`}, + {"panicCustomUint8", `panic: main.MyUint8(93)`}, + {"panicCustomUint16", `panic: main.MyUint16(93)`}, + {"panicCustomUint32", `panic: main.MyUint32(93)`}, + {"panicCustomUint64", `panic: main.MyUint64(93)`}, + {"panicCustomUintptr", `panic: main.MyUintptr(93)`}, + } + + for _, tt := range tests { + t := t + t.Run(tt.name, func(t *testing.T) { + output := runTestProg(t, "testprog", tt.name) + if !strings.HasPrefix(output, tt.wantPanicPrefix) { + t.Fatalf("%q\nis not present in\n%s", tt.wantPanicPrefix, output) + } + }) + } +} diff --git a/libgo/go/runtime/pprof/internal/profile/encode.go b/libgo/go/runtime/pprof/internal/profile/encode.go deleted file mode 100644 index af319330d9a..00000000000 --- a/libgo/go/runtime/pprof/internal/profile/encode.go +++ /dev/null @@ -1,482 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package profile - -import ( - "errors" - "fmt" - "sort" -) - -func (p *Profile) decoder() []decoder { - return profileDecoder -} - -// preEncode populates the unexported fields to be used by encode -// (with suffix X) from the corresponding exported fields. The -// exported fields are cleared up to facilitate testing. -func (p *Profile) preEncode() { - strings := make(map[string]int) - addString(strings, "") - - for _, st := range p.SampleType { - st.typeX = addString(strings, st.Type) - st.unitX = addString(strings, st.Unit) - } - - for _, s := range p.Sample { - s.labelX = nil - var keys []string - for k := range s.Label { - keys = append(keys, k) - } - sort.Strings(keys) - for _, k := range keys { - vs := s.Label[k] - for _, v := range vs { - s.labelX = append(s.labelX, - Label{ - keyX: addString(strings, k), - strX: addString(strings, v), - }, - ) - } - } - var numKeys []string - for k := range s.NumLabel { - numKeys = append(numKeys, k) - } - sort.Strings(numKeys) - for _, k := range numKeys { - vs := s.NumLabel[k] - for _, v := range vs { - s.labelX = append(s.labelX, - Label{ - keyX: addString(strings, k), - numX: v, - }, - ) - } - } - s.locationIDX = nil - for _, l := range s.Location { - s.locationIDX = append(s.locationIDX, l.ID) - } - } - - for _, m := range p.Mapping { - m.fileX = addString(strings, m.File) - m.buildIDX = addString(strings, m.BuildID) - } - - for _, l := range p.Location { - for i, ln := range l.Line { - if ln.Function != nil { - l.Line[i].functionIDX = ln.Function.ID - } else { - l.Line[i].functionIDX = 0 - } - } - if l.Mapping != nil { - l.mappingIDX = l.Mapping.ID - } else { - l.mappingIDX = 0 - } - } - for _, f := range p.Function { - f.nameX = addString(strings, f.Name) - f.systemNameX = addString(strings, f.SystemName) - f.filenameX = addString(strings, f.Filename) - } - - p.dropFramesX = addString(strings, p.DropFrames) - p.keepFramesX = addString(strings, p.KeepFrames) - - if pt := p.PeriodType; pt != nil { - pt.typeX = addString(strings, pt.Type) - pt.unitX = addString(strings, pt.Unit) - } - - p.stringTable = make([]string, len(strings)) - for s, i := range strings { - p.stringTable[i] = s - } -} - -func (p *Profile) encode(b *buffer) { - for _, x := range p.SampleType { - encodeMessage(b, 1, x) - } - for _, x := range p.Sample { - encodeMessage(b, 2, x) - } - for _, x := range p.Mapping { - encodeMessage(b, 3, x) - } - for _, x := range p.Location { - encodeMessage(b, 4, x) - } - for _, x := range p.Function { - encodeMessage(b, 5, x) - } - encodeStrings(b, 6, p.stringTable) - encodeInt64Opt(b, 7, p.dropFramesX) - encodeInt64Opt(b, 8, p.keepFramesX) - encodeInt64Opt(b, 9, p.TimeNanos) - encodeInt64Opt(b, 10, p.DurationNanos) - if pt := p.PeriodType; pt != nil && (pt.typeX != 0 || pt.unitX != 0) { - encodeMessage(b, 11, p.PeriodType) - } - encodeInt64Opt(b, 12, p.Period) -} - -var profileDecoder = []decoder{ - nil, // 0 - // repeated ValueType sample_type = 1 - func(b *buffer, m message) error { - x := new(ValueType) - pp := m.(*Profile) - pp.SampleType = append(pp.SampleType, x) - return decodeMessage(b, x) - }, - // repeated Sample sample = 2 - func(b *buffer, m message) error { - x := new(Sample) - pp := m.(*Profile) - pp.Sample = append(pp.Sample, x) - return decodeMessage(b, x) - }, - // repeated Mapping mapping = 3 - func(b *buffer, m message) error { - x := new(Mapping) - pp := m.(*Profile) - pp.Mapping = append(pp.Mapping, x) - return decodeMessage(b, x) - }, - // repeated Location location = 4 - func(b *buffer, m message) error { - x := new(Location) - pp := m.(*Profile) - pp.Location = append(pp.Location, x) - return decodeMessage(b, x) - }, - // repeated Function function = 5 - func(b *buffer, m message) error { - x := new(Function) - pp := m.(*Profile) - pp.Function = append(pp.Function, x) - return decodeMessage(b, x) - }, - // repeated string string_table = 6 - func(b *buffer, m message) error { - err := decodeStrings(b, &m.(*Profile).stringTable) - if err != nil { - return err - } - if *&m.(*Profile).stringTable[0] != "" { - return errors.New("string_table[0] must be ''") - } - return nil - }, - // repeated int64 drop_frames = 7 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).dropFramesX) }, - // repeated int64 keep_frames = 8 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).keepFramesX) }, - // repeated int64 time_nanos = 9 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).TimeNanos) }, - // repeated int64 duration_nanos = 10 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).DurationNanos) }, - // optional string period_type = 11 - func(b *buffer, m message) error { - x := new(ValueType) - pp := m.(*Profile) - pp.PeriodType = x - return decodeMessage(b, x) - }, - // repeated int64 period = 12 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).Period) }, - // repeated int64 comment = 13 - func(b *buffer, m message) error { return decodeInt64s(b, &m.(*Profile).commentX) }, - // int64 defaultSampleType = 14 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).defaultSampleTypeX) }, -} - -// postDecode takes the unexported fields populated by decode (with -// suffix X) and populates the corresponding exported fields. -// The unexported fields are cleared up to facilitate testing. -func (p *Profile) postDecode() error { - var err error - - mappings := make(map[uint64]*Mapping) - for _, m := range p.Mapping { - m.File, err = getString(p.stringTable, &m.fileX, err) - m.BuildID, err = getString(p.stringTable, &m.buildIDX, err) - mappings[m.ID] = m - } - - functions := make(map[uint64]*Function) - for _, f := range p.Function { - f.Name, err = getString(p.stringTable, &f.nameX, err) - f.SystemName, err = getString(p.stringTable, &f.systemNameX, err) - f.Filename, err = getString(p.stringTable, &f.filenameX, err) - functions[f.ID] = f - } - - locations := make(map[uint64]*Location) - for _, l := range p.Location { - l.Mapping = mappings[l.mappingIDX] - l.mappingIDX = 0 - for i, ln := range l.Line { - if id := ln.functionIDX; id != 0 { - l.Line[i].Function = functions[id] - if l.Line[i].Function == nil { - return fmt.Errorf("Function ID %d not found", id) - } - l.Line[i].functionIDX = 0 - } - } - locations[l.ID] = l - } - - for _, st := range p.SampleType { - st.Type, err = getString(p.stringTable, &st.typeX, err) - st.Unit, err = getString(p.stringTable, &st.unitX, err) - } - - for _, s := range p.Sample { - labels := make(map[string][]string) - numLabels := make(map[string][]int64) - for _, l := range s.labelX { - var key, value string - key, err = getString(p.stringTable, &l.keyX, err) - if l.strX != 0 { - value, err = getString(p.stringTable, &l.strX, err) - labels[key] = append(labels[key], value) - } else { - numLabels[key] = append(numLabels[key], l.numX) - } - } - if len(labels) > 0 { - s.Label = labels - } - if len(numLabels) > 0 { - s.NumLabel = numLabels - } - s.Location = nil - for _, lid := range s.locationIDX { - s.Location = append(s.Location, locations[lid]) - } - s.locationIDX = nil - } - - p.DropFrames, err = getString(p.stringTable, &p.dropFramesX, err) - p.KeepFrames, err = getString(p.stringTable, &p.keepFramesX, err) - - if pt := p.PeriodType; pt == nil { - p.PeriodType = &ValueType{} - } - - if pt := p.PeriodType; pt != nil { - pt.Type, err = getString(p.stringTable, &pt.typeX, err) - pt.Unit, err = getString(p.stringTable, &pt.unitX, err) - } - for _, i := range p.commentX { - var c string - c, err = getString(p.stringTable, &i, err) - p.Comments = append(p.Comments, c) - } - - p.commentX = nil - p.DefaultSampleType, err = getString(p.stringTable, &p.defaultSampleTypeX, err) - p.stringTable = nil - return nil -} - -func (p *ValueType) decoder() []decoder { - return valueTypeDecoder -} - -func (p *ValueType) encode(b *buffer) { - encodeInt64Opt(b, 1, p.typeX) - encodeInt64Opt(b, 2, p.unitX) -} - -var valueTypeDecoder = []decoder{ - nil, // 0 - // optional int64 type = 1 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*ValueType).typeX) }, - // optional int64 unit = 2 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*ValueType).unitX) }, -} - -func (p *Sample) decoder() []decoder { - return sampleDecoder -} - -func (p *Sample) encode(b *buffer) { - encodeUint64s(b, 1, p.locationIDX) - for _, x := range p.Value { - encodeInt64(b, 2, x) - } - for _, x := range p.labelX { - encodeMessage(b, 3, x) - } -} - -var sampleDecoder = []decoder{ - nil, // 0 - // repeated uint64 location = 1 - func(b *buffer, m message) error { return decodeUint64s(b, &m.(*Sample).locationIDX) }, - // repeated int64 value = 2 - func(b *buffer, m message) error { return decodeInt64s(b, &m.(*Sample).Value) }, - // repeated Label label = 3 - func(b *buffer, m message) error { - s := m.(*Sample) - n := len(s.labelX) - s.labelX = append(s.labelX, Label{}) - return decodeMessage(b, &s.labelX[n]) - }, -} - -func (p Label) decoder() []decoder { - return labelDecoder -} - -func (p Label) encode(b *buffer) { - encodeInt64Opt(b, 1, p.keyX) - encodeInt64Opt(b, 2, p.strX) - encodeInt64Opt(b, 3, p.numX) -} - -var labelDecoder = []decoder{ - nil, // 0 - // optional int64 key = 1 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Label).keyX) }, - // optional int64 str = 2 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Label).strX) }, - // optional int64 num = 3 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Label).numX) }, -} - -func (p *Mapping) decoder() []decoder { - return mappingDecoder -} - -func (p *Mapping) encode(b *buffer) { - encodeUint64Opt(b, 1, p.ID) - encodeUint64Opt(b, 2, p.Start) - encodeUint64Opt(b, 3, p.Limit) - encodeUint64Opt(b, 4, p.Offset) - encodeInt64Opt(b, 5, p.fileX) - encodeInt64Opt(b, 6, p.buildIDX) - encodeBoolOpt(b, 7, p.HasFunctions) - encodeBoolOpt(b, 8, p.HasFilenames) - encodeBoolOpt(b, 9, p.HasLineNumbers) - encodeBoolOpt(b, 10, p.HasInlineFrames) -} - -var mappingDecoder = []decoder{ - nil, // 0 - func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).ID) }, // optional uint64 id = 1 - func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Start) }, // optional uint64 memory_offset = 2 - func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Limit) }, // optional uint64 memory_limit = 3 - func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Offset) }, // optional uint64 file_offset = 4 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Mapping).fileX) }, // optional int64 filename = 5 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Mapping).buildIDX) }, // optional int64 build_id = 6 - func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasFunctions) }, // optional bool has_functions = 7 - func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasFilenames) }, // optional bool has_filenames = 8 - func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasLineNumbers) }, // optional bool has_line_numbers = 9 - func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasInlineFrames) }, // optional bool has_inline_frames = 10 -} - -func (p *Location) decoder() []decoder { - return locationDecoder -} - -func (p *Location) encode(b *buffer) { - encodeUint64Opt(b, 1, p.ID) - encodeUint64Opt(b, 2, p.mappingIDX) - encodeUint64Opt(b, 3, p.Address) - for i := range p.Line { - encodeMessage(b, 4, &p.Line[i]) - } -} - -var locationDecoder = []decoder{ - nil, // 0 - func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).ID) }, // optional uint64 id = 1; - func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).mappingIDX) }, // optional uint64 mapping_id = 2; - func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).Address) }, // optional uint64 address = 3; - func(b *buffer, m message) error { // repeated Line line = 4 - pp := m.(*Location) - n := len(pp.Line) - pp.Line = append(pp.Line, Line{}) - return decodeMessage(b, &pp.Line[n]) - }, -} - -func (p *Line) decoder() []decoder { - return lineDecoder -} - -func (p *Line) encode(b *buffer) { - encodeUint64Opt(b, 1, p.functionIDX) - encodeInt64Opt(b, 2, p.Line) -} - -var lineDecoder = []decoder{ - nil, // 0 - // optional uint64 function_id = 1 - func(b *buffer, m message) error { return decodeUint64(b, &m.(*Line).functionIDX) }, - // optional int64 line = 2 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Line).Line) }, -} - -func (p *Function) decoder() []decoder { - return functionDecoder -} - -func (p *Function) encode(b *buffer) { - encodeUint64Opt(b, 1, p.ID) - encodeInt64Opt(b, 2, p.nameX) - encodeInt64Opt(b, 3, p.systemNameX) - encodeInt64Opt(b, 4, p.filenameX) - encodeInt64Opt(b, 5, p.StartLine) -} - -var functionDecoder = []decoder{ - nil, // 0 - // optional uint64 id = 1 - func(b *buffer, m message) error { return decodeUint64(b, &m.(*Function).ID) }, - // optional int64 function_name = 2 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).nameX) }, - // optional int64 function_system_name = 3 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).systemNameX) }, - // repeated int64 filename = 4 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).filenameX) }, - // optional int64 start_line = 5 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).StartLine) }, -} - -func addString(strings map[string]int, s string) int64 { - i, ok := strings[s] - if !ok { - i = len(strings) - strings[s] = i - } - return int64(i) -} - -func getString(strings []string, strng *int64, err error) (string, error) { - if err != nil { - return "", err - } - s := int(*strng) - if s < 0 || s >= len(strings) { - return "", errMalformed - } - *strng = 0 - return strings[s], nil -} diff --git a/libgo/go/runtime/pprof/internal/profile/filter.go b/libgo/go/runtime/pprof/internal/profile/filter.go deleted file mode 100644 index 9cad866df8c..00000000000 --- a/libgo/go/runtime/pprof/internal/profile/filter.go +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Implements methods to filter samples from profiles. - -package profile - -import "regexp" - -// FilterSamplesByName filters the samples in a profile and only keeps -// samples where at least one frame matches focus but none match ignore. -// Returns true is the corresponding regexp matched at least one sample. -func (p *Profile) FilterSamplesByName(focus, ignore, hide *regexp.Regexp) (fm, im, hm bool) { - focusOrIgnore := make(map[uint64]bool) - hidden := make(map[uint64]bool) - for _, l := range p.Location { - if ignore != nil && l.matchesName(ignore) { - im = true - focusOrIgnore[l.ID] = false - } else if focus == nil || l.matchesName(focus) { - fm = true - focusOrIgnore[l.ID] = true - } - if hide != nil && l.matchesName(hide) { - hm = true - l.Line = l.unmatchedLines(hide) - if len(l.Line) == 0 { - hidden[l.ID] = true - } - } - } - - s := make([]*Sample, 0, len(p.Sample)) - for _, sample := range p.Sample { - if focusedAndNotIgnored(sample.Location, focusOrIgnore) { - if len(hidden) > 0 { - var locs []*Location - for _, loc := range sample.Location { - if !hidden[loc.ID] { - locs = append(locs, loc) - } - } - if len(locs) == 0 { - // Remove sample with no locations (by not adding it to s). - continue - } - sample.Location = locs - } - s = append(s, sample) - } - } - p.Sample = s - - return -} - -// matchesName reports whether the function name or file in the -// location matches the regular expression. -func (loc *Location) matchesName(re *regexp.Regexp) bool { - for _, ln := range loc.Line { - if fn := ln.Function; fn != nil { - if re.MatchString(fn.Name) { - return true - } - if re.MatchString(fn.Filename) { - return true - } - } - } - return false -} - -// unmatchedLines returns the lines in the location that do not match -// the regular expression. -func (loc *Location) unmatchedLines(re *regexp.Regexp) []Line { - var lines []Line - for _, ln := range loc.Line { - if fn := ln.Function; fn != nil { - if re.MatchString(fn.Name) { - continue - } - if re.MatchString(fn.Filename) { - continue - } - } - lines = append(lines, ln) - } - return lines -} - -// focusedAndNotIgnored looks up a slice of ids against a map of -// focused/ignored locations. The map only contains locations that are -// explicitly focused or ignored. Returns whether there is at least -// one focused location but no ignored locations. -func focusedAndNotIgnored(locs []*Location, m map[uint64]bool) bool { - var f bool - for _, loc := range locs { - if focus, focusOrIgnore := m[loc.ID]; focusOrIgnore { - if focus { - // Found focused location. Must keep searching in case there - // is an ignored one as well. - f = true - } else { - // Found ignored location. Can return false right away. - return false - } - } - } - return f -} - -// TagMatch selects tags for filtering -type TagMatch func(key, val string, nval int64) bool - -// FilterSamplesByTag removes all samples from the profile, except -// those that match focus and do not match the ignore regular -// expression. -func (p *Profile) FilterSamplesByTag(focus, ignore TagMatch) (fm, im bool) { - samples := make([]*Sample, 0, len(p.Sample)) - for _, s := range p.Sample { - focused, ignored := focusedSample(s, focus, ignore) - fm = fm || focused - im = im || ignored - if focused && !ignored { - samples = append(samples, s) - } - } - p.Sample = samples - return -} - -// focusedTag checks a sample against focus and ignore regexps. -// Returns whether the focus/ignore regexps match any tags -func focusedSample(s *Sample, focus, ignore TagMatch) (fm, im bool) { - fm = focus == nil - for key, vals := range s.Label { - for _, val := range vals { - if ignore != nil && ignore(key, val, 0) { - im = true - } - if !fm && focus(key, val, 0) { - fm = true - } - } - } - for key, vals := range s.NumLabel { - for _, val := range vals { - if ignore != nil && ignore(key, "", val) { - im = true - } - if !fm && focus(key, "", val) { - fm = true - } - } - } - return fm, im -} diff --git a/libgo/go/runtime/pprof/internal/profile/legacy_profile.go b/libgo/go/runtime/pprof/internal/profile/legacy_profile.go deleted file mode 100644 index d69f8deee7c..00000000000 --- a/libgo/go/runtime/pprof/internal/profile/legacy_profile.go +++ /dev/null @@ -1,1266 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements parsers to convert legacy profiles into the -// profile.proto format. - -package profile - -import ( - "bufio" - "bytes" - "fmt" - "io" - "math" - "regexp" - "strconv" - "strings" -) - -var ( - countStartRE = regexp.MustCompile(`\A(\w+) profile: total \d+\n\z`) - countRE = regexp.MustCompile(`\A(\d+) @(( 0x[0-9a-f]+)+)\n\z`) - - heapHeaderRE = regexp.MustCompile(`heap profile: *(\d+): *(\d+) *\[ *(\d+): *(\d+) *\] *@ *(heap[_a-z0-9]*)/?(\d*)`) - heapSampleRE = regexp.MustCompile(`(-?\d+): *(-?\d+) *\[ *(\d+): *(\d+) *] @([ x0-9a-f]*)`) - - contentionSampleRE = regexp.MustCompile(`(\d+) *(\d+) @([ x0-9a-f]*)`) - - hexNumberRE = regexp.MustCompile(`0x[0-9a-f]+`) - - growthHeaderRE = regexp.MustCompile(`heap profile: *(\d+): *(\d+) *\[ *(\d+): *(\d+) *\] @ growthz`) - - fragmentationHeaderRE = regexp.MustCompile(`heap profile: *(\d+): *(\d+) *\[ *(\d+): *(\d+) *\] @ fragmentationz`) - - threadzStartRE = regexp.MustCompile(`--- threadz \d+ ---`) - threadStartRE = regexp.MustCompile(`--- Thread ([[:xdigit:]]+) \(name: (.*)/(\d+)\) stack: ---`) - - procMapsRE = regexp.MustCompile(`([[:xdigit:]]+)-([[:xdigit:]]+)\s+([-rwxp]+)\s+([[:xdigit:]]+)\s+([[:xdigit:]]+):([[:xdigit:]]+)\s+([[:digit:]]+)\s*(\S+)?`) - - briefMapsRE = regexp.MustCompile(`\s*([[:xdigit:]]+)-([[:xdigit:]]+):\s*(\S+)(\s.*@)?([[:xdigit:]]+)?`) - - // LegacyHeapAllocated instructs the heapz parsers to use the - // allocated memory stats instead of the default in-use memory. Note - // that tcmalloc doesn't provide all allocated memory, only in-use - // stats. - LegacyHeapAllocated bool -) - -func isSpaceOrComment(line string) bool { - trimmed := strings.TrimSpace(line) - return len(trimmed) == 0 || trimmed[0] == '#' -} - -// parseGoCount parses a Go count profile (e.g., threadcreate or -// goroutine) and returns a new Profile. -func parseGoCount(b []byte) (*Profile, error) { - r := bytes.NewBuffer(b) - - var line string - var err error - for { - // Skip past comments and empty lines seeking a real header. - line, err = r.ReadString('\n') - if err != nil { - return nil, err - } - if !isSpaceOrComment(line) { - break - } - } - - m := countStartRE.FindStringSubmatch(line) - if m == nil { - return nil, errUnrecognized - } - profileType := m[1] - p := &Profile{ - PeriodType: &ValueType{Type: profileType, Unit: "count"}, - Period: 1, - SampleType: []*ValueType{{Type: profileType, Unit: "count"}}, - } - locations := make(map[uint64]*Location) - for { - line, err = r.ReadString('\n') - if err != nil { - if err == io.EOF { - break - } - return nil, err - } - if isSpaceOrComment(line) { - continue - } - if strings.HasPrefix(line, "---") { - break - } - m := countRE.FindStringSubmatch(line) - if m == nil { - return nil, errMalformed - } - n, err := strconv.ParseInt(m[1], 0, 64) - if err != nil { - return nil, errMalformed - } - fields := strings.Fields(m[2]) - locs := make([]*Location, 0, len(fields)) - for _, stk := range fields { - addr, err := strconv.ParseUint(stk, 0, 64) - if err != nil { - return nil, errMalformed - } - // Adjust all frames by -1 to land on the call instruction. - addr-- - loc := locations[addr] - if loc == nil { - loc = &Location{ - Address: addr, - } - locations[addr] = loc - p.Location = append(p.Location, loc) - } - locs = append(locs, loc) - } - p.Sample = append(p.Sample, &Sample{ - Location: locs, - Value: []int64{n}, - }) - } - - if err = parseAdditionalSections(strings.TrimSpace(line), r, p); err != nil { - return nil, err - } - return p, nil -} - -// remapLocationIDs ensures there is a location for each address -// referenced by a sample, and remaps the samples to point to the new -// location ids. -func (p *Profile) remapLocationIDs() { - seen := make(map[*Location]bool, len(p.Location)) - var locs []*Location - - for _, s := range p.Sample { - for _, l := range s.Location { - if seen[l] { - continue - } - l.ID = uint64(len(locs) + 1) - locs = append(locs, l) - seen[l] = true - } - } - p.Location = locs -} - -func (p *Profile) remapFunctionIDs() { - seen := make(map[*Function]bool, len(p.Function)) - var fns []*Function - - for _, l := range p.Location { - for _, ln := range l.Line { - fn := ln.Function - if fn == nil || seen[fn] { - continue - } - fn.ID = uint64(len(fns) + 1) - fns = append(fns, fn) - seen[fn] = true - } - } - p.Function = fns -} - -// remapMappingIDs matches location addresses with existing mappings -// and updates them appropriately. This is O(N*M), if this ever shows -// up as a bottleneck, evaluate sorting the mappings and doing a -// binary search, which would make it O(N*log(M)). -func (p *Profile) remapMappingIDs() { - if len(p.Mapping) == 0 { - return - } - - // Some profile handlers will incorrectly set regions for the main - // executable if its section is remapped. Fix them through heuristics. - - // Remove the initial mapping if named '/anon_hugepage' and has a - // consecutive adjacent mapping. - if m := p.Mapping[0]; strings.HasPrefix(m.File, "/anon_hugepage") { - if len(p.Mapping) > 1 && m.Limit == p.Mapping[1].Start { - p.Mapping = p.Mapping[1:] - } - } - - // Subtract the offset from the start of the main mapping if it - // ends up at a recognizable start address. - const expectedStart = 0x400000 - if m := p.Mapping[0]; m.Start-m.Offset == expectedStart { - m.Start = expectedStart - m.Offset = 0 - } - - for _, l := range p.Location { - if a := l.Address; a != 0 { - for _, m := range p.Mapping { - if m.Start <= a && a < m.Limit { - l.Mapping = m - break - } - } - } - } - - // Reset all mapping IDs. - for i, m := range p.Mapping { - m.ID = uint64(i + 1) - } -} - -var cpuInts = []func([]byte) (uint64, []byte){ - get32l, - get32b, - get64l, - get64b, -} - -func get32l(b []byte) (uint64, []byte) { - if len(b) < 4 { - return 0, nil - } - return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24, b[4:] -} - -func get32b(b []byte) (uint64, []byte) { - if len(b) < 4 { - return 0, nil - } - return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24, b[4:] -} - -func get64l(b []byte) (uint64, []byte) { - if len(b) < 8 { - return 0, nil - } - return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56, b[8:] -} - -func get64b(b []byte) (uint64, []byte) { - if len(b) < 8 { - return 0, nil - } - return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56, b[8:] -} - -// ParseTracebacks parses a set of tracebacks and returns a newly -// populated profile. It will accept any text file and generate a -// Profile out of it with any hex addresses it can identify, including -// a process map if it can recognize one. Each sample will include a -// tag "source" with the addresses recognized in string format. -func ParseTracebacks(b []byte) (*Profile, error) { - r := bytes.NewBuffer(b) - - p := &Profile{ - PeriodType: &ValueType{Type: "trace", Unit: "count"}, - Period: 1, - SampleType: []*ValueType{ - {Type: "trace", Unit: "count"}, - }, - } - - var sources []string - var sloc []*Location - - locs := make(map[uint64]*Location) - for { - l, err := r.ReadString('\n') - if err != nil { - if err != io.EOF { - return nil, err - } - if l == "" { - break - } - } - if sectionTrigger(l) == memoryMapSection { - break - } - if s, addrs := extractHexAddresses(l); len(s) > 0 { - for _, addr := range addrs { - // Addresses from stack traces point to the next instruction after - // each call. Adjust by -1 to land somewhere on the actual call. - addr-- - loc := locs[addr] - if locs[addr] == nil { - loc = &Location{ - Address: addr, - } - p.Location = append(p.Location, loc) - locs[addr] = loc - } - sloc = append(sloc, loc) - } - - sources = append(sources, s...) - } else { - if len(sources) > 0 || len(sloc) > 0 { - addTracebackSample(sloc, sources, p) - sloc, sources = nil, nil - } - } - } - - // Add final sample to save any leftover data. - if len(sources) > 0 || len(sloc) > 0 { - addTracebackSample(sloc, sources, p) - } - - if err := p.ParseMemoryMap(r); err != nil { - return nil, err - } - return p, nil -} - -func addTracebackSample(l []*Location, s []string, p *Profile) { - p.Sample = append(p.Sample, - &Sample{ - Value: []int64{1}, - Location: l, - Label: map[string][]string{"source": s}, - }) -} - -// parseCPU parses a profilez legacy profile and returns a newly -// populated Profile. -// -// The general format for profilez samples is a sequence of words in -// binary format. The first words are a header with the following data: -// 1st word -- 0 -// 2nd word -- 3 -// 3rd word -- 0 if a c++ application, 1 if a java application. -// 4th word -- Sampling period (in microseconds). -// 5th word -- Padding. -func parseCPU(b []byte) (*Profile, error) { - var parse func([]byte) (uint64, []byte) - var n1, n2, n3, n4, n5 uint64 - for _, parse = range cpuInts { - var tmp []byte - n1, tmp = parse(b) - n2, tmp = parse(tmp) - n3, tmp = parse(tmp) - n4, tmp = parse(tmp) - n5, tmp = parse(tmp) - - if tmp != nil && n1 == 0 && n2 == 3 && n3 == 0 && n4 > 0 && n5 == 0 { - b = tmp - return cpuProfile(b, int64(n4), parse) - } - } - return nil, errUnrecognized -} - -// cpuProfile returns a new Profile from C++ profilez data. -// b is the profile bytes after the header, period is the profiling -// period, and parse is a function to parse 8-byte chunks from the -// profile in its native endianness. -func cpuProfile(b []byte, period int64, parse func(b []byte) (uint64, []byte)) (*Profile, error) { - p := &Profile{ - Period: period * 1000, - PeriodType: &ValueType{Type: "cpu", Unit: "nanoseconds"}, - SampleType: []*ValueType{ - {Type: "samples", Unit: "count"}, - {Type: "cpu", Unit: "nanoseconds"}, - }, - } - var err error - if b, _, err = parseCPUSamples(b, parse, true, p); err != nil { - return nil, err - } - - // If all samples have the same second-to-the-bottom frame, it - // strongly suggests that it is an uninteresting artifact of - // measurement -- a stack frame pushed by the signal handler. The - // bottom frame is always correct as it is picked up from the signal - // structure, not the stack. Check if this is the case and if so, - // remove. - if len(p.Sample) > 1 && len(p.Sample[0].Location) > 1 { - allSame := true - id1 := p.Sample[0].Location[1].Address - for _, s := range p.Sample { - if len(s.Location) < 2 || id1 != s.Location[1].Address { - allSame = false - break - } - } - if allSame { - for _, s := range p.Sample { - s.Location = append(s.Location[:1], s.Location[2:]...) - } - } - } - - if err := p.ParseMemoryMap(bytes.NewBuffer(b)); err != nil { - return nil, err - } - return p, nil -} - -// parseCPUSamples parses a collection of profilez samples from a -// profile. -// -// profilez samples are a repeated sequence of stack frames of the -// form: -// 1st word -- The number of times this stack was encountered. -// 2nd word -- The size of the stack (StackSize). -// 3rd word -- The first address on the stack. -// ... -// StackSize + 2 -- The last address on the stack -// The last stack trace is of the form: -// 1st word -- 0 -// 2nd word -- 1 -// 3rd word -- 0 -// -// Addresses from stack traces may point to the next instruction after -// each call. Optionally adjust by -1 to land somewhere on the actual -// call (except for the leaf, which is not a call). -func parseCPUSamples(b []byte, parse func(b []byte) (uint64, []byte), adjust bool, p *Profile) ([]byte, map[uint64]*Location, error) { - locs := make(map[uint64]*Location) - for len(b) > 0 { - var count, nstk uint64 - count, b = parse(b) - nstk, b = parse(b) - if b == nil || nstk > uint64(len(b)/4) { - return nil, nil, errUnrecognized - } - var sloc []*Location - addrs := make([]uint64, nstk) - for i := 0; i < int(nstk); i++ { - addrs[i], b = parse(b) - } - - if count == 0 && nstk == 1 && addrs[0] == 0 { - // End of data marker - break - } - for i, addr := range addrs { - if adjust && i > 0 { - addr-- - } - loc := locs[addr] - if loc == nil { - loc = &Location{ - Address: addr, - } - locs[addr] = loc - p.Location = append(p.Location, loc) - } - sloc = append(sloc, loc) - } - p.Sample = append(p.Sample, - &Sample{ - Value: []int64{int64(count), int64(count) * p.Period}, - Location: sloc, - }) - } - // Reached the end without finding the EOD marker. - return b, locs, nil -} - -// parseHeap parses a heapz legacy or a growthz profile and -// returns a newly populated Profile. -func parseHeap(b []byte) (p *Profile, err error) { - r := bytes.NewBuffer(b) - l, err := r.ReadString('\n') - if err != nil { - return nil, errUnrecognized - } - - sampling := "" - - if header := heapHeaderRE.FindStringSubmatch(l); header != nil { - p = &Profile{ - SampleType: []*ValueType{ - {Type: "objects", Unit: "count"}, - {Type: "space", Unit: "bytes"}, - }, - PeriodType: &ValueType{Type: "objects", Unit: "bytes"}, - } - - var period int64 - if len(header[6]) > 0 { - if period, err = strconv.ParseInt(header[6], 10, 64); err != nil { - return nil, errUnrecognized - } - } - - switch header[5] { - case "heapz_v2", "heap_v2": - sampling, p.Period = "v2", period - case "heapprofile": - sampling, p.Period = "", 1 - case "heap": - sampling, p.Period = "v2", period/2 - default: - return nil, errUnrecognized - } - } else if header = growthHeaderRE.FindStringSubmatch(l); header != nil { - p = &Profile{ - SampleType: []*ValueType{ - {Type: "objects", Unit: "count"}, - {Type: "space", Unit: "bytes"}, - }, - PeriodType: &ValueType{Type: "heapgrowth", Unit: "count"}, - Period: 1, - } - } else if header = fragmentationHeaderRE.FindStringSubmatch(l); header != nil { - p = &Profile{ - SampleType: []*ValueType{ - {Type: "objects", Unit: "count"}, - {Type: "space", Unit: "bytes"}, - }, - PeriodType: &ValueType{Type: "allocations", Unit: "count"}, - Period: 1, - } - } else { - return nil, errUnrecognized - } - - if LegacyHeapAllocated { - for _, st := range p.SampleType { - st.Type = "alloc_" + st.Type - } - } else { - for _, st := range p.SampleType { - st.Type = "inuse_" + st.Type - } - } - - locs := make(map[uint64]*Location) - for { - l, err = r.ReadString('\n') - if err != nil { - if err != io.EOF { - return nil, err - } - - if l == "" { - break - } - } - - if isSpaceOrComment(l) { - continue - } - l = strings.TrimSpace(l) - - if sectionTrigger(l) != unrecognizedSection { - break - } - - value, blocksize, addrs, err := parseHeapSample(l, p.Period, sampling) - if err != nil { - return nil, err - } - var sloc []*Location - for _, addr := range addrs { - // Addresses from stack traces point to the next instruction after - // each call. Adjust by -1 to land somewhere on the actual call. - addr-- - loc := locs[addr] - if locs[addr] == nil { - loc = &Location{ - Address: addr, - } - p.Location = append(p.Location, loc) - locs[addr] = loc - } - sloc = append(sloc, loc) - } - - p.Sample = append(p.Sample, &Sample{ - Value: value, - Location: sloc, - NumLabel: map[string][]int64{"bytes": {blocksize}}, - }) - } - - if err = parseAdditionalSections(l, r, p); err != nil { - return nil, err - } - return p, nil -} - -// parseHeapSample parses a single row from a heap profile into a new Sample. -func parseHeapSample(line string, rate int64, sampling string) (value []int64, blocksize int64, addrs []uint64, err error) { - sampleData := heapSampleRE.FindStringSubmatch(line) - if len(sampleData) != 6 { - return value, blocksize, addrs, fmt.Errorf("unexpected number of sample values: got %d, want 6", len(sampleData)) - } - - // Use first two values by default; tcmalloc sampling generates the - // same value for both, only the older heap-profile collect separate - // stats for in-use and allocated objects. - valueIndex := 1 - if LegacyHeapAllocated { - valueIndex = 3 - } - - var v1, v2 int64 - if v1, err = strconv.ParseInt(sampleData[valueIndex], 10, 64); err != nil { - return value, blocksize, addrs, fmt.Errorf("malformed sample: %s: %v", line, err) - } - if v2, err = strconv.ParseInt(sampleData[valueIndex+1], 10, 64); err != nil { - return value, blocksize, addrs, fmt.Errorf("malformed sample: %s: %v", line, err) - } - - if v1 == 0 { - if v2 != 0 { - return value, blocksize, addrs, fmt.Errorf("allocation count was 0 but allocation bytes was %d", v2) - } - } else { - blocksize = v2 / v1 - if sampling == "v2" { - v1, v2 = scaleHeapSample(v1, v2, rate) - } - } - - value = []int64{v1, v2} - addrs = parseHexAddresses(sampleData[5]) - - return value, blocksize, addrs, nil -} - -// extractHexAddresses extracts hex numbers from a string and returns -// them, together with their numeric value, in a slice. -func extractHexAddresses(s string) ([]string, []uint64) { - hexStrings := hexNumberRE.FindAllString(s, -1) - var ids []uint64 - for _, s := range hexStrings { - if id, err := strconv.ParseUint(s, 0, 64); err == nil { - ids = append(ids, id) - } else { - // Do not expect any parsing failures due to the regexp matching. - panic("failed to parse hex value:" + s) - } - } - return hexStrings, ids -} - -// parseHexAddresses parses hex numbers from a string and returns them -// in a slice. -func parseHexAddresses(s string) []uint64 { - _, ids := extractHexAddresses(s) - return ids -} - -// scaleHeapSample adjusts the data from a heapz Sample to -// account for its probability of appearing in the collected -// data. heapz profiles are a sampling of the memory allocations -// requests in a program. We estimate the unsampled value by dividing -// each collected sample by its probability of appearing in the -// profile. heapz v2 profiles rely on a poisson process to determine -// which samples to collect, based on the desired average collection -// rate R. The probability of a sample of size S to appear in that -// profile is 1-exp(-S/R). -func scaleHeapSample(count, size, rate int64) (int64, int64) { - if count == 0 || size == 0 { - return 0, 0 - } - - if rate <= 1 { - // if rate==1 all samples were collected so no adjustment is needed. - // if rate<1 treat as unknown and skip scaling. - return count, size - } - - avgSize := float64(size) / float64(count) - scale := 1 / (1 - math.Exp(-avgSize/float64(rate))) - - return int64(float64(count) * scale), int64(float64(size) * scale) -} - -// parseContention parses a mutex or contention profile. There are 2 cases: -// "--- contentionz " for legacy C++ profiles (and backwards compatibility) -// "--- mutex:" or "--- contention:" for profiles generated by the Go runtime. -// This code converts the text output from runtime into a *Profile. (In the future -// the runtime might write a serialized Profile directly making this unnecessary.) -func parseContention(b []byte) (*Profile, error) { - r := bytes.NewBuffer(b) - var l string - var err error - for { - // Skip past comments and empty lines seeking a real header. - l, err = r.ReadString('\n') - if err != nil { - return nil, err - } - if !isSpaceOrComment(l) { - break - } - } - - if strings.HasPrefix(l, "--- contentionz ") { - return parseCppContention(r) - } else if strings.HasPrefix(l, "--- mutex:") { - return parseCppContention(r) - } else if strings.HasPrefix(l, "--- contention:") { - return parseCppContention(r) - } - return nil, errUnrecognized -} - -// parseCppContention parses the output from synchronization_profiling.cc -// for backward compatibility, and the compatible (non-debug) block profile -// output from the Go runtime. -func parseCppContention(r *bytes.Buffer) (*Profile, error) { - p := &Profile{ - PeriodType: &ValueType{Type: "contentions", Unit: "count"}, - Period: 1, - SampleType: []*ValueType{ - {Type: "contentions", Unit: "count"}, - {Type: "delay", Unit: "nanoseconds"}, - }, - } - - var cpuHz int64 - var l string - var err error - // Parse text of the form "attribute = value" before the samples. - const delimiter = "=" - for { - l, err = r.ReadString('\n') - if err != nil { - if err != io.EOF { - return nil, err - } - - if l == "" { - break - } - } - if isSpaceOrComment(l) { - continue - } - - if l = strings.TrimSpace(l); l == "" { - continue - } - - if strings.HasPrefix(l, "---") { - break - } - - attr := strings.SplitN(l, delimiter, 2) - if len(attr) != 2 { - break - } - key, val := strings.TrimSpace(attr[0]), strings.TrimSpace(attr[1]) - var err error - switch key { - case "cycles/second": - if cpuHz, err = strconv.ParseInt(val, 0, 64); err != nil { - return nil, errUnrecognized - } - case "sampling period": - if p.Period, err = strconv.ParseInt(val, 0, 64); err != nil { - return nil, errUnrecognized - } - case "ms since reset": - ms, err := strconv.ParseInt(val, 0, 64) - if err != nil { - return nil, errUnrecognized - } - p.DurationNanos = ms * 1000 * 1000 - case "format": - // CPP contentionz profiles don't have format. - return nil, errUnrecognized - case "resolution": - // CPP contentionz profiles don't have resolution. - return nil, errUnrecognized - case "discarded samples": - default: - return nil, errUnrecognized - } - } - - locs := make(map[uint64]*Location) - for { - if !isSpaceOrComment(l) { - if l = strings.TrimSpace(l); strings.HasPrefix(l, "---") { - break - } - value, addrs, err := parseContentionSample(l, p.Period, cpuHz) - if err != nil { - return nil, err - } - var sloc []*Location - for _, addr := range addrs { - // Addresses from stack traces point to the next instruction after - // each call. Adjust by -1 to land somewhere on the actual call. - addr-- - loc := locs[addr] - if locs[addr] == nil { - loc = &Location{ - Address: addr, - } - p.Location = append(p.Location, loc) - locs[addr] = loc - } - sloc = append(sloc, loc) - } - p.Sample = append(p.Sample, &Sample{ - Value: value, - Location: sloc, - }) - } - - if l, err = r.ReadString('\n'); err != nil { - if err != io.EOF { - return nil, err - } - if l == "" { - break - } - } - } - - if err = parseAdditionalSections(l, r, p); err != nil { - return nil, err - } - - return p, nil -} - -// parseContentionSample parses a single row from a contention profile -// into a new Sample. -func parseContentionSample(line string, period, cpuHz int64) (value []int64, addrs []uint64, err error) { - sampleData := contentionSampleRE.FindStringSubmatch(line) - if sampleData == nil { - return value, addrs, errUnrecognized - } - - v1, err := strconv.ParseInt(sampleData[1], 10, 64) - if err != nil { - return value, addrs, fmt.Errorf("malformed sample: %s: %v", line, err) - } - v2, err := strconv.ParseInt(sampleData[2], 10, 64) - if err != nil { - return value, addrs, fmt.Errorf("malformed sample: %s: %v", line, err) - } - - // Unsample values if period and cpuHz are available. - // - Delays are scaled to cycles and then to nanoseconds. - // - Contentions are scaled to cycles. - if period > 0 { - if cpuHz > 0 { - cpuGHz := float64(cpuHz) / 1e9 - v1 = int64(float64(v1) * float64(period) / cpuGHz) - } - v2 = v2 * period - } - - value = []int64{v2, v1} - addrs = parseHexAddresses(sampleData[3]) - - return value, addrs, nil -} - -// parseThread parses a Threadz profile and returns a new Profile. -func parseThread(b []byte) (*Profile, error) { - r := bytes.NewBuffer(b) - - var line string - var err error - for { - // Skip past comments and empty lines seeking a real header. - line, err = r.ReadString('\n') - if err != nil { - return nil, err - } - if !isSpaceOrComment(line) { - break - } - } - - if m := threadzStartRE.FindStringSubmatch(line); m != nil { - // Advance over initial comments until first stack trace. - for { - line, err = r.ReadString('\n') - if err != nil { - if err != io.EOF { - return nil, err - } - - if line == "" { - break - } - } - if sectionTrigger(line) != unrecognizedSection || line[0] == '-' { - break - } - } - } else if t := threadStartRE.FindStringSubmatch(line); len(t) != 4 { - return nil, errUnrecognized - } - - p := &Profile{ - SampleType: []*ValueType{{Type: "thread", Unit: "count"}}, - PeriodType: &ValueType{Type: "thread", Unit: "count"}, - Period: 1, - } - - locs := make(map[uint64]*Location) - // Recognize each thread and populate profile samples. - for sectionTrigger(line) == unrecognizedSection { - if strings.HasPrefix(line, "---- no stack trace for") { - line = "" - break - } - if t := threadStartRE.FindStringSubmatch(line); len(t) != 4 { - return nil, errUnrecognized - } - - var addrs []uint64 - line, addrs, err = parseThreadSample(r) - if err != nil { - return nil, errUnrecognized - } - if len(addrs) == 0 { - // We got a --same as previous threads--. Bump counters. - if len(p.Sample) > 0 { - s := p.Sample[len(p.Sample)-1] - s.Value[0]++ - } - continue - } - - var sloc []*Location - for _, addr := range addrs { - // Addresses from stack traces point to the next instruction after - // each call. Adjust by -1 to land somewhere on the actual call. - addr-- - loc := locs[addr] - if locs[addr] == nil { - loc = &Location{ - Address: addr, - } - p.Location = append(p.Location, loc) - locs[addr] = loc - } - sloc = append(sloc, loc) - } - - p.Sample = append(p.Sample, &Sample{ - Value: []int64{1}, - Location: sloc, - }) - } - - if err = parseAdditionalSections(line, r, p); err != nil { - return nil, err - } - - return p, nil -} - -// parseThreadSample parses a symbolized or unsymbolized stack trace. -// Returns the first line after the traceback, the sample (or nil if -// it hits a 'same-as-previous' marker) and an error. -func parseThreadSample(b *bytes.Buffer) (nextl string, addrs []uint64, err error) { - var l string - sameAsPrevious := false - for { - if l, err = b.ReadString('\n'); err != nil { - if err != io.EOF { - return "", nil, err - } - if l == "" { - break - } - } - if l = strings.TrimSpace(l); l == "" { - continue - } - - if strings.HasPrefix(l, "---") { - break - } - if strings.Contains(l, "same as previous thread") { - sameAsPrevious = true - continue - } - - addrs = append(addrs, parseHexAddresses(l)...) - } - - if sameAsPrevious { - return l, nil, nil - } - return l, addrs, nil -} - -// parseAdditionalSections parses any additional sections in the -// profile, ignoring any unrecognized sections. -func parseAdditionalSections(l string, b *bytes.Buffer, p *Profile) (err error) { - for { - if sectionTrigger(l) == memoryMapSection { - break - } - // Ignore any unrecognized sections. - if l, err := b.ReadString('\n'); err != nil { - if err != io.EOF { - return err - } - if l == "" { - break - } - } - } - return p.ParseMemoryMap(b) -} - -// ParseMemoryMap parses a memory map in the format of -// /proc/self/maps, and overrides the mappings in the current profile. -// It renumbers the samples and locations in the profile correspondingly. -func (p *Profile) ParseMemoryMap(rd io.Reader) error { - b := bufio.NewReader(rd) - - var attrs []string - var r *strings.Replacer - const delimiter = "=" - for { - l, err := b.ReadString('\n') - if err != nil { - if err != io.EOF { - return err - } - if l == "" { - break - } - } - if l = strings.TrimSpace(l); l == "" { - continue - } - - if r != nil { - l = r.Replace(l) - } - m, err := parseMappingEntry(l) - if err != nil { - if err == errUnrecognized { - // Recognize assignments of the form: attr=value, and replace - // $attr with value on subsequent mappings. - if attr := strings.SplitN(l, delimiter, 2); len(attr) == 2 { - attrs = append(attrs, "$"+strings.TrimSpace(attr[0]), strings.TrimSpace(attr[1])) - r = strings.NewReplacer(attrs...) - } - // Ignore any unrecognized entries - continue - } - return err - } - if m == nil || (m.File == "" && len(p.Mapping) != 0) { - // In some cases the first entry may include the address range - // but not the name of the file. It should be followed by - // another entry with the name. - continue - } - if len(p.Mapping) == 1 && p.Mapping[0].File == "" { - // Update the name if this is the entry following that empty one. - p.Mapping[0].File = m.File - continue - } - p.Mapping = append(p.Mapping, m) - } - p.remapLocationIDs() - p.remapFunctionIDs() - p.remapMappingIDs() - return nil -} - -func parseMappingEntry(l string) (*Mapping, error) { - mapping := &Mapping{} - var err error - if me := procMapsRE.FindStringSubmatch(l); len(me) == 9 { - if !strings.Contains(me[3], "x") { - // Skip non-executable entries. - return nil, nil - } - if mapping.Start, err = strconv.ParseUint(me[1], 16, 64); err != nil { - return nil, errUnrecognized - } - if mapping.Limit, err = strconv.ParseUint(me[2], 16, 64); err != nil { - return nil, errUnrecognized - } - if me[4] != "" { - if mapping.Offset, err = strconv.ParseUint(me[4], 16, 64); err != nil { - return nil, errUnrecognized - } - } - mapping.File = me[8] - return mapping, nil - } - - if me := briefMapsRE.FindStringSubmatch(l); len(me) == 6 { - if mapping.Start, err = strconv.ParseUint(me[1], 16, 64); err != nil { - return nil, errUnrecognized - } - if mapping.Limit, err = strconv.ParseUint(me[2], 16, 64); err != nil { - return nil, errUnrecognized - } - mapping.File = me[3] - if me[5] != "" { - if mapping.Offset, err = strconv.ParseUint(me[5], 16, 64); err != nil { - return nil, errUnrecognized - } - } - return mapping, nil - } - - return nil, errUnrecognized -} - -type sectionType int - -const ( - unrecognizedSection sectionType = iota - memoryMapSection -) - -var memoryMapTriggers = []string{ - "--- Memory map: ---", - "MAPPED_LIBRARIES:", -} - -func sectionTrigger(line string) sectionType { - for _, trigger := range memoryMapTriggers { - if strings.Contains(line, trigger) { - return memoryMapSection - } - } - return unrecognizedSection -} - -func (p *Profile) addLegacyFrameInfo() { - switch { - case isProfileType(p, heapzSampleTypes) || - isProfileType(p, heapzInUseSampleTypes) || - isProfileType(p, heapzAllocSampleTypes): - p.DropFrames, p.KeepFrames = allocRxStr, allocSkipRxStr - case isProfileType(p, contentionzSampleTypes): - p.DropFrames, p.KeepFrames = lockRxStr, "" - default: - p.DropFrames, p.KeepFrames = cpuProfilerRxStr, "" - } -} - -var heapzSampleTypes = []string{"allocations", "size"} // early Go pprof profiles -var heapzInUseSampleTypes = []string{"inuse_objects", "inuse_space"} -var heapzAllocSampleTypes = []string{"alloc_objects", "alloc_space"} -var contentionzSampleTypes = []string{"contentions", "delay"} - -func isProfileType(p *Profile, t []string) bool { - st := p.SampleType - if len(st) != len(t) { - return false - } - - for i := range st { - if st[i].Type != t[i] { - return false - } - } - return true -} - -var allocRxStr = strings.Join([]string{ - // POSIX entry points. - `calloc`, - `cfree`, - `malloc`, - `free`, - `memalign`, - `do_memalign`, - `(__)?posix_memalign`, - `pvalloc`, - `valloc`, - `realloc`, - - // TC malloc. - `tcmalloc::.*`, - `tc_calloc`, - `tc_cfree`, - `tc_malloc`, - `tc_free`, - `tc_memalign`, - `tc_posix_memalign`, - `tc_pvalloc`, - `tc_valloc`, - `tc_realloc`, - `tc_new`, - `tc_delete`, - `tc_newarray`, - `tc_deletearray`, - `tc_new_nothrow`, - `tc_newarray_nothrow`, - - // Memory-allocation routines on OS X. - `malloc_zone_malloc`, - `malloc_zone_calloc`, - `malloc_zone_valloc`, - `malloc_zone_realloc`, - `malloc_zone_memalign`, - `malloc_zone_free`, - - // Go runtime - `runtime\..*`, - - // Other misc. memory allocation routines - `BaseArena::.*`, - `(::)?do_malloc_no_errno`, - `(::)?do_malloc_pages`, - `(::)?do_malloc`, - `DoSampledAllocation`, - `MallocedMemBlock::MallocedMemBlock`, - `_M_allocate`, - `__builtin_(vec_)?delete`, - `__builtin_(vec_)?new`, - `__gnu_cxx::new_allocator::allocate`, - `__libc_malloc`, - `__malloc_alloc_template::allocate`, - `allocate`, - `cpp_alloc`, - `operator new(\[\])?`, - `simple_alloc::allocate`, -}, `|`) - -var allocSkipRxStr = strings.Join([]string{ - // Preserve Go runtime frames that appear in the middle/bottom of - // the stack. - `runtime\.panic`, - `runtime\.reflectcall`, - `runtime\.call[0-9]*`, -}, `|`) - -var cpuProfilerRxStr = strings.Join([]string{ - `ProfileData::Add`, - `ProfileData::prof_handler`, - `CpuProfiler::prof_handler`, - `__pthread_sighandler`, - `__restore`, -}, `|`) - -var lockRxStr = strings.Join([]string{ - `RecordLockProfileData`, - `(base::)?RecordLockProfileData.*`, - `(base::)?SubmitMutexProfileData.*`, - `(base::)?SubmitSpinLockProfileData.*`, - `(Mutex::)?AwaitCommon.*`, - `(Mutex::)?Unlock.*`, - `(Mutex::)?UnlockSlow.*`, - `(Mutex::)?ReaderUnlock.*`, - `(MutexLock::)?~MutexLock.*`, - `(SpinLock::)?Unlock.*`, - `(SpinLock::)?SlowUnlock.*`, - `(SpinLockHolder::)?~SpinLockHolder.*`, -}, `|`) diff --git a/libgo/go/runtime/pprof/internal/profile/profile.go b/libgo/go/runtime/pprof/internal/profile/profile.go deleted file mode 100644 index 443accdd6d3..00000000000 --- a/libgo/go/runtime/pprof/internal/profile/profile.go +++ /dev/null @@ -1,577 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package profile provides a representation of profile.proto and -// methods to encode/decode profiles in this format. -// -// This package is only for testing runtime/pprof. -// It is not used by production Go programs. -package profile - -import ( - "bytes" - "compress/gzip" - "fmt" - "io" - "io/ioutil" - "regexp" - "strings" - "time" -) - -// Profile is an in-memory representation of profile.proto. -type Profile struct { - SampleType []*ValueType - DefaultSampleType string - Sample []*Sample - Mapping []*Mapping - Location []*Location - Function []*Function - Comments []string - - DropFrames string - KeepFrames string - - TimeNanos int64 - DurationNanos int64 - PeriodType *ValueType - Period int64 - - commentX []int64 - dropFramesX int64 - keepFramesX int64 - stringTable []string - defaultSampleTypeX int64 -} - -// ValueType corresponds to Profile.ValueType -type ValueType struct { - Type string // cpu, wall, inuse_space, etc - Unit string // seconds, nanoseconds, bytes, etc - - typeX int64 - unitX int64 -} - -// Sample corresponds to Profile.Sample -type Sample struct { - Location []*Location - Value []int64 - Label map[string][]string - NumLabel map[string][]int64 - - locationIDX []uint64 - labelX []Label -} - -// Label corresponds to Profile.Label -type Label struct { - keyX int64 - // Exactly one of the two following values must be set - strX int64 - numX int64 // Integer value for this label -} - -// Mapping corresponds to Profile.Mapping -type Mapping struct { - ID uint64 - Start uint64 - Limit uint64 - Offset uint64 - File string - BuildID string - HasFunctions bool - HasFilenames bool - HasLineNumbers bool - HasInlineFrames bool - - fileX int64 - buildIDX int64 -} - -// Location corresponds to Profile.Location -type Location struct { - ID uint64 - Mapping *Mapping - Address uint64 - Line []Line - - mappingIDX uint64 -} - -// Line corresponds to Profile.Line -type Line struct { - Function *Function - Line int64 - - functionIDX uint64 -} - -// Function corresponds to Profile.Function -type Function struct { - ID uint64 - Name string - SystemName string - Filename string - StartLine int64 - - nameX int64 - systemNameX int64 - filenameX int64 -} - -// Parse parses a profile and checks for its validity. The input -// may be a gzip-compressed encoded protobuf or one of many legacy -// profile formats which may be unsupported in the future. -func Parse(r io.Reader) (*Profile, error) { - orig, err := ioutil.ReadAll(r) - if err != nil { - return nil, err - } - - var p *Profile - if len(orig) >= 2 && orig[0] == 0x1f && orig[1] == 0x8b { - gz, err := gzip.NewReader(bytes.NewBuffer(orig)) - if err != nil { - return nil, fmt.Errorf("decompressing profile: %v", err) - } - data, err := ioutil.ReadAll(gz) - if err != nil { - return nil, fmt.Errorf("decompressing profile: %v", err) - } - orig = data - } - if p, err = parseUncompressed(orig); err != nil { - if p, err = parseLegacy(orig); err != nil { - return nil, fmt.Errorf("parsing profile: %v", err) - } - } - - if err := p.CheckValid(); err != nil { - return nil, fmt.Errorf("malformed profile: %v", err) - } - return p, nil -} - -var errUnrecognized = fmt.Errorf("unrecognized profile format") -var errMalformed = fmt.Errorf("malformed profile format") - -func parseLegacy(data []byte) (*Profile, error) { - parsers := []func([]byte) (*Profile, error){ - parseCPU, - parseHeap, - parseGoCount, // goroutine, threadcreate - parseThread, - parseContention, - } - - for _, parser := range parsers { - p, err := parser(data) - if err == nil { - p.setMain() - p.addLegacyFrameInfo() - return p, nil - } - if err != errUnrecognized { - return nil, err - } - } - return nil, errUnrecognized -} - -func parseUncompressed(data []byte) (*Profile, error) { - p := &Profile{} - if err := unmarshal(data, p); err != nil { - return nil, err - } - - if err := p.postDecode(); err != nil { - return nil, err - } - - return p, nil -} - -var libRx = regexp.MustCompile(`([.]so$|[.]so[._][0-9]+)`) - -// setMain scans Mapping entries and guesses which entry is main -// because legacy profiles don't obey the convention of putting main -// first. -func (p *Profile) setMain() { - for i := 0; i < len(p.Mapping); i++ { - file := strings.TrimSpace(strings.ReplaceAll(p.Mapping[i].File, "(deleted)", "")) - if len(file) == 0 { - continue - } - if len(libRx.FindStringSubmatch(file)) > 0 { - continue - } - if strings.HasPrefix(file, "[") { - continue - } - // Swap what we guess is main to position 0. - p.Mapping[i], p.Mapping[0] = p.Mapping[0], p.Mapping[i] - break - } -} - -// Write writes the profile as a gzip-compressed marshaled protobuf. -func (p *Profile) Write(w io.Writer) error { - p.preEncode() - b := marshal(p) - zw := gzip.NewWriter(w) - defer zw.Close() - _, err := zw.Write(b) - return err -} - -// CheckValid tests whether the profile is valid. Checks include, but are -// not limited to: -// - len(Profile.Sample[n].value) == len(Profile.value_unit) -// - Sample.id has a corresponding Profile.Location -func (p *Profile) CheckValid() error { - // Check that sample values are consistent - sampleLen := len(p.SampleType) - if sampleLen == 0 && len(p.Sample) != 0 { - return fmt.Errorf("missing sample type information") - } - for _, s := range p.Sample { - if len(s.Value) != sampleLen { - return fmt.Errorf("mismatch: sample has: %d values vs. %d types", len(s.Value), len(p.SampleType)) - } - } - - // Check that all mappings/locations/functions are in the tables - // Check that there are no duplicate ids - mappings := make(map[uint64]*Mapping, len(p.Mapping)) - for _, m := range p.Mapping { - if m.ID == 0 { - return fmt.Errorf("found mapping with reserved ID=0") - } - if mappings[m.ID] != nil { - return fmt.Errorf("multiple mappings with same id: %d", m.ID) - } - mappings[m.ID] = m - } - functions := make(map[uint64]*Function, len(p.Function)) - for _, f := range p.Function { - if f.ID == 0 { - return fmt.Errorf("found function with reserved ID=0") - } - if functions[f.ID] != nil { - return fmt.Errorf("multiple functions with same id: %d", f.ID) - } - functions[f.ID] = f - } - locations := make(map[uint64]*Location, len(p.Location)) - for _, l := range p.Location { - if l.ID == 0 { - return fmt.Errorf("found location with reserved id=0") - } - if locations[l.ID] != nil { - return fmt.Errorf("multiple locations with same id: %d", l.ID) - } - locations[l.ID] = l - if m := l.Mapping; m != nil { - if m.ID == 0 || mappings[m.ID] != m { - return fmt.Errorf("inconsistent mapping %p: %d", m, m.ID) - } - } - for _, ln := range l.Line { - if f := ln.Function; f != nil { - if f.ID == 0 || functions[f.ID] != f { - return fmt.Errorf("inconsistent function %p: %d", f, f.ID) - } - } - } - } - return nil -} - -// Aggregate merges the locations in the profile into equivalence -// classes preserving the request attributes. It also updates the -// samples to point to the merged locations. -func (p *Profile) Aggregate(inlineFrame, function, filename, linenumber, address bool) error { - for _, m := range p.Mapping { - m.HasInlineFrames = m.HasInlineFrames && inlineFrame - m.HasFunctions = m.HasFunctions && function - m.HasFilenames = m.HasFilenames && filename - m.HasLineNumbers = m.HasLineNumbers && linenumber - } - - // Aggregate functions - if !function || !filename { - for _, f := range p.Function { - if !function { - f.Name = "" - f.SystemName = "" - } - if !filename { - f.Filename = "" - } - } - } - - // Aggregate locations - if !inlineFrame || !address || !linenumber { - for _, l := range p.Location { - if !inlineFrame && len(l.Line) > 1 { - l.Line = l.Line[len(l.Line)-1:] - } - if !linenumber { - for i := range l.Line { - l.Line[i].Line = 0 - } - } - if !address { - l.Address = 0 - } - } - } - - return p.CheckValid() -} - -// Print dumps a text representation of a profile. Intended mainly -// for debugging purposes. -func (p *Profile) String() string { - - ss := make([]string, 0, len(p.Sample)+len(p.Mapping)+len(p.Location)) - if pt := p.PeriodType; pt != nil { - ss = append(ss, fmt.Sprintf("PeriodType: %s %s", pt.Type, pt.Unit)) - } - ss = append(ss, fmt.Sprintf("Period: %d", p.Period)) - if p.TimeNanos != 0 { - ss = append(ss, fmt.Sprintf("Time: %v", time.Unix(0, p.TimeNanos))) - } - if p.DurationNanos != 0 { - ss = append(ss, fmt.Sprintf("Duration: %v", time.Duration(p.DurationNanos))) - } - - ss = append(ss, "Samples:") - var sh1 string - for _, s := range p.SampleType { - sh1 = sh1 + fmt.Sprintf("%s/%s ", s.Type, s.Unit) - } - ss = append(ss, strings.TrimSpace(sh1)) - for _, s := range p.Sample { - var sv string - for _, v := range s.Value { - sv = fmt.Sprintf("%s %10d", sv, v) - } - sv = sv + ": " - for _, l := range s.Location { - sv = sv + fmt.Sprintf("%d ", l.ID) - } - ss = append(ss, sv) - const labelHeader = " " - if len(s.Label) > 0 { - ls := labelHeader - for k, v := range s.Label { - ls = ls + fmt.Sprintf("%s:%v ", k, v) - } - ss = append(ss, ls) - } - if len(s.NumLabel) > 0 { - ls := labelHeader - for k, v := range s.NumLabel { - ls = ls + fmt.Sprintf("%s:%v ", k, v) - } - ss = append(ss, ls) - } - } - - ss = append(ss, "Locations") - for _, l := range p.Location { - locStr := fmt.Sprintf("%6d: %#x ", l.ID, l.Address) - if m := l.Mapping; m != nil { - locStr = locStr + fmt.Sprintf("M=%d ", m.ID) - } - if len(l.Line) == 0 { - ss = append(ss, locStr) - } - for li := range l.Line { - lnStr := "??" - if fn := l.Line[li].Function; fn != nil { - lnStr = fmt.Sprintf("%s %s:%d s=%d", - fn.Name, - fn.Filename, - l.Line[li].Line, - fn.StartLine) - if fn.Name != fn.SystemName { - lnStr = lnStr + "(" + fn.SystemName + ")" - } - } - ss = append(ss, locStr+lnStr) - // Do not print location details past the first line - locStr = " " - } - } - - ss = append(ss, "Mappings") - for _, m := range p.Mapping { - bits := "" - if m.HasFunctions { - bits += "[FN]" - } - if m.HasFilenames { - bits += "[FL]" - } - if m.HasLineNumbers { - bits += "[LN]" - } - if m.HasInlineFrames { - bits += "[IN]" - } - ss = append(ss, fmt.Sprintf("%d: %#x/%#x/%#x %s %s %s", - m.ID, - m.Start, m.Limit, m.Offset, - m.File, - m.BuildID, - bits)) - } - - return strings.Join(ss, "\n") + "\n" -} - -// Merge adds profile p adjusted by ratio r into profile p. Profiles -// must be compatible (same Type and SampleType). -// TODO(rsilvera): consider normalizing the profiles based on the -// total samples collected. -func (p *Profile) Merge(pb *Profile, r float64) error { - if err := p.Compatible(pb); err != nil { - return err - } - - pb = pb.Copy() - - // Keep the largest of the two periods. - if pb.Period > p.Period { - p.Period = pb.Period - } - - p.DurationNanos += pb.DurationNanos - - p.Mapping = append(p.Mapping, pb.Mapping...) - for i, m := range p.Mapping { - m.ID = uint64(i + 1) - } - p.Location = append(p.Location, pb.Location...) - for i, l := range p.Location { - l.ID = uint64(i + 1) - } - p.Function = append(p.Function, pb.Function...) - for i, f := range p.Function { - f.ID = uint64(i + 1) - } - - if r != 1.0 { - for _, s := range pb.Sample { - for i, v := range s.Value { - s.Value[i] = int64((float64(v) * r)) - } - } - } - p.Sample = append(p.Sample, pb.Sample...) - return p.CheckValid() -} - -// Compatible determines if two profiles can be compared/merged. -// returns nil if the profiles are compatible; otherwise an error with -// details on the incompatibility. -func (p *Profile) Compatible(pb *Profile) error { - if !compatibleValueTypes(p.PeriodType, pb.PeriodType) { - return fmt.Errorf("incompatible period types %v and %v", p.PeriodType, pb.PeriodType) - } - - if len(p.SampleType) != len(pb.SampleType) { - return fmt.Errorf("incompatible sample types %v and %v", p.SampleType, pb.SampleType) - } - - for i := range p.SampleType { - if !compatibleValueTypes(p.SampleType[i], pb.SampleType[i]) { - return fmt.Errorf("incompatible sample types %v and %v", p.SampleType, pb.SampleType) - } - } - - return nil -} - -// HasFunctions determines if all locations in this profile have -// symbolized function information. -func (p *Profile) HasFunctions() bool { - for _, l := range p.Location { - if l.Mapping == nil || !l.Mapping.HasFunctions { - return false - } - } - return true -} - -// HasFileLines determines if all locations in this profile have -// symbolized file and line number information. -func (p *Profile) HasFileLines() bool { - for _, l := range p.Location { - if l.Mapping == nil || (!l.Mapping.HasFilenames || !l.Mapping.HasLineNumbers) { - return false - } - } - return true -} - -func compatibleValueTypes(v1, v2 *ValueType) bool { - if v1 == nil || v2 == nil { - return true // No grounds to disqualify. - } - return v1.Type == v2.Type && v1.Unit == v2.Unit -} - -// Copy makes a fully independent copy of a profile. -func (p *Profile) Copy() *Profile { - p.preEncode() - b := marshal(p) - - pp := &Profile{} - if err := unmarshal(b, pp); err != nil { - panic(err) - } - if err := pp.postDecode(); err != nil { - panic(err) - } - - return pp -} - -// Demangler maps symbol names to a human-readable form. This may -// include C++ demangling and additional simplification. Names that -// are not demangled may be missing from the resulting map. -type Demangler func(name []string) (map[string]string, error) - -// Demangle attempts to demangle and optionally simplify any function -// names referenced in the profile. It works on a best-effort basis: -// it will silently preserve the original names in case of any errors. -func (p *Profile) Demangle(d Demangler) error { - // Collect names to demangle. - var names []string - for _, fn := range p.Function { - names = append(names, fn.SystemName) - } - - // Update profile with demangled names. - demangled, err := d(names) - if err != nil { - return err - } - for _, fn := range p.Function { - if dd, ok := demangled[fn.SystemName]; ok { - fn.Name = dd - } - } - return nil -} - -// Empty reports whether the profile contains no samples. -func (p *Profile) Empty() bool { - return len(p.Sample) == 0 -} diff --git a/libgo/go/runtime/pprof/internal/profile/profile_test.go b/libgo/go/runtime/pprof/internal/profile/profile_test.go deleted file mode 100644 index e1963f33515..00000000000 --- a/libgo/go/runtime/pprof/internal/profile/profile_test.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package profile - -import ( - "bytes" - "testing" -) - -func TestEmptyProfile(t *testing.T) { - var buf bytes.Buffer - p, err := Parse(&buf) - if err != nil { - t.Error("Want no error, got", err) - } - if p == nil { - t.Fatal("Want a valid profile, got ") - } - if !p.Empty() { - t.Errorf("Profile should be empty, got %#v", p) - } -} - -func TestParseContention(t *testing.T) { - tests := []struct { - name string - in string - wantErr bool - }{ - { - name: "valid", - in: `--- mutex: -cycles/second=3491920901 -sampling period=1 -43227965305 1659640 @ 0x45e851 0x45f764 0x4a2be1 0x44ea31 -34035731690 15760 @ 0x45e851 0x45f764 0x4a2b17 0x44ea31 -`, - }, - { - name: "valid with comment", - in: `--- mutex: -cycles/second=3491920901 -sampling period=1 -43227965305 1659640 @ 0x45e851 0x45f764 0x4a2be1 0x44ea31 -# 0x45e850 sync.(*Mutex).Unlock+0x80 /go/src/sync/mutex.go:126 -# 0x45f763 sync.(*RWMutex).Unlock+0x83 /go/src/sync/rwmutex.go:125 -# 0x4a2be0 main.main.func3+0x70 /go/src/internal/pprof/profile/a_binary.go:58 - -34035731690 15760 @ 0x45e851 0x45f764 0x4a2b17 0x44ea31 -# 0x45e850 sync.(*Mutex).Unlock+0x80 /go/src/sync/mutex.go:126 -# 0x45f763 sync.(*RWMutex).Unlock+0x83 /go/src/sync/rwmutex.go:125 -# 0x4a2b16 main.main.func2+0xd6 /go/src/internal/pprof/profile/a_binary.go:48 -`, - }, - { - name: "empty", - in: `--- mutex:`, - wantErr: true, - }, - { - name: "invalid header", - in: `--- channel: -43227965305 1659640 @ 0x45e851 0x45f764 0x4a2be1 0x44ea31`, - wantErr: true, - }, - } - for _, tc := range tests { - _, err := parseContention([]byte(tc.in)) - if tc.wantErr && err == nil { - t.Errorf("parseContention(%q) succeeded unexpectedly", tc.name) - } - if !tc.wantErr && err != nil { - t.Errorf("parseContention(%q) failed unexpectedly: %v", tc.name, err) - } - } - -} diff --git a/libgo/go/runtime/pprof/internal/profile/proto.go b/libgo/go/runtime/pprof/internal/profile/proto.go deleted file mode 100644 index 11d7f9ff9b3..00000000000 --- a/libgo/go/runtime/pprof/internal/profile/proto.go +++ /dev/null @@ -1,360 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file is a simple protocol buffer encoder and decoder. -// -// A protocol message must implement the message interface: -// decoder() []decoder -// encode(*buffer) -// -// The decode method returns a slice indexed by field number that gives the -// function to decode that field. -// The encode method encodes its receiver into the given buffer. -// -// The two methods are simple enough to be implemented by hand rather than -// by using a protocol compiler. -// -// See profile.go for examples of messages implementing this interface. -// -// There is no support for groups, message sets, or "has" bits. - -package profile - -import "errors" - -type buffer struct { - field int - typ int - u64 uint64 - data []byte - tmp [16]byte -} - -type decoder func(*buffer, message) error - -type message interface { - decoder() []decoder - encode(*buffer) -} - -func marshal(m message) []byte { - var b buffer - m.encode(&b) - return b.data -} - -func encodeVarint(b *buffer, x uint64) { - for x >= 128 { - b.data = append(b.data, byte(x)|0x80) - x >>= 7 - } - b.data = append(b.data, byte(x)) -} - -func encodeLength(b *buffer, tag int, len int) { - encodeVarint(b, uint64(tag)<<3|2) - encodeVarint(b, uint64(len)) -} - -func encodeUint64(b *buffer, tag int, x uint64) { - // append varint to b.data - encodeVarint(b, uint64(tag)<<3|0) - encodeVarint(b, x) -} - -func encodeUint64s(b *buffer, tag int, x []uint64) { - if len(x) > 2 { - // Use packed encoding - n1 := len(b.data) - for _, u := range x { - encodeVarint(b, u) - } - n2 := len(b.data) - encodeLength(b, tag, n2-n1) - n3 := len(b.data) - copy(b.tmp[:], b.data[n2:n3]) - copy(b.data[n1+(n3-n2):], b.data[n1:n2]) - copy(b.data[n1:], b.tmp[:n3-n2]) - return - } - for _, u := range x { - encodeUint64(b, tag, u) - } -} - -func encodeUint64Opt(b *buffer, tag int, x uint64) { - if x == 0 { - return - } - encodeUint64(b, tag, x) -} - -func encodeInt64(b *buffer, tag int, x int64) { - u := uint64(x) - encodeUint64(b, tag, u) -} - -func encodeInt64Opt(b *buffer, tag int, x int64) { - if x == 0 { - return - } - encodeInt64(b, tag, x) -} - -func encodeInt64s(b *buffer, tag int, x []int64) { - if len(x) > 2 { - // Use packed encoding - n1 := len(b.data) - for _, u := range x { - encodeVarint(b, uint64(u)) - } - n2 := len(b.data) - encodeLength(b, tag, n2-n1) - n3 := len(b.data) - copy(b.tmp[:], b.data[n2:n3]) - copy(b.data[n1+(n3-n2):], b.data[n1:n2]) - copy(b.data[n1:], b.tmp[:n3-n2]) - return - } - for _, u := range x { - encodeInt64(b, tag, u) - } -} - -func encodeString(b *buffer, tag int, x string) { - encodeLength(b, tag, len(x)) - b.data = append(b.data, x...) -} - -func encodeStrings(b *buffer, tag int, x []string) { - for _, s := range x { - encodeString(b, tag, s) - } -} - -func encodeStringOpt(b *buffer, tag int, x string) { - if x == "" { - return - } - encodeString(b, tag, x) -} - -func encodeBool(b *buffer, tag int, x bool) { - if x { - encodeUint64(b, tag, 1) - } else { - encodeUint64(b, tag, 0) - } -} - -func encodeBoolOpt(b *buffer, tag int, x bool) { - if x == false { - return - } - encodeBool(b, tag, x) -} - -func encodeMessage(b *buffer, tag int, m message) { - n1 := len(b.data) - m.encode(b) - n2 := len(b.data) - encodeLength(b, tag, n2-n1) - n3 := len(b.data) - copy(b.tmp[:], b.data[n2:n3]) - copy(b.data[n1+(n3-n2):], b.data[n1:n2]) - copy(b.data[n1:], b.tmp[:n3-n2]) -} - -func unmarshal(data []byte, m message) (err error) { - b := buffer{data: data, typ: 2} - return decodeMessage(&b, m) -} - -func le64(p []byte) uint64 { - return uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 | uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56 -} - -func le32(p []byte) uint32 { - return uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24 -} - -func decodeVarint(data []byte) (uint64, []byte, error) { - var i int - var u uint64 - for i = 0; ; i++ { - if i >= 10 || i >= len(data) { - return 0, nil, errors.New("bad varint") - } - u |= uint64(data[i]&0x7F) << uint(7*i) - if data[i]&0x80 == 0 { - return u, data[i+1:], nil - } - } -} - -func decodeField(b *buffer, data []byte) ([]byte, error) { - x, data, err := decodeVarint(data) - if err != nil { - return nil, err - } - b.field = int(x >> 3) - b.typ = int(x & 7) - b.data = nil - b.u64 = 0 - switch b.typ { - case 0: - b.u64, data, err = decodeVarint(data) - if err != nil { - return nil, err - } - case 1: - if len(data) < 8 { - return nil, errors.New("not enough data") - } - b.u64 = le64(data[:8]) - data = data[8:] - case 2: - var n uint64 - n, data, err = decodeVarint(data) - if err != nil { - return nil, err - } - if n > uint64(len(data)) { - return nil, errors.New("too much data") - } - b.data = data[:n] - data = data[n:] - case 5: - if len(data) < 4 { - return nil, errors.New("not enough data") - } - b.u64 = uint64(le32(data[:4])) - data = data[4:] - default: - return nil, errors.New("unknown type: " + string(b.typ)) - } - - return data, nil -} - -func checkType(b *buffer, typ int) error { - if b.typ != typ { - return errors.New("type mismatch") - } - return nil -} - -func decodeMessage(b *buffer, m message) error { - if err := checkType(b, 2); err != nil { - return err - } - dec := m.decoder() - data := b.data - for len(data) > 0 { - // pull varint field# + type - var err error - data, err = decodeField(b, data) - if err != nil { - return err - } - if b.field >= len(dec) || dec[b.field] == nil { - continue - } - if err := dec[b.field](b, m); err != nil { - return err - } - } - return nil -} - -func decodeInt64(b *buffer, x *int64) error { - if err := checkType(b, 0); err != nil { - return err - } - *x = int64(b.u64) - return nil -} - -func decodeInt64s(b *buffer, x *[]int64) error { - if b.typ == 2 { - // Packed encoding - data := b.data - for len(data) > 0 { - var u uint64 - var err error - - if u, data, err = decodeVarint(data); err != nil { - return err - } - *x = append(*x, int64(u)) - } - return nil - } - var i int64 - if err := decodeInt64(b, &i); err != nil { - return err - } - *x = append(*x, i) - return nil -} - -func decodeUint64(b *buffer, x *uint64) error { - if err := checkType(b, 0); err != nil { - return err - } - *x = b.u64 - return nil -} - -func decodeUint64s(b *buffer, x *[]uint64) error { - if b.typ == 2 { - data := b.data - // Packed encoding - for len(data) > 0 { - var u uint64 - var err error - - if u, data, err = decodeVarint(data); err != nil { - return err - } - *x = append(*x, u) - } - return nil - } - var u uint64 - if err := decodeUint64(b, &u); err != nil { - return err - } - *x = append(*x, u) - return nil -} - -func decodeString(b *buffer, x *string) error { - if err := checkType(b, 2); err != nil { - return err - } - *x = string(b.data) - return nil -} - -func decodeStrings(b *buffer, x *[]string) error { - var s string - if err := decodeString(b, &s); err != nil { - return err - } - *x = append(*x, s) - return nil -} - -func decodeBool(b *buffer, x *bool) error { - if err := checkType(b, 0); err != nil { - return err - } - if int64(b.u64) == 0 { - *x = false - } else { - *x = true - } - return nil -} diff --git a/libgo/go/runtime/pprof/internal/profile/proto_test.go b/libgo/go/runtime/pprof/internal/profile/proto_test.go deleted file mode 100644 index c2613fc375a..00000000000 --- a/libgo/go/runtime/pprof/internal/profile/proto_test.go +++ /dev/null @@ -1,67 +0,0 @@ -package profile - -import ( - "reflect" - "testing" -) - -func TestPackedEncoding(t *testing.T) { - - type testcase struct { - uint64s []uint64 - int64s []int64 - encoded []byte - } - for i, tc := range []testcase{ - { - []uint64{0, 1, 10, 100, 1000, 10000}, - []int64{1000, 0, 1000}, - []byte{10, 8, 0, 1, 10, 100, 232, 7, 144, 78, 18, 5, 232, 7, 0, 232, 7}, - }, - { - []uint64{10000}, - nil, - []byte{8, 144, 78}, - }, - { - nil, - []int64{-10000}, - []byte{16, 240, 177, 255, 255, 255, 255, 255, 255, 255, 1}, - }, - } { - source := &packedInts{tc.uint64s, tc.int64s} - if got, want := marshal(source), tc.encoded; !reflect.DeepEqual(got, want) { - t.Errorf("failed encode %d, got %v, want %v", i, got, want) - } - - dest := new(packedInts) - if err := unmarshal(tc.encoded, dest); err != nil { - t.Errorf("failed decode %d: %v", i, err) - continue - } - if got, want := dest.uint64s, tc.uint64s; !reflect.DeepEqual(got, want) { - t.Errorf("failed decode uint64s %d, got %v, want %v", i, got, want) - } - if got, want := dest.int64s, tc.int64s; !reflect.DeepEqual(got, want) { - t.Errorf("failed decode int64s %d, got %v, want %v", i, got, want) - } - } -} - -type packedInts struct { - uint64s []uint64 - int64s []int64 -} - -func (u *packedInts) decoder() []decoder { - return []decoder{ - nil, - func(b *buffer, m message) error { return decodeUint64s(b, &m.(*packedInts).uint64s) }, - func(b *buffer, m message) error { return decodeInt64s(b, &m.(*packedInts).int64s) }, - } -} - -func (u *packedInts) encode(b *buffer) { - encodeUint64s(b, 1, u.uint64s) - encodeInt64s(b, 2, u.int64s) -} diff --git a/libgo/go/runtime/pprof/internal/profile/prune.go b/libgo/go/runtime/pprof/internal/profile/prune.go deleted file mode 100644 index 1924fada7a5..00000000000 --- a/libgo/go/runtime/pprof/internal/profile/prune.go +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Implements methods to remove frames from profiles. - -package profile - -import ( - "fmt" - "regexp" -) - -// Prune removes all nodes beneath a node matching dropRx, and not -// matching keepRx. If the root node of a Sample matches, the sample -// will have an empty stack. -func (p *Profile) Prune(dropRx, keepRx *regexp.Regexp) { - prune := make(map[uint64]bool) - pruneBeneath := make(map[uint64]bool) - - for _, loc := range p.Location { - var i int - for i = len(loc.Line) - 1; i >= 0; i-- { - if fn := loc.Line[i].Function; fn != nil && fn.Name != "" { - funcName := fn.Name - // Account for leading '.' on the PPC ELF v1 ABI. - if funcName[0] == '.' { - funcName = funcName[1:] - } - if dropRx.MatchString(funcName) { - if keepRx == nil || !keepRx.MatchString(funcName) { - break - } - } - } - } - - if i >= 0 { - // Found matching entry to prune. - pruneBeneath[loc.ID] = true - - // Remove the matching location. - if i == len(loc.Line)-1 { - // Matched the top entry: prune the whole location. - prune[loc.ID] = true - } else { - loc.Line = loc.Line[i+1:] - } - } - } - - // Prune locs from each Sample - for _, sample := range p.Sample { - // Scan from the root to the leaves to find the prune location. - // Do not prune frames before the first user frame, to avoid - // pruning everything. - foundUser := false - for i := len(sample.Location) - 1; i >= 0; i-- { - id := sample.Location[i].ID - if !prune[id] && !pruneBeneath[id] { - foundUser = true - continue - } - if !foundUser { - continue - } - if prune[id] { - sample.Location = sample.Location[i+1:] - break - } - if pruneBeneath[id] { - sample.Location = sample.Location[i:] - break - } - } - } -} - -// RemoveUninteresting prunes and elides profiles using built-in -// tables of uninteresting function names. -func (p *Profile) RemoveUninteresting() error { - var keep, drop *regexp.Regexp - var err error - - if p.DropFrames != "" { - if drop, err = regexp.Compile("^(" + p.DropFrames + ")$"); err != nil { - return fmt.Errorf("failed to compile regexp %s: %v", p.DropFrames, err) - } - if p.KeepFrames != "" { - if keep, err = regexp.Compile("^(" + p.KeepFrames + ")$"); err != nil { - return fmt.Errorf("failed to compile regexp %s: %v", p.KeepFrames, err) - } - } - p.Prune(drop, keep) - } - return nil -} diff --git a/libgo/go/runtime/pprof/label.go b/libgo/go/runtime/pprof/label.go index 2d92ef7e8a2..b614f125449 100644 --- a/libgo/go/runtime/pprof/label.go +++ b/libgo/go/runtime/pprof/label.go @@ -6,6 +6,9 @@ package pprof import ( "context" + "fmt" + "sort" + "strings" ) type label struct { @@ -34,6 +37,23 @@ func labelValue(ctx context.Context) labelMap { // that admits incremental immutable modification more efficiently. type labelMap map[string]string +// String statisfies Stringer and returns key, value pairs in a consistent +// order. +func (l *labelMap) String() string { + if l == nil { + return "" + } + keyVals := make([]string, 0, len(*l)) + + for k, v := range *l { + keyVals = append(keyVals, fmt.Sprintf("%q:%q", k, v)) + } + + sort.Strings(keyVals) + + return "{" + strings.Join(keyVals, ", ") + "}" +} + // WithLabels returns a new context.Context with the given labels added. // A label overwrites a prior label with the same key. func WithLabels(ctx context.Context, labels LabelSet) context.Context { @@ -54,7 +74,8 @@ func WithLabels(ctx context.Context, labels LabelSet) context.Context { // Labels takes an even number of strings representing key-value pairs // and makes a LabelSet containing them. // A label overwrites a prior label with the same key. -// Currently only CPU profile utilizes labels information. +// Currently only the CPU and goroutine profiles utilize any labels +// information. // See https://golang.org/issue/23458 for details. func Labels(args ...string) LabelSet { if len(args)%2 != 0 { diff --git a/libgo/go/runtime/pprof/label_test.go b/libgo/go/runtime/pprof/label_test.go index de39d85d3af..fcb00bde506 100644 --- a/libgo/go/runtime/pprof/label_test.go +++ b/libgo/go/runtime/pprof/label_test.go @@ -80,3 +80,35 @@ func TestContextLabels(t *testing.T) { t.Errorf("(sorted) labels on context: got %v, want %v", gotLabels, wantLabels) } } + +func TestLabelMapStringer(t *testing.T) { + for _, tbl := range []struct { + m labelMap + expected string + }{ + { + m: labelMap{ + // empty map + }, + expected: "{}", + }, { + m: labelMap{ + "foo": "bar", + }, + expected: `{"foo":"bar"}`, + }, { + m: labelMap{ + "foo": "bar", + "key1": "value1", + "key2": "value2", + "key3": "value3", + "key4WithNewline": "\nvalue4", + }, + expected: `{"foo":"bar", "key1":"value1", "key2":"value2", "key3":"value3", "key4WithNewline":"\nvalue4"}`, + }, + } { + if got := tbl.m.String(); tbl.expected != got { + t.Errorf("%#v.String() = %q; want %q", tbl.m, got, tbl.expected) + } + } +} diff --git a/libgo/go/runtime/pprof/mprof_test.go b/libgo/go/runtime/pprof/mprof_test.go index c352dea83ae..625ab7de8c8 100644 --- a/libgo/go/runtime/pprof/mprof_test.go +++ b/libgo/go/runtime/pprof/mprof_test.go @@ -9,10 +9,10 @@ package pprof import ( "bytes" "fmt" + "internal/profile" "reflect" "regexp" "runtime" - "runtime/pprof/internal/profile" "testing" "unsafe" ) diff --git a/libgo/go/runtime/pprof/pprof.go b/libgo/go/runtime/pprof/pprof.go index 183881cfd3e..52df44a5a10 100644 --- a/libgo/go/runtime/pprof/pprof.go +++ b/libgo/go/runtime/pprof/pprof.go @@ -313,9 +313,11 @@ func (p *Profile) Remove(value interface{}) { // Otherwise, WriteTo returns nil. // // The debug parameter enables additional output. -// Passing debug=0 prints only the hexadecimal addresses that pprof needs. -// Passing debug=1 adds comments translating addresses to function names -// and line numbers, so that a programmer can read the profile without tools. +// Passing debug=0 writes the gzip-compressed protocol buffer described +// in https://github.com/google/pprof/tree/master/proto#overview. +// Passing debug=1 writes the legacy text format with comments +// translating addresses to function names and line numbers, so that a +// programmer can read the profile without tools. // // The predefined profiles may assign meaning to other debug values; // for example, when printing the "goroutine" profile, debug=2 means to @@ -355,6 +357,7 @@ type stackProfile [][]uintptr func (x stackProfile) Len() int { return len(x) } func (x stackProfile) Stack(i int) []uintptr { return x[i] } +func (x stackProfile) Label(i int) *labelMap { return nil } // A countProfile is a set of stack traces to be printed as counts // grouped by stack trace. There are multiple implementations: @@ -363,6 +366,7 @@ func (x stackProfile) Stack(i int) []uintptr { return x[i] } type countProfile interface { Len() int Stack(i int) []uintptr + Label(i int) *labelMap } // printCountCycleProfile outputs block profile records (for block or mutex profiles) @@ -400,12 +404,16 @@ func printCountCycleProfile(w io.Writer, countName, cycleName string, scaler fun func printCountProfile(w io.Writer, debug int, name string, p countProfile) error { // Build count of each stack. var buf bytes.Buffer - key := func(stk []uintptr) string { + key := func(stk []uintptr, lbls *labelMap) string { buf.Reset() fmt.Fprintf(&buf, "@") for _, pc := range stk { fmt.Fprintf(&buf, " %#x", pc) } + if lbls != nil { + buf.WriteString("\n# labels: ") + buf.WriteString(lbls.String()) + } return buf.String() } count := map[string]int{} @@ -413,7 +421,7 @@ func printCountProfile(w io.Writer, debug int, name string, p countProfile) erro var keys []string n := p.Len() for i := 0; i < n; i++ { - k := key(p.Stack(i)) + k := key(p.Stack(i), p.Label(i)) if count[k] == 0 { index[k] = i keys = append(keys, k) @@ -447,7 +455,16 @@ func printCountProfile(w io.Writer, debug int, name string, p countProfile) erro // For count profiles, all stack addresses are // return PCs, which is what appendLocsForStack expects. locs = b.appendLocsForStack(locs[:0], p.Stack(index[k])) - b.pbSample(values, locs, nil) + idx := index[k] + var labels func() + if p.Label(idx) != nil { + labels = func() { + for k, v := range *p.Label(idx) { + b.pbLabel(tagSample_Label, k, v, 0) + } + } + } + b.pbSample(values, locs, labels) } b.build() return nil @@ -642,6 +659,9 @@ func writeHeapInternal(w io.Writer, debug int, defaultSampleType string) error { fmt.Fprintf(w, "# GCCPUFraction = %v\n", s.GCCPUFraction) fmt.Fprintf(w, "# DebugGC = %v\n", s.DebugGC) + // Also flush out MaxRSS on supported platforms. + addMaxRSS(w) + tw.Flush() return b.Flush() } @@ -654,7 +674,12 @@ func countThreadCreate() int { // writeThreadCreate writes the current runtime ThreadCreateProfile to w. func writeThreadCreate(w io.Writer, debug int) error { - return writeRuntimeProfile(w, debug, "threadcreate", runtime.ThreadCreateProfile) + // Until https://golang.org/issues/6104 is addressed, wrap + // ThreadCreateProfile because there's no point in tracking labels when we + // don't get any stack-traces. + return writeRuntimeProfile(w, debug, "threadcreate", func(p []runtime.StackRecord, _ []unsafe.Pointer) (n int, ok bool) { + return runtime.ThreadCreateProfile(p) + }) } // countGoroutine returns the number of goroutines. @@ -662,12 +687,15 @@ func countGoroutine() int { return runtime.NumGoroutine() } +// runtime_goroutineProfileWithLabels is defined in runtime/mprof.go +func runtime_goroutineProfileWithLabels(p []runtime.StackRecord, labels []unsafe.Pointer) (n int, ok bool) + // writeGoroutine writes the current runtime GoroutineProfile to w. func writeGoroutine(w io.Writer, debug int) error { if debug >= 2 { return writeGoroutineStacks(w) } - return writeRuntimeProfile(w, debug, "goroutine", runtime.GoroutineProfile) + return writeRuntimeProfile(w, debug, "goroutine", runtime_goroutineProfileWithLabels) } func writeGoroutineStacks(w io.Writer) error { @@ -691,7 +719,7 @@ func writeGoroutineStacks(w io.Writer) error { return err } -func writeRuntimeProfile(w io.Writer, debug int, name string, fetch func([]runtime.StackRecord) (int, bool)) error { +func writeRuntimeProfile(w io.Writer, debug int, name string, fetch func([]runtime.StackRecord, []unsafe.Pointer) (int, bool)) error { // Find out how many records there are (fetch(nil)), // allocate that many records, and get the data. // There's a race—more records might be added between @@ -699,13 +727,15 @@ func writeRuntimeProfile(w io.Writer, debug int, name string, fetch func([]runti // and also try again if we're very unlucky. // The loop should only execute one iteration in the common case. var p []runtime.StackRecord - n, ok := fetch(nil) + var labels []unsafe.Pointer + n, ok := fetch(nil, nil) for { // Allocate room for a slightly bigger profile, // in case a few more entries have been added // since the call to ThreadProfile. p = make([]runtime.StackRecord, n+10) - n, ok = fetch(p) + labels = make([]unsafe.Pointer, n+10) + n, ok = fetch(p, labels) if ok { p = p[0:n] break @@ -713,13 +743,17 @@ func writeRuntimeProfile(w io.Writer, debug int, name string, fetch func([]runti // Profile grew; try again. } - return printCountProfile(w, debug, name, runtimeProfile(p)) + return printCountProfile(w, debug, name, &runtimeProfile{p, labels}) } -type runtimeProfile []runtime.StackRecord +type runtimeProfile struct { + stk []runtime.StackRecord + labels []unsafe.Pointer +} -func (p runtimeProfile) Len() int { return len(p) } -func (p runtimeProfile) Stack(i int) []uintptr { return p[i].Stack() } +func (p *runtimeProfile) Len() int { return len(p.stk) } +func (p *runtimeProfile) Stack(i int) []uintptr { return p.stk[i].Stack() } +func (p *runtimeProfile) Label(i int) *labelMap { return (*labelMap)(p.labels[i]) } var cpu struct { sync.Mutex diff --git a/libgo/go/runtime/pprof/pprof_norusage.go b/libgo/go/runtime/pprof/pprof_norusage.go new file mode 100644 index 00000000000..6fdcc6cc38d --- /dev/null +++ b/libgo/go/runtime/pprof/pprof_norusage.go @@ -0,0 +1,15 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !darwin,!linux + +package pprof + +import ( + "io" +) + +// Stub call for platforms that don't support rusage. +func addMaxRSS(w io.Writer) { +} diff --git a/libgo/go/runtime/pprof/pprof_rusage.go b/libgo/go/runtime/pprof/pprof_rusage.go new file mode 100644 index 00000000000..d42e6ed4737 --- /dev/null +++ b/libgo/go/runtime/pprof/pprof_rusage.go @@ -0,0 +1,31 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin linux + +package pprof + +import ( + "fmt" + "io" + "runtime" + "syscall" +) + +// Adds MaxRSS to platforms that are supported. +func addMaxRSS(w io.Writer) { + var rssToBytes uintptr + switch runtime.GOOS { + case "linux", "android": + rssToBytes = 1024 + case "darwin": + rssToBytes = 1 + default: + panic("unsupported OS") + } + + var rusage syscall.Rusage + syscall.Getrusage(0, &rusage) + fmt.Fprintf(w, "# MaxRSS = %d\n", uintptr(rusage.Maxrss)*rssToBytes) +} diff --git a/libgo/go/runtime/pprof/pprof_test.go b/libgo/go/runtime/pprof/pprof_test.go index 239466fecc6..ff86bce1211 100644 --- a/libgo/go/runtime/pprof/pprof_test.go +++ b/libgo/go/runtime/pprof/pprof_test.go @@ -10,6 +10,7 @@ import ( "bytes" "context" "fmt" + "internal/profile" "internal/testenv" "io" "io/ioutil" @@ -18,7 +19,6 @@ import ( "os/exec" "regexp" "runtime" - "runtime/pprof/internal/profile" "strings" "sync" "sync/atomic" @@ -176,6 +176,25 @@ func inlinedCallee(x, n int) int { return cpuHog0(x, n) } +//go:noinline +func dumpCallers(pcs []uintptr) { + if pcs == nil { + return + } + + skip := 2 // Callers and dumpCallers + runtime.Callers(skip, pcs) +} + +//go:noinline +func inlinedCallerDump(pcs []uintptr) { + inlinedCalleeDump(pcs) +} + +func inlinedCalleeDump(pcs []uintptr) { + dumpCallers(pcs) +} + func TestCPUProfileRecursion(t *testing.T) { p := testCPUProfile(t, stackContains, []string{"runtime/pprof.inlinedCallee", "runtime/pprof.recursionCallee", "runtime/pprof.recursionCaller"}, avoidFunctions(), func(dur time.Duration) { cpuHogger(recursionCaller, &salt1, dur) @@ -208,6 +227,25 @@ func recursionCallee(n, x int) int { return y * recursionCallee(n-1, x) } +func recursionChainTop(x int, pcs []uintptr) { + if x < 0 { + return + } + recursionChainMiddle(x, pcs) +} + +func recursionChainMiddle(x int, pcs []uintptr) { + recursionChainBottom(x, pcs) +} + +func recursionChainBottom(x int, pcs []uintptr) { + // This will be called each time, we only care about the last. We + // can't make this conditional or this function won't be inlined. + dumpCallers(pcs) + + recursionChainTop(x-1, pcs) +} + func parseProfile(t *testing.T, valBytes []byte, f func(uintptr, []*profile.Location, map[string][]string)) *profile.Profile { p, err := profile.Parse(bytes.NewReader(valBytes)) if err != nil { @@ -226,7 +264,7 @@ func testCPUProfile(t *testing.T, matches matchFunc, need []string, avoid []stri switch runtime.GOOS { case "darwin": switch runtime.GOARCH { - case "arm", "arm64": + case "arm64": // nothing default: out, err := exec.Command("uname", "-a").CombinedOutput() @@ -959,6 +997,26 @@ func TestGoroutineCounts(t *testing.T) { runtime.Gosched() } } + ctx := context.Background() + + // ... and again, with labels this time (just with fewer iterations to keep + // sorting deterministic). + Do(ctx, Labels("label", "value"), func(context.Context) { + for i := 0; i < 89; i++ { + switch { + case i%10 == 0: + go func1(c) + case i%2 == 0: + go func2(c) + default: + go func3(c) + } + // Let goroutines block on channel + for j := 0; j < 5; j++ { + runtime.Gosched() + } + } + }) var w bytes.Buffer goroutineProf := Lookup("goroutine") @@ -967,8 +1025,11 @@ func TestGoroutineCounts(t *testing.T) { goroutineProf.WriteTo(&w, 1) prof := w.String() - if !containsInOrder(prof, "\n50 @ ", "\n40 @", "\n10 @", "\n1 @") { - t.Errorf("expected sorted goroutine counts:\n%s", prof) + labels := labelMap{"label": "value"} + labelStr := "\n# labels: " + labels.String() + if !containsInOrder(prof, "\n50 @ ", "\n44 @", labelStr, + "\n40 @", "\n36 @", labelStr, "\n10 @", "\n9 @", labelStr, "\n1 @") { + t.Errorf("expected sorted goroutine counts with Labels:\n%s", prof) } // Check proto profile @@ -981,9 +1042,18 @@ func TestGoroutineCounts(t *testing.T) { if err := p.CheckValid(); err != nil { t.Errorf("protobuf profile is invalid: %v", err) } - if !containsCounts(p, []int64{50, 40, 10, 1}) { - t.Errorf("expected count profile to contain goroutines with counts %v, got %v", - []int64{50, 40, 10, 1}, p) + expectedLabels := map[int64]map[string]string{ + 50: map[string]string{}, + 44: map[string]string{"label": "value"}, + 40: map[string]string{}, + 36: map[string]string{"label": "value"}, + 10: map[string]string{}, + 9: map[string]string{"label": "value"}, + 1: map[string]string{}, + } + if !containsCountsLabels(p, expectedLabels) { + t.Errorf("expected count profile to contain goroutines with counts and labels %v, got %v", + expectedLabels, p) } close(c) @@ -1002,10 +1072,23 @@ func containsInOrder(s string, all ...string) bool { return true } -func containsCounts(prof *profile.Profile, counts []int64) bool { +func containsCountsLabels(prof *profile.Profile, countLabels map[int64]map[string]string) bool { m := make(map[int64]int) - for _, c := range counts { + type nkey struct { + count int64 + key, val string + } + n := make(map[nkey]int) + for c, kv := range countLabels { m[c]++ + for k, v := range kv { + n[nkey{ + count: c, + key: k, + val: v, + }]++ + + } } for _, s := range prof.Sample { // The count is the single value in the sample @@ -1013,12 +1096,26 @@ func containsCounts(prof *profile.Profile, counts []int64) bool { return false } m[s.Value[0]]-- + for k, vs := range s.Label { + for _, v := range vs { + n[nkey{ + count: s.Value[0], + key: k, + val: v, + }]-- + } + } } for _, n := range m { if n > 0 { return false } } + for _, ncnt := range n { + if ncnt != 0 { + return false + } + } return true } @@ -1159,18 +1256,42 @@ func TestTracebackAll(t *testing.T) { } } -// TestTryAdd tests the cases that's hard to test with real program execution. -// For example, the current go compilers may not inline functions involved in recursion -// but that may not be true in the future compilers. This tests such cases by -// using fake call sequences and forcing the profile build utilizing -// translateCPUProfile defined in proto_test.go +// TestTryAdd tests the cases that are hard to test with real program execution. +// +// For example, the current go compilers may not always inline functions +// involved in recursion but that may not be true in the future compilers. This +// tests such cases by using fake call sequences and forcing the profile build +// utilizing translateCPUProfile defined in proto_test.go func TestTryAdd(t *testing.T) { - inlinedCallerPtr := uint64(funcPC(inlinedCaller)) + 1 - inlinedCalleePtr, found := findInlinedCall(inlinedCaller, 4<<10) - if !found { - t.Skip("Can't determine whether inlinedCallee was inlined into inlinedCaller.") + if _, found := findInlinedCall(inlinedCallerDump, 4<<10); !found { + t.Skip("Can't determine whether anything was inlined into inlinedCallerDump.") + } + + // inlinedCallerDump + // inlinedCalleeDump + pcs := make([]uintptr, 2) + inlinedCallerDump(pcs) + inlinedCallerStack := make([]uint64, 2) + for i := range pcs { + inlinedCallerStack[i] = uint64(pcs[i]) + } + + if _, found := findInlinedCall(recursionChainBottom, 4<<10); !found { + t.Skip("Can't determine whether anything was inlined into recursionChainBottom.") + } + + // recursionChainTop + // recursionChainMiddle + // recursionChainBottom + // recursionChainTop + // recursionChainMiddle + // recursionChainBottom + pcs = make([]uintptr, 6) + recursionChainTop(1, pcs) + recursionStack := make([]uint64, len(pcs)) + for i := range pcs { + recursionStack[i] = uint64(pcs[i]) } - inlinedCalleePtr += 1 // +1 to be safely inside of the function body. period := int64(2000 * 1000) // 1/500*1e9 nanosec. @@ -1180,13 +1301,29 @@ func TestTryAdd(t *testing.T) { wantLocs [][]string // ordered location entries with function names. wantSamples []*profile.Sample // ordered samples, we care only about Value and the profile location IDs. }{{ + // Sanity test for a normal, complete stack trace. + name: "full_stack_trace", + input: []uint64{ + 3, 0, 500, // hz = 500. Must match the period. + 5, 0, 50, inlinedCallerStack[0], inlinedCallerStack[1], + }, + wantLocs: [][]string{ + {"runtime/pprof.inlinedCalleeDump", "runtime/pprof.inlinedCallerDump"}, + }, + wantSamples: []*profile.Sample{ + {Value: []int64{50, 50 * period}, Location: []*profile.Location{{ID: 1}}}, + }, + }, { name: "bug35538", input: []uint64{ 3, 0, 500, // hz = 500. Must match the period. - 7, 0, 10, inlinedCalleePtr, inlinedCallerPtr, inlinedCalleePtr, inlinedCallerPtr, - 5, 0, 20, inlinedCalleePtr, inlinedCallerPtr, + // Fake frame: tryAdd will have inlinedCallerDump + // (stack[1]) on the deck when it encounters the next + // inline function. It should accept this. + 7, 0, 10, inlinedCallerStack[0], inlinedCallerStack[1], inlinedCallerStack[0], inlinedCallerStack[1], + 5, 0, 20, inlinedCallerStack[0], inlinedCallerStack[1], }, - wantLocs: [][]string{{"runtime/pprof.inlinedCallee", "runtime/pprof.inlinedCaller"}}, + wantLocs: [][]string{{"runtime/pprof.inlinedCalleeDump", "runtime/pprof.inlinedCallerDump"}}, wantSamples: []*profile.Sample{ {Value: []int64{10, 10 * period}, Location: []*profile.Location{{ID: 1}, {ID: 1}}}, {Value: []int64{20, 20 * period}, Location: []*profile.Location{{ID: 1}}}, @@ -1204,34 +1341,56 @@ func TestTryAdd(t *testing.T) { {Value: []int64{4242, 4242 * period}, Location: []*profile.Location{{ID: 1}}}, }, }, { - // If a function is called recursively then it must not be - // inlined in the caller. + // If a function is directly called recursively then it must + // not be inlined in the caller. // // N.B. We're generating an impossible profile here, with a - // recursive inlineCallee call. This is simulating a non-Go + // recursive inlineCalleeDump call. This is simulating a non-Go // function that looks like an inlined Go function other than // its recursive property. See pcDeck.tryAdd. - name: "recursive_func_is_not_inlined", + name: "directly_recursive_func_is_not_inlined", input: []uint64{ 3, 0, 500, // hz = 500. Must match the period. - 5, 0, 30, inlinedCalleePtr, inlinedCalleePtr, - 4, 0, 40, inlinedCalleePtr, + 5, 0, 30, inlinedCallerStack[0], inlinedCallerStack[0], + 4, 0, 40, inlinedCallerStack[0], }, - // inlinedCaller shows up here because + // inlinedCallerDump shows up here because // runtime_expandFinalInlineFrame adds it to the stack frame. - wantLocs: [][]string{{"runtime/pprof.inlinedCallee"}, {"runtime/pprof.inlinedCaller"}}, + wantLocs: [][]string{{"runtime/pprof.inlinedCalleeDump"}, {"runtime/pprof.inlinedCallerDump"}}, wantSamples: []*profile.Sample{ {Value: []int64{30, 30 * period}, Location: []*profile.Location{{ID: 1}, {ID: 1}, {ID: 2}}}, {Value: []int64{40, 40 * period}, Location: []*profile.Location{{ID: 1}, {ID: 2}}}, }, + }, { + name: "recursion_chain_inline", + input: []uint64{ + 3, 0, 500, // hz = 500. Must match the period. + 9, 0, 10, recursionStack[0], recursionStack[1], recursionStack[2], recursionStack[3], recursionStack[4], recursionStack[5], + }, + wantLocs: [][]string{ + {"runtime/pprof.recursionChainBottom"}, + { + "runtime/pprof.recursionChainMiddle", + "runtime/pprof.recursionChainTop", + "runtime/pprof.recursionChainBottom", + }, + { + "runtime/pprof.recursionChainMiddle", + "runtime/pprof.recursionChainTop", + "runtime/pprof.TestTryAdd", // inlined into the test. + }, + }, + wantSamples: []*profile.Sample{ + {Value: []int64{10, 10 * period}, Location: []*profile.Location{{ID: 1}, {ID: 2}, {ID: 3}}}, + }, }, { name: "truncated_stack_trace_later", input: []uint64{ 3, 0, 500, // hz = 500. Must match the period. - 5, 0, 50, inlinedCalleePtr, inlinedCallerPtr, - 4, 0, 60, inlinedCalleePtr, + 5, 0, 50, inlinedCallerStack[0], inlinedCallerStack[1], + 4, 0, 60, inlinedCallerStack[0], }, - wantLocs: [][]string{{"runtime/pprof.inlinedCallee", "runtime/pprof.inlinedCaller"}}, + wantLocs: [][]string{{"runtime/pprof.inlinedCalleeDump", "runtime/pprof.inlinedCallerDump"}}, wantSamples: []*profile.Sample{ {Value: []int64{50, 50 * period}, Location: []*profile.Location{{ID: 1}}}, {Value: []int64{60, 60 * period}, Location: []*profile.Location{{ID: 1}}}, @@ -1240,10 +1399,10 @@ func TestTryAdd(t *testing.T) { name: "truncated_stack_trace_first", input: []uint64{ 3, 0, 500, // hz = 500. Must match the period. - 4, 0, 70, inlinedCalleePtr, - 5, 0, 80, inlinedCalleePtr, inlinedCallerPtr, + 4, 0, 70, inlinedCallerStack[0], + 5, 0, 80, inlinedCallerStack[0], inlinedCallerStack[1], }, - wantLocs: [][]string{{"runtime/pprof.inlinedCallee", "runtime/pprof.inlinedCaller"}}, + wantLocs: [][]string{{"runtime/pprof.inlinedCalleeDump", "runtime/pprof.inlinedCallerDump"}}, wantSamples: []*profile.Sample{ {Value: []int64{70, 70 * period}, Location: []*profile.Location{{ID: 1}}}, {Value: []int64{80, 80 * period}, Location: []*profile.Location{{ID: 1}}}, @@ -1253,9 +1412,9 @@ func TestTryAdd(t *testing.T) { name: "truncated_stack_trace_only", input: []uint64{ 3, 0, 500, // hz = 500. Must match the period. - 4, 0, 70, inlinedCalleePtr, + 4, 0, 70, inlinedCallerStack[0], }, - wantLocs: [][]string{{"runtime/pprof.inlinedCallee", "runtime/pprof.inlinedCaller"}}, + wantLocs: [][]string{{"runtime/pprof.inlinedCalleeDump", "runtime/pprof.inlinedCallerDump"}}, wantSamples: []*profile.Sample{ {Value: []int64{70, 70 * period}, Location: []*profile.Location{{ID: 1}}}, }, @@ -1264,12 +1423,16 @@ func TestTryAdd(t *testing.T) { name: "truncated_stack_trace_twice", input: []uint64{ 3, 0, 500, // hz = 500. Must match the period. - 4, 0, 70, inlinedCalleePtr, - 5, 0, 80, inlinedCallerPtr, inlinedCalleePtr, + 4, 0, 70, inlinedCallerStack[0], + // Fake frame: add a fake call to + // inlinedCallerDump to prevent this sample + // from getting merged into above. + 5, 0, 80, inlinedCallerStack[1], inlinedCallerStack[0], }, wantLocs: [][]string{ - {"runtime/pprof.inlinedCallee", "runtime/pprof.inlinedCaller"}, - {"runtime/pprof.inlinedCaller"}}, + {"runtime/pprof.inlinedCalleeDump", "runtime/pprof.inlinedCallerDump"}, + {"runtime/pprof.inlinedCallerDump"}, + }, wantSamples: []*profile.Sample{ {Value: []int64{70, 70 * period}, Location: []*profile.Location{{ID: 1}}}, {Value: []int64{80, 80 * period}, Location: []*profile.Location{{ID: 2}, {ID: 1}}}, diff --git a/libgo/go/runtime/pprof/proto.go b/libgo/go/runtime/pprof/proto.go index 15fa44b991e..bd269e7a4a7 100644 --- a/libgo/go/runtime/pprof/proto.go +++ b/libgo/go/runtime/pprof/proto.go @@ -474,7 +474,7 @@ func (b *profileBuilder) appendLocsForStack(locs []uint64, stk []uintptr) (newLo // have the following properties: // Frame's Func is nil (note: also true for non-Go functions), and // Frame's Entry matches its entry function frame's Entry (note: could also be true for recursive calls and non-Go functions), and -// Frame's Name does not match its entry function frame's name (note: inlined functions cannot be recursive). +// Frame's Name does not match its entry function frame's name (note: inlined functions cannot be directly recursive). // // As reading and processing the pcs in a stack trace one by one (from leaf to the root), // we use pcDeck to temporarily hold the observed pcs and their expanded frames diff --git a/libgo/go/runtime/pprof/proto_test.go b/libgo/go/runtime/pprof/proto_test.go index 81cd5591d1d..e8efd4aa1ba 100644 --- a/libgo/go/runtime/pprof/proto_test.go +++ b/libgo/go/runtime/pprof/proto_test.go @@ -8,13 +8,13 @@ import ( "bytes" "encoding/json" "fmt" + "internal/profile" "internal/testenv" "io/ioutil" "os" "os/exec" "reflect" "runtime" - "runtime/pprof/internal/profile" "strings" "testing" ) diff --git a/libgo/go/runtime/pprof/protomem_test.go b/libgo/go/runtime/pprof/protomem_test.go index 471b1ae9c32..156f6286a92 100644 --- a/libgo/go/runtime/pprof/protomem_test.go +++ b/libgo/go/runtime/pprof/protomem_test.go @@ -6,8 +6,8 @@ package pprof import ( "bytes" + "internal/profile" "runtime" - "runtime/pprof/internal/profile" "testing" ) diff --git a/libgo/go/runtime/preempt.go b/libgo/go/runtime/preempt.go index 1a8f9ac4a3d..9a78bcf51b8 100644 --- a/libgo/go/runtime/preempt.go +++ b/libgo/go/runtime/preempt.go @@ -56,6 +56,11 @@ import ( "runtime/internal/atomic" ) +// Keep in sync with cmd/compile/internal/gc/plive.go:go115ReduceLiveness. +const go115ReduceLiveness = true + +const go115RestartSeq = go115ReduceLiveness && true // enable restartable sequences + type suspendGState struct { g *g @@ -328,26 +333,30 @@ func wantAsyncPreempt(gp *g) bool { // 3. It's generally safe to interact with the runtime, even if we're // in a signal handler stopped here. For example, there are no runtime // locks held, so acquiring a runtime lock won't self-deadlock. -func isAsyncSafePoint(gp *g, pc uintptr) bool { +// +// In some cases the PC is safe for asynchronous preemption but it +// also needs to adjust the resumption PC. The new PC is returned in +// the second result. +func isAsyncSafePoint(gp *g, pc uintptr) (bool, uintptr) { mp := gp.m // Only user Gs can have safe-points. We check this first // because it's extremely common that we'll catch mp in the // scheduler processing this G preemption. if mp.curg != gp { - return false + return false, 0 } // Check M state. if mp.p == 0 || !canPreemptM(mp) { - return false + return false, 0 } // Check if PC is an unsafe-point. f := FuncForPC(pc) if f == nil { // Not Go code. - return false + return false, 0 } name := f.Name() if hasPrefix(name, "runtime.") || @@ -363,8 +372,7 @@ func isAsyncSafePoint(gp *g, pc uintptr) bool { // // TODO(austin): We should improve this, or opt things // in incrementally. - return false + return false, 0 } - - return true + return true, pc } diff --git a/libgo/go/runtime/print.go b/libgo/go/runtime/print.go index 7729ddc0a74..e42023f889c 100644 --- a/libgo/go/runtime/print.go +++ b/libgo/go/runtime/print.go @@ -6,6 +6,7 @@ package runtime import ( "runtime/internal/atomic" + "runtime/internal/sys" "unsafe" ) @@ -276,3 +277,56 @@ func printeface(e eface) { func printiface(i iface) { print("(", i.tab, ",", i.data, ")") } + +// hexdumpWords prints a word-oriented hex dump of [p, end). +// +// If mark != nil, it will be called with each printed word's address +// and should return a character mark to appear just before that +// word's value. It can return 0 to indicate no mark. +func hexdumpWords(p, end uintptr, mark func(uintptr) byte) { + p1 := func(x uintptr) { + var buf [2 * sys.PtrSize]byte + for i := len(buf) - 1; i >= 0; i-- { + if x&0xF < 10 { + buf[i] = byte(x&0xF) + '0' + } else { + buf[i] = byte(x&0xF) - 10 + 'a' + } + x >>= 4 + } + gwrite(buf[:]) + } + + printlock() + var markbuf [1]byte + markbuf[0] = ' ' + for i := uintptr(0); p+i < end; i += sys.PtrSize { + if i%16 == 0 { + if i != 0 { + println() + } + p1(p + i) + print(": ") + } + + if mark != nil { + markbuf[0] = mark(p + i) + if markbuf[0] == 0 { + markbuf[0] = ' ' + } + } + gwrite(markbuf[:]) + val := *(*uintptr)(unsafe.Pointer(p + i)) + p1(val) + print(" ") + + // Can we symbolize val? + name, _, _, _ := funcfileline(val, -1, false) + if name != "" { + entry := funcentry(val) + print("<", name, "+", val-entry, "> ") + } + } + println() + printunlock() +} diff --git a/libgo/go/runtime/proc.go b/libgo/go/runtime/proc.go index e0981377512..8f6eb6c6122 100644 --- a/libgo/go/runtime/proc.go +++ b/libgo/go/runtime/proc.go @@ -139,6 +139,7 @@ var modinfo string var ( m0 m g0 g + mcache0 *mcache raceprocctx0 uintptr ) @@ -279,13 +280,14 @@ func forcegchelper() { setSystemGoroutine() forcegc.g = getg() + lockInit(&forcegc.lock, lockRankForcegc) for { lock(&forcegc.lock) if forcegc.idle != 0 { throw("forcegc: phase error") } atomic.Store(&forcegc.idle, 1) - goparkunlock(&forcegc.lock, waitReasonForceGGIdle, traceEvGoBlock, 1) + goparkunlock(&forcegc.lock, waitReasonForceGCIdle, traceEvGoBlock, 1) // this goroutine is explicitly resumed by sysmon if debug.gctrace > 0 { println("GC forced") @@ -542,6 +544,22 @@ func ginit() { // // The new G calls runtime·main. func schedinit() { + lockInit(&sched.lock, lockRankSched) + lockInit(&sched.sysmonlock, lockRankSysmon) + lockInit(&sched.deferlock, lockRankDefer) + lockInit(&sched.sudoglock, lockRankSudog) + lockInit(&deadlock, lockRankDeadlock) + lockInit(&paniclk, lockRankPanic) + lockInit(&allglock, lockRankAllg) + lockInit(&allpLock, lockRankAllp) + // lockInit(&reflectOffs.lock, lockRankReflectOffs) + lockInit(&finlock, lockRankFin) + lockInit(&trace.bufLock, lockRankTraceBuf) + lockInit(&trace.stringsLock, lockRankTraceStrings) + lockInit(&trace.lock, lockRankTrace) + lockInit(&cpuprof.lock, lockRankCpuprof) + lockInit(&trace.stackTab.lock, lockRankTraceStackTab) + _g_ := getg() sched.maxmcount = 10000 @@ -675,9 +693,7 @@ func ready(gp *g, traceskip int, next bool) { // status is Gwaiting or Gscanwaiting, make Grunnable and put on runq casgstatus(gp, _Gwaiting, _Grunnable) runqput(_g_.m.p.ptr(), gp, next) - if atomic.Load(&sched.npidle) != 0 && atomic.Load(&sched.nmspinning) == 0 { - wakep() - } + wakep() releasem(mp) } @@ -747,6 +763,7 @@ func casfrom_Gscanstatus(gp *g, oldval, newval uint32) { dumpgstatus(gp) throw("casfrom_Gscanstatus: gp->status is not in scan state") } + releaseLockRank(lockRankGscan) } // This will return false if the gp is not in the expected status and the cas fails. @@ -758,7 +775,12 @@ func castogscanstatus(gp *g, oldval, newval uint32) bool { _Gwaiting, _Gsyscall: if newval == oldval|_Gscan { - return atomic.Cas(&gp.atomicstatus, oldval, newval) + r := atomic.Cas(&gp.atomicstatus, oldval, newval) + if r { + acquireLockRank(lockRankGscan) + } + return r + } } print("runtime: castogscanstatus oldval=", hex(oldval), " newval=", hex(newval), "\n") @@ -779,6 +801,9 @@ func casgstatus(gp *g, oldval, newval uint32) { }) } + acquireLockRank(lockRankGscan) + releaseLockRank(lockRankGscan) + // See https://golang.org/cl/21503 for justification of the yield delay. const yieldDelay = 5 * 1000 var nextYield int64 @@ -811,6 +836,7 @@ func casGToPreemptScan(gp *g, old, new uint32) { if old != _Grunning || new != _Gscan|_Gpreempted { throw("bad g transition") } + acquireLockRank(lockRankGscan) for !atomic.Cas(&gp.atomicstatus, _Grunning, _Gscan|_Gpreempted) { } } @@ -841,8 +867,23 @@ func casGFromPreempted(gp *g, old, new uint32) bool { // goroutines. func stopTheWorld(reason string) { semacquire(&worldsema) - getg().m.preemptoff = reason - systemstack(stopTheWorldWithSema) + gp := getg() + gp.m.preemptoff = reason + systemstack(func() { + // Mark the goroutine which called stopTheWorld preemptible so its + // stack may be scanned. + // This lets a mark worker scan us while we try to stop the world + // since otherwise we could get in a mutual preemption deadlock. + // We must not modify anything on the G stack because a stack shrink + // may occur. A stack shrink is otherwise OK though because in order + // to return from this function (and to leave the system stack) we + // must have preempted all goroutines, including any attempting + // to scan our stack, in which case, any stack shrinking will + // have already completed by the time we exit. + casgstatus(gp, _Grunning, _Gwaiting) + stopTheWorldWithSema() + casgstatus(gp, _Gwaiting, _Grunning) + }) } // startTheWorld undoes the effects of stopTheWorld. @@ -854,10 +895,31 @@ func startTheWorld() { getg().m.preemptoff = "" } -// Holding worldsema grants an M the right to try to stop the world -// and prevents gomaxprocs from changing concurrently. +// stopTheWorldGC has the same effect as stopTheWorld, but blocks +// until the GC is not running. It also blocks a GC from starting +// until startTheWorldGC is called. +func stopTheWorldGC(reason string) { + semacquire(&gcsema) + stopTheWorld(reason) +} + +// startTheWorldGC undoes the effects of stopTheWorldGC. +func startTheWorldGC() { + startTheWorld() + semrelease(&gcsema) +} + +// Holding worldsema grants an M the right to try to stop the world. var worldsema uint32 = 1 +// Holding gcsema grants the M the right to block a GC, and blocks +// until the current GC is done. In particular, it prevents gomaxprocs +// from changing concurrently. +// +// TODO(mknyszek): Once gomaxprocs and the execution tracer can handle +// being changed/enabled during a GC, remove this. +var gcsema uint32 = 1 + // stopTheWorldWithSema is the core implementation of stopTheWorld. // The caller is responsible for acquiring worldsema and disabling // preemption first and then should stopTheWorldWithSema on the system @@ -1003,9 +1065,7 @@ func startTheWorldWithSema(emitTraceEvent bool) int64 { // Wakeup an additional proc in case we have excessive runnable goroutines // in local queues or in the global queue. If we don't, the proc will park itself. // If we have lots of excessive work, resetspinning will unpark additional procs as necessary. - if atomic.Load(&sched.npidle) != 0 && atomic.Load(&sched.nmspinning) == 0 { - wakep() - } + wakep() releasem(mp) @@ -1599,8 +1659,7 @@ func lockextra(nilokay bool) *m { for { old := atomic.Loaduintptr(&extram) if old == locked { - yield := osyield - yield() + osyield() continue } if old == 0 && !nilokay { @@ -1617,8 +1676,7 @@ func lockextra(nilokay bool) *m { if atomic.Casuintptr(&extram, old, locked) { return (*m)(unsafe.Pointer(old)) } - yield := osyield - yield() + osyield() continue } } @@ -1894,8 +1952,11 @@ func handoffp(_p_ *p) { // Tries to add one more P to execute G's. // Called when a G is made runnable (newproc, ready). func wakep() { + if atomic.Load(&sched.npidle) == 0 { + return + } // be conservative about spinning threads - if !atomic.Cas(&sched.nmspinning, 0, 1) { + if atomic.Load(&sched.nmspinning) != 0 || !atomic.Cas(&sched.nmspinning, 0, 1) { return } startm(nil, true) @@ -2111,11 +2172,14 @@ top: // Consider stealing timers from p2. // This call to checkTimers is the only place where // we hold a lock on a different P's timers. - // Lock contention can be a problem here, so avoid - // grabbing the lock if p2 is running and not marked - // for preemption. If p2 is running and not being - // preempted we assume it will handle its own timers. - if i > 2 && shouldStealTimers(p2) { + // Lock contention can be a problem here, so + // initially avoid grabbing the lock if p2 is running + // and is not marked for preemption. If p2 is running + // and not being preempted we assume it will handle its + // own timers. + // If we're still looking for work after checking all + // the P's, then go ahead and steal from an active P. + if i > 2 || (i > 1 && shouldStealTimers(p2)) { tnow, w, ran := checkTimers(p2, now) now = tnow if w != 0 && (pollUntil == 0 || w < pollUntil) { @@ -2166,9 +2230,17 @@ stop: // wasm only: // If a callback returned and no other goroutine is awake, - // then pause execution until a callback was triggered. - if beforeIdle(delta) { - // At least one goroutine got woken. + // then wake event handler goroutine which pauses execution + // until a callback was triggered. + gp, otherReady := beforeIdle(delta) + if gp != nil { + casgstatus(gp, _Gwaiting, _Grunnable) + if trace.enabled { + traceGoUnpark(gp, 0) + } + return gp, false + } + if otherReady { goto top } @@ -2358,12 +2430,16 @@ func resetspinning() { // M wakeup policy is deliberately somewhat conservative, so check if we // need to wakeup another P here. See "Worker thread parking/unparking" // comment at the top of the file for details. - if nmspinning == 0 && atomic.Load(&sched.npidle) > 0 { - wakep() - } + wakep() } -// Injects the list of runnable G's into the scheduler and clears glist. +// injectglist adds each runnable G on the list to some run queue, +// and clears glist. If there is no current P, they are added to the +// global queue, and up to npidle M's are started to run them. +// Otherwise, for each idle P, this adds a G to the global queue +// and starts an M. Any remaining G's are added to the current P's +// local run queue. +// This may temporarily acquire the scheduler lock. // Can run concurrently with GC. func injectglist(glist *gList) { if glist.empty() { @@ -2374,18 +2450,52 @@ func injectglist(glist *gList) { traceGoUnpark(gp, 0) } } + + // Mark all the goroutines as runnable before we put them + // on the run queues. + head := glist.head.ptr() + var tail *g + qsize := 0 + for gp := head; gp != nil; gp = gp.schedlink.ptr() { + tail = gp + qsize++ + casgstatus(gp, _Gwaiting, _Grunnable) + } + + // Turn the gList into a gQueue. + var q gQueue + q.head.set(head) + q.tail.set(tail) + *glist = gList{} + + startIdle := func(n int) { + for ; n != 0 && sched.npidle != 0; n-- { + startm(nil, false) + } + } + + pp := getg().m.p.ptr() + if pp == nil { + lock(&sched.lock) + globrunqputbatch(&q, int32(qsize)) + unlock(&sched.lock) + startIdle(qsize) + return + } + lock(&sched.lock) + npidle := int(sched.npidle) var n int - for n = 0; !glist.empty(); n++ { - gp := glist.pop() - casgstatus(gp, _Gwaiting, _Grunnable) - globrunqput(gp) + for n = 0; n < npidle && !q.empty(); n++ { + globrunqput(q.pop()) } unlock(&sched.lock) - for ; n != 0 && sched.npidle != 0; n-- { - startm(nil, false) + startIdle(n) + qsize -= n + + if !q.empty() { + runqputbatch(pp, &q, qsize) } - *glist = gList{} } // One round of scheduler: find a runnable goroutine and execute it. @@ -2509,9 +2619,7 @@ top: // If about to schedule a not-normal goroutine (a GCworker or tracereader), // wake a P if there is one. if tryWakeP { - if atomic.Load(&sched.npidle) != 0 && atomic.Load(&sched.nmspinning) == 0 { - wakep() - } + wakep() } if gp.lockedm != 0 { // Hands off own p to the locked m, @@ -2861,7 +2969,6 @@ func reentersyscall(pc, sp uintptr) { _g_.m.syscalltick = _g_.m.p.ptr().syscalltick _g_.sysblocktraced = true - _g_.m.mcache = nil pp := _g_.m.p.ptr() pp.m = 0 _g_.m.oldp.set(pp) @@ -2945,9 +3052,6 @@ func exitsyscall() { oldp := _g_.m.oldp.ptr() _g_.m.oldp = 0 if exitsyscallfast(oldp) { - if _g_.m.mcache == nil { - throw("lost mcache") - } if trace.enabled { if oldp != _g_.m.p.ptr() || _g_.m.syscalltick != _g_.m.p.ptr().syscalltick { systemstack(traceGoStart) @@ -2996,10 +3100,6 @@ func exitsyscall() { // Call the scheduler. mcall(exitsyscall0) - if _g_.m.mcache == nil { - throw("lost mcache") - } - // Scheduler returned, so we're allowed to run now. // Delete the syscallsp information that we left for // the garbage collector during the system call. @@ -3305,12 +3405,14 @@ func newproc(fn uintptr, arg unsafe.Pointer) *g { makeGContext(newg, sp, spsize) + releasem(_g_.m) + runqput(_p_, newg, true) - if atomic.Load(&sched.npidle) != 0 && atomic.Load(&sched.nmspinning) == 0 && mainStarted { + if mainStarted { wakep() } - releasem(_g_.m) + return newg } @@ -3772,10 +3874,12 @@ func (pp *p) init(id int32) { pp.wbBuf.reset() if pp.mcache == nil { if id == 0 { - if getg().m.mcache == nil { + if mcache0 == nil { throw("missing mcache?") } - pp.mcache = getg().m.mcache // bootstrap + // Use the bootstrap mcache0. Only one P will get + // mcache0: the one with ID 0. + pp.mcache = mcache0 } else { pp.mcache = allocmcache() } @@ -3788,6 +3892,7 @@ func (pp *p) init(id int32) { pp.raceprocctx = raceproccreate() } } + lockInit(&pp.timersLock, lockRankTimers) } // destroy releases all of the resources associated with pp and @@ -3934,7 +4039,6 @@ func procresize(nprocs int32) *p { _g_.m.p.ptr().m = 0 } _g_.m.p = 0 - _g_.m.mcache = nil p := allp[0] p.m = 0 p.status = _Pidle @@ -3944,6 +4048,9 @@ func procresize(nprocs int32) *p { } } + // g.m.p is now set, so we no longer need mcache0 for bootstrapping. + mcache0 = nil + // release resources from unused P's for i := nprocs; i < old; i++ { p := allp[i] @@ -4009,7 +4116,7 @@ func acquirep(_p_ *p) { func wirep(_p_ *p) { _g_ := getg() - if _g_.m.p != 0 || _g_.m.mcache != nil { + if _g_.m.p != 0 { throw("wirep: already in go") } if _p_.m != 0 || _p_.status != _Pidle { @@ -4020,7 +4127,6 @@ func wirep(_p_ *p) { print("wirep: p->m=", _p_.m, "(", id, ") p->status=", _p_.status, "\n") throw("wirep: invalid p state") } - _g_.m.mcache = _p_.mcache _g_.m.p.set(_p_) _p_.m.set(_g_.m) _p_.status = _Prunning @@ -4030,19 +4136,18 @@ func wirep(_p_ *p) { func releasep() *p { _g_ := getg() - if _g_.m.p == 0 || _g_.m.mcache == nil { + if _g_.m.p == 0 { throw("releasep: invalid arg") } _p_ := _g_.m.p.ptr() - if _p_.m.ptr() != _g_.m || _p_.mcache != _g_.m.mcache || _p_.status != _Prunning { - print("releasep: m=", _g_.m, " m->p=", _g_.m.p.ptr(), " p->m=", hex(_p_.m), " m->mcache=", _g_.m.mcache, " p->mcache=", _p_.mcache, " p->status=", _p_.status, "\n") + if _p_.m.ptr() != _g_.m || _p_.status != _Prunning { + print("releasep: m=", _g_.m, " m->p=", _g_.m.p.ptr(), " p->m=", hex(_p_.m), " p->status=", _p_.status, "\n") throw("releasep: invalid p state") } if trace.enabled { traceProcStop(_g_.m.p.ptr()) } _g_.m.p = 0 - _g_.m.mcache = nil _p_.m = 0 _p_.status = _Pidle return _p_ @@ -4222,6 +4327,18 @@ func sysmon() { } unlock(&sched.lock) } + lock(&sched.sysmonlock) + { + // If we spent a long time blocked on sysmonlock + // then we want to update now and next since it's + // likely stale. + now1 := nanotime() + if now1-now > 50*1000 /* 50µs */ { + next, _ = timeSleepUntil() + } + now = now1 + } + // trigger libc interceptors if needed if *cgo_yield != nil { asmcgocall(*cgo_yield, nil) @@ -4250,6 +4367,10 @@ func sysmon() { // Try to start an M to run them. startm(nil, false) } + if atomic.Load(&scavenge.sysmonWake) != 0 { + // Kick the scavenger awake if someone requested it. + wakeScavenger() + } // retake P's blocked in syscalls // and preempt long running G's if retake(now) != 0 { @@ -4270,6 +4391,7 @@ func sysmon() { lasttrace = now schedtrace(debug.scheddetail > 0) } + unlock(&sched.sysmonlock) } } @@ -4747,6 +4869,38 @@ func runqputslow(_p_ *p, gp *g, h, t uint32) bool { return true } +// runqputbatch tries to put all the G's on q on the local runnable queue. +// If the queue is full, they are put on the global queue; in that case +// this will temporarily acquire the scheduler lock. +// Executed only by the owner P. +func runqputbatch(pp *p, q *gQueue, qsize int) { + h := atomic.LoadAcq(&pp.runqhead) + t := pp.runqtail + n := uint32(0) + for !q.empty() && t-h < uint32(len(pp.runq)) { + gp := q.pop() + pp.runq[t%uint32(len(pp.runq))].set(gp) + t++ + n++ + } + qsize -= int(n) + + if randomizeScheduler { + off := func(o uint32) uint32 { + return (pp.runqtail + o) % uint32(len(pp.runq)) + } + for i := uint32(1); i < n; i++ { + j := fastrandn(i + 1) + pp.runq[off(i)], pp.runq[off(j)] = pp.runq[off(j)], pp.runq[off(i)] + } + } + + atomic.StoreRel(&pp.runqtail, t) + if !q.empty() { + globrunqputbatch(q, int32(qsize)) + } +} + // Get g from local runnable queue. // If inheritTime is true, gp should inherit the remaining time in the // current time slice. Otherwise, it should start a new time slice. diff --git a/libgo/go/runtime/proc_test.go b/libgo/go/runtime/proc_test.go index 5f96d648d98..b9828d98183 100644 --- a/libgo/go/runtime/proc_test.go +++ b/libgo/go/runtime/proc_test.go @@ -6,6 +6,7 @@ package runtime_test import ( "fmt" + "internal/race" "internal/testenv" "math" "net" @@ -429,6 +430,11 @@ func TestPingPongHog(t *testing.T) { if testing.Short() { t.Skip("skipping in -short mode") } + if race.Enabled { + // The race detector randomizes the scheduler, + // which causes this test to fail (#38266). + t.Skip("skipping in -race mode") + } defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1)) done := make(chan bool) @@ -1062,3 +1068,22 @@ loop: t.Errorf("netpollBreak did not interrupt netpoll: slept for: %v", dur) } } + +// TestBigGOMAXPROCS tests that setting GOMAXPROCS to a large value +// doesn't cause a crash at startup. See issue 38474. +func TestBigGOMAXPROCS(t *testing.T) { + t.Parallel() + output := runTestProg(t, "testprog", "NonexistentTest", "GOMAXPROCS=1024") + // Ignore error conditions on small machines. + for _, errstr := range []string{ + "failed to create new OS thread", + "cannot allocate memory", + } { + if strings.Contains(output, errstr) { + t.Skipf("failed to create 1024 threads") + } + } + if !strings.Contains(output, "unknown function: NonexistentTest") { + t.Errorf("output:\n%s\nwanted:\nunknown function: NonexistentTest", output) + } +} diff --git a/libgo/go/runtime/runtime1.go b/libgo/go/runtime/runtime1.go index 6edf7a5acec..a8a53d3052c 100644 --- a/libgo/go/runtime/runtime1.go +++ b/libgo/go/runtime/runtime1.go @@ -475,8 +475,3 @@ func releasem(mp *m) { // _g_.stackguard0 = stackPreempt // } } - -//go:nosplit -func gomcache() *mcache { - return getg().m.mcache -} diff --git a/libgo/go/runtime/runtime2.go b/libgo/go/runtime/runtime2.go index 75b42f71309..5029dbad027 100644 --- a/libgo/go/runtime/runtime2.go +++ b/libgo/go/runtime/runtime2.go @@ -164,7 +164,10 @@ const ( // as fast as spin locks (just a few user-level instructions), // but on the contention path they sleep in the kernel. // A zeroed Mutex is unlocked (no need to initialize each lock). +// Initialization is helpful for static lock ranking, but not required. type mutex struct { + // Empty struct if lock ranking is disabled, otherwise includes the lock rank + lockRankStruct // Futex-based impl treats it as uint32 key, // while sema-based impl as M* waitm. // Used to be a union, but unions break precise GC. @@ -334,12 +337,9 @@ type sudog struct { g *g - // isSelect indicates g is participating in a select, so - // g.selectDone must be CAS'd to win the wake-up race. - isSelect bool - next *sudog - prev *sudog - elem unsafe.Pointer // data element (may point to stack) + next *sudog + prev *sudog + elem unsafe.Pointer // data element (may point to stack) // The following fields are never accessed concurrently. // For channels, waitlink is only accessed by g. @@ -349,10 +349,15 @@ type sudog struct { acquiretime int64 releasetime int64 ticket uint32 - parent *sudog // semaRoot binary tree - waitlink *sudog // g.waiting list or semaRoot - waittail *sudog // semaRoot - c *hchan // channel + + // isSelect indicates g is participating in a select, so + // g.selectDone must be CAS'd to win the wake-up race. + isSelect bool + + parent *sudog // semaRoot binary tree + waitlink *sudog // g.waiting list or semaRoot + waittail *sudog // semaRoot + c *hchan // channel } /* @@ -393,6 +398,12 @@ type stack struct { } */ +// heldLockInfo gives info on a held lock and the rank of that lock +type heldLockInfo struct { + lockAddr uintptr + rank lockRank +} + type g struct { // Stack parameters. // stack describes the actual stack memory: [stack.lo, stack.hi). @@ -566,7 +577,6 @@ type m struct { park note alllink *m // on allm schedlink muintptr - mcache *mcache lockedg guintptr createstack [32]location // stack that created this thread. lockedExt uint32 // tracking for external LockOSThread @@ -601,6 +611,10 @@ type m struct { mOS + // Up to 10 locks held by this m, maintained by the lock ranking code. + locksHeldLen int + locksHeld [10]heldLockInfo + // Remaining fields are specific to gccgo. gsignalstack unsafe.Pointer // stack for gsignal @@ -817,6 +831,12 @@ type schedt struct { procresizetime int64 // nanotime() of last change to gomaxprocs totaltime int64 // ∫gomaxprocs dt up to procresizetime + + // sysmonlock protects sysmon's actions on the runtime. + // + // Acquire and hold this mutex to block sysmon from interacting + // with the rest of the runtime. + sysmonlock mutex } // Values for the flags field of a sigTabT. @@ -985,7 +1005,7 @@ const ( waitReasonChanReceive // "chan receive" waitReasonChanSend // "chan send" waitReasonFinalizerWait // "finalizer wait" - waitReasonForceGGIdle // "force gc (idle)" + waitReasonForceGCIdle // "force gc (idle)" waitReasonSemacquire // "semacquire" waitReasonSleep // "sleep" waitReasonSyncCondWait // "sync.Cond.Wait" @@ -994,6 +1014,7 @@ const ( waitReasonWaitForGCCycle // "wait for GC cycle" waitReasonGCWorkerIdle // "GC worker (idle)" waitReasonPreempted // "preempted" + waitReasonDebugCall // "debug call" ) var waitReasonStrings = [...]string{ @@ -1014,7 +1035,7 @@ var waitReasonStrings = [...]string{ waitReasonChanReceive: "chan receive", waitReasonChanSend: "chan send", waitReasonFinalizerWait: "finalizer wait", - waitReasonForceGGIdle: "force gc (idle)", + waitReasonForceGCIdle: "force gc (idle)", waitReasonSemacquire: "semacquire", waitReasonSleep: "sleep", waitReasonSyncCondWait: "sync.Cond.Wait", @@ -1023,6 +1044,7 @@ var waitReasonStrings = [...]string{ waitReasonWaitForGCCycle: "wait for GC cycle", waitReasonGCWorkerIdle: "GC worker (idle)", waitReasonPreempted: "preempted", + waitReasonDebugCall: "debug call", } func (w waitReason) String() string { diff --git a/libgo/go/runtime/rwmutex.go b/libgo/go/runtime/rwmutex.go index a6da4c979ba..7713c3f1ccf 100644 --- a/libgo/go/runtime/rwmutex.go +++ b/libgo/go/runtime/rwmutex.go @@ -39,7 +39,7 @@ func (rw *rwmutex) rlock() { if int32(atomic.Xadd(&rw.readerCount, 1)) < 0 { // A writer is pending. Park on the reader queue. systemstack(func() { - lock(&rw.rLock) + lockWithRank(&rw.rLock, lockRankRwmutexR) if rw.readerPass > 0 { // Writer finished. rw.readerPass -= 1 @@ -67,7 +67,7 @@ func (rw *rwmutex) runlock() { // A writer is pending. if atomic.Xadd(&rw.readerWait, -1) == 0 { // The last reader unblocks the writer. - lock(&rw.rLock) + lockWithRank(&rw.rLock, lockRankRwmutexR) w := rw.writer.ptr() if w != nil { notewakeup(&w.park) @@ -81,12 +81,12 @@ func (rw *rwmutex) runlock() { // lock locks rw for writing. func (rw *rwmutex) lock() { // Resolve competition with other writers and stick to our P. - lock(&rw.wLock) + lockWithRank(&rw.wLock, lockRankRwmutexW) m := getg().m // Announce that there is a pending writer. r := int32(atomic.Xadd(&rw.readerCount, -rwmutexMaxReaders)) + rwmutexMaxReaders // Wait for any active readers to complete. - lock(&rw.rLock) + lockWithRank(&rw.rLock, lockRankRwmutexR) if r != 0 && atomic.Xadd(&rw.readerWait, r) != 0 { // Wait for reader to wake us up. systemstack(func() { @@ -108,7 +108,7 @@ func (rw *rwmutex) unlock() { throw("unlock of unlocked rwmutex") } // Unblock blocked readers. - lock(&rw.rLock) + lockWithRank(&rw.rLock, lockRankRwmutexR) for rw.readers.ptr() != nil { reader := rw.readers.ptr() rw.readers = reader.schedlink diff --git a/libgo/go/runtime/select.go b/libgo/go/runtime/select.go index c9e3dd77d70..cf5d0c75a49 100644 --- a/libgo/go/runtime/select.go +++ b/libgo/go/runtime/select.go @@ -103,8 +103,9 @@ func block() { // selectgo implements the select statement. // // cas0 points to an array of type [ncases]scase, and order0 points to -// an array of type [2*ncases]uint16. Both reside on the goroutine's -// stack (regardless of any escaping in selectgo). +// an array of type [2*ncases]uint16 where ncases must be <= 65536. +// Both reside on the goroutine's stack (regardless of any escaping in +// selectgo). // // selectgo returns the index of the chosen scase, which matches the // ordinal position of its respective select{recv,send,default} call. @@ -115,6 +116,8 @@ func selectgo(cas0 *scase, order0 *uint16, ncases int) (int, bool) { print("select: cas0=", cas0, "\n") } + // NOTE: In order to maintain a lean stack size, the number of scases + // is capped at 65536. cas1 := (*[1 << 16]scase)(unsafe.Pointer(cas0)) order1 := (*[1 << 17]uint16)(unsafe.Pointer(order0)) diff --git a/libgo/go/runtime/sema.go b/libgo/go/runtime/sema.go index b6fab6daca7..c1418b3da43 100644 --- a/libgo/go/runtime/sema.go +++ b/libgo/go/runtime/sema.go @@ -129,7 +129,7 @@ func semacquire1(addr *uint32, lifo bool, profile semaProfileFlags, skipframes i s.acquiretime = t0 } for { - lock(&root.lock) + lockWithRank(&root.lock, lockRankRoot) // Add ourselves to nwait to disable "easy case" in semrelease. atomic.Xadd(&root.nwait, 1) // Check cansemacquire to avoid missed wakeup. @@ -168,7 +168,7 @@ func semrelease1(addr *uint32, handoff bool, skipframes int) { } // Harder case: search for a waiter and wake it. - lock(&root.lock) + lockWithRank(&root.lock, lockRankRoot) if atomic.Load(&root.nwait) == 0 { // The count is already consumed by another goroutine, // so no need to wake up another goroutine. @@ -486,7 +486,7 @@ func notifyListAdd(l *notifyList) uint32 { // notifyListAdd was called, it returns immediately. Otherwise, it blocks. //go:linkname notifyListWait sync.runtime_notifyListWait func notifyListWait(l *notifyList, t uint32) { - lock(&l.lock) + lockWithRank(&l.lock, lockRankNotifyList) // Return right away if this ticket has already been notified. if less(t, l.notify) { @@ -528,7 +528,7 @@ func notifyListNotifyAll(l *notifyList) { // Pull the list out into a local variable, waiters will be readied // outside the lock. - lock(&l.lock) + lockWithRank(&l.lock, lockRankNotifyList) s := l.head l.head = nil l.tail = nil @@ -558,7 +558,7 @@ func notifyListNotifyOne(l *notifyList) { return } - lock(&l.lock) + lockWithRank(&l.lock, lockRankNotifyList) // Re-check under the lock if we need to do anything. t := l.notify diff --git a/libgo/go/runtime/sema_test.go b/libgo/go/runtime/sema_test.go index 8bd5d4ce57c..cf3de0a1909 100644 --- a/libgo/go/runtime/sema_test.go +++ b/libgo/go/runtime/sema_test.go @@ -6,6 +6,7 @@ package runtime_test import ( . "runtime" + "sync" "sync/atomic" "testing" ) @@ -61,8 +62,11 @@ func testSemaHandoff() bool { // to another goroutine. Stop the current goroutine from migrating to // another CPU where it can win the race (and appear to have not yielded) by // keeping the CPUs slightly busy. + var wg sync.WaitGroup for i := 0; i < GOMAXPROCS(-1); i++ { + wg.Add(1) go func() { + defer wg.Done() for { select { case <-done: @@ -74,7 +78,9 @@ func testSemaHandoff() bool { }() } + wg.Add(1) go func() { + defer wg.Done() Semacquire(&sema) atomic.CompareAndSwapUint32(&res, 0, 1) @@ -91,7 +97,7 @@ func testSemaHandoff() bool { Semrelease1(&sema, true, 0) atomic.CompareAndSwapUint32(&res, 0, 2) - <-done // wait for goroutines to finish to avoid data races + wg.Wait() // wait for goroutines to finish to avoid data races return res == 1 // did the waiter run first? } diff --git a/libgo/go/runtime/signal_unix.go b/libgo/go/runtime/signal_unix.go index 1e057f6bf24..17c15c5a205 100644 --- a/libgo/go/runtime/signal_unix.go +++ b/libgo/go/runtime/signal_unix.go @@ -335,10 +335,13 @@ func sigpipe() { func doSigPreempt(gp *g, ctxt *sigctxt, sigpc uintptr) { // Check if this G wants to be preempted and is safe to // preempt. - if wantAsyncPreempt(gp) && isAsyncSafePoint(gp, sigpc) { - // Inject a call to asyncPreempt. - // ctxt.pushCall(funcPC(asyncPreempt)) - throw("pushCall not implemented") + if wantAsyncPreempt(gp) { + if ok, newpc := isAsyncSafePoint(gp, sigpc); ok { + // Adjust the PC and inject a call to asyncPreempt. + // ctxt.pushCall(funcPC(asyncPreempt), newpc) + throw("pushCall not implemented") + _ = newpc + } } // Acknowledge the preemption. @@ -346,10 +349,8 @@ func doSigPreempt(gp *g, ctxt *sigctxt, sigpc uintptr) { atomic.Store(&gp.m.signalPending, 0) } -// gccgo-specific definition. -const pushCallSupported = false - -const preemptMSupported = pushCallSupported +// This is false for gccgo. +const preemptMSupported = false // preemptM sends a preemption request to mp. This request may be // handled asynchronously and may be coalesced with other requests to @@ -358,13 +359,8 @@ const preemptMSupported = pushCallSupported // safe-point, it will preempt the goroutine. It always atomically // increments mp.preemptGen after handling a preemption request. func preemptM(mp *m) { - if !pushCallSupported { - // This architecture doesn't support ctxt.pushCall - // yet, so doSigPreempt won't work. - return - } - if GOOS == "darwin" && (GOARCH == "arm" || GOARCH == "arm64") && !iscgo { - // On darwin, we use libc calls, and cgo is required on ARM and ARM64 + if GOOS == "darwin" && GOARCH == "arm64" && !iscgo { + // On darwin, we use libc calls, and cgo is required on ARM64 // so we have TLS set up to save/restore G during C calls. If cgo is // absent, we cannot save/restore G in TLS, and if a signal is // received during C execution we cannot get the G. Therefore don't @@ -480,7 +476,7 @@ func sighandler(sig uint32, info *_siginfo_t, ctxt unsafe.Pointer, gp *g) { return } - if sig == sigPreempt { + if sig == sigPreempt && debug.asyncpreemptoff == 0 { // Might be a preemption signal. doSigPreempt(gp, c, sigpc) // Even if this was definitely a preemption signal, it @@ -492,10 +488,10 @@ func sighandler(sig uint32, info *_siginfo_t, ctxt unsafe.Pointer, gp *g) { if sig < uint32(len(sigtable)) { flags = sigtable[sig].flags } - if flags&_SigPanic != 0 && gp.throwsplit { + if c.sigcode() != _SI_USER && flags&_SigPanic != 0 && gp.throwsplit { // We can't safely sigpanic because it may grow the // stack. Abort in the signal handler instead. - flags = (flags &^ _SigPanic) | _SigThrow + flags = _SigThrow } if isAbortPC(sigpc) { // On many architectures, the abort function just @@ -536,7 +532,11 @@ func sighandler(sig uint32, info *_siginfo_t, ctxt unsafe.Pointer, gp *g) { dieFromSignal(sig) } - if flags&_SigThrow == 0 { + // _SigThrow means that we should exit now. + // If we get here with _SigPanic, it means that the signal + // was sent to us by a program (c.sigcode() == _SI_USER); + // in that case, if we didn't handle it in sigsend, we exit now. + if flags&(_SigThrow|_SigPanic) == 0 { return } @@ -558,6 +558,30 @@ func sighandler(sig uint32, info *_siginfo_t, ctxt unsafe.Pointer, gp *g) { print("signal arrived during cgo execution\n") gp = _g_.m.lockedg.ptr() } + if sig == _SIGILL { + // It would be nice to know how long the instruction is. + // Unfortunately, that's complicated to do in general (mostly for x86 + // and s930x, but other archs have non-standard instruction lengths also). + // Opt to print 16 bytes, which covers most instructions. + const maxN = 16 + n := uintptr(maxN) + // We have to be careful, though. If we're near the end of + // a page and the following page isn't mapped, we could + // segfault. So make sure we don't straddle a page (even though + // that could lead to printing an incomplete instruction). + // We're assuming here we can read at least the page containing the PC. + // I suppose it is possible that the page is mapped executable but not readable? + pc := sigpc + if n > physPageSize-pc%physPageSize { + n = physPageSize - pc%physPageSize + } + print("instruction bytes:") + b := (*[maxN]byte)(unsafe.Pointer(pc)) + for i := uintptr(0); i < n; i++ { + print(" ", hex(b[i])) + } + println() + } print("\n") level, _, docrash := gotraceback() diff --git a/libgo/go/runtime/signal_windows_test.go b/libgo/go/runtime/signal_windows_test.go index 97484034126..f99857193c1 100644 --- a/libgo/go/runtime/signal_windows_test.go +++ b/libgo/go/runtime/signal_windows_test.go @@ -3,6 +3,9 @@ package runtime_test import ( + "bufio" + "bytes" + "fmt" "internal/testenv" "io/ioutil" "os" @@ -10,6 +13,7 @@ import ( "path/filepath" "runtime" "strings" + "syscall" "testing" ) @@ -59,3 +63,90 @@ func TestVectoredHandlerDontCrashOnLibrary(t *testing.T) { t.Errorf("expected output %q, got %q", expectedOutput, cleanedOut) } } + +func sendCtrlBreak(pid int) error { + kernel32, err := syscall.LoadDLL("kernel32.dll") + if err != nil { + return fmt.Errorf("LoadDLL: %v\n", err) + } + generateEvent, err := kernel32.FindProc("GenerateConsoleCtrlEvent") + if err != nil { + return fmt.Errorf("FindProc: %v\n", err) + } + result, _, err := generateEvent.Call(syscall.CTRL_BREAK_EVENT, uintptr(pid)) + if result == 0 { + return fmt.Errorf("GenerateConsoleCtrlEvent: %v\n", err) + } + return nil +} + +// TestLibraryCtrlHandler tests that Go DLL allows calling program to handle console control events. +// See https://golang.org/issues/35965. +func TestLibraryCtrlHandler(t *testing.T) { + if *flagQuick { + t.Skip("-quick") + } + if runtime.GOARCH != "amd64" { + t.Skip("this test can only run on windows/amd64") + } + testenv.MustHaveGoBuild(t) + testenv.MustHaveExecPath(t, "gcc") + testprog.Lock() + defer testprog.Unlock() + dir, err := ioutil.TempDir("", "go-build") + if err != nil { + t.Fatalf("failed to create temp directory: %v", err) + } + defer os.RemoveAll(dir) + + // build go dll + dll := filepath.Join(dir, "dummy.dll") + cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", dll, "--buildmode", "c-shared", "testdata/testwinlibsignal/dummy.go") + out, err := testenv.CleanCmdEnv(cmd).CombinedOutput() + if err != nil { + t.Fatalf("failed to build go library: %s\n%s", err, out) + } + + // build c program + exe := filepath.Join(dir, "test.exe") + cmd = exec.Command("gcc", "-o", exe, "testdata/testwinlibsignal/main.c") + out, err = testenv.CleanCmdEnv(cmd).CombinedOutput() + if err != nil { + t.Fatalf("failed to build c exe: %s\n%s", err, out) + } + + // run test program + cmd = exec.Command(exe) + var stderr bytes.Buffer + cmd.Stderr = &stderr + outPipe, err := cmd.StdoutPipe() + if err != nil { + t.Fatalf("Failed to create stdout pipe: %v", err) + } + outReader := bufio.NewReader(outPipe) + + cmd.SysProcAttr = &syscall.SysProcAttr{ + CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP, + } + if err := cmd.Start(); err != nil { + t.Fatalf("Start failed: %v", err) + } + + errCh := make(chan error, 1) + go func() { + if line, err := outReader.ReadString('\n'); err != nil { + errCh <- fmt.Errorf("could not read stdout: %v", err) + } else if strings.TrimSpace(line) != "ready" { + errCh <- fmt.Errorf("unexpected message: %v", line) + } else { + errCh <- sendCtrlBreak(cmd.Process.Pid) + } + }() + + if err := <-errCh; err != nil { + t.Fatal(err) + } + if err := cmd.Wait(); err != nil { + t.Fatalf("Program exited with error: %v\n%s", err, &stderr) + } +} diff --git a/libgo/go/runtime/sigqueue.go b/libgo/go/runtime/sigqueue.go index 20704642f8d..7d1028eac29 100644 --- a/libgo/go/runtime/sigqueue.go +++ b/libgo/go/runtime/sigqueue.go @@ -192,16 +192,13 @@ func signalWaitUntilIdle() { //go:linkname signal_enable os..z2fsignal.signal_enable func signal_enable(s uint32) { if !sig.inuse { - // The first call to signal_enable is for us - // to use for initialization. It does not pass - // signal information in m. + // This is the first call to signal_enable. Initialize. sig.inuse = true // enable reception of signals; cannot disable if GOOS == "darwin" { sigNoteSetup(&sig.note) - return + } else { + noteclear(&sig.note) } - noteclear(&sig.note) - return } if s >= uint32(len(sig.wanted)*32) { diff --git a/libgo/go/runtime/sizeof_test.go b/libgo/go/runtime/sizeof_test.go index d829c5865db..0afb05e19d2 100644 --- a/libgo/go/runtime/sizeof_test.go +++ b/libgo/go/runtime/sizeof_test.go @@ -25,7 +25,8 @@ func TestSizeof(t *testing.T) { _32bit uintptr // size on 32bit platforms _64bit uintptr // size on 64bit platforms }{ - {runtime.G{}, 216, 376}, // g, but exported for testing + {runtime.G{}, 216, 376}, // g, but exported for testing + {runtime.Sudog{}, 56, 88}, // sudog, but exported for testing } for _, tt := range tests { diff --git a/libgo/go/runtime/slice.go b/libgo/go/runtime/slice.go index 519735392a9..97b26594dad 100644 --- a/libgo/go/runtime/slice.go +++ b/libgo/go/runtime/slice.go @@ -41,6 +41,55 @@ func panicmakeslicecap() { panic(errorString("makeslice: cap out of range")) } +// makeslicecopy allocates a slice of "tolen" elements of type "et", +// then copies "fromlen" elements of type "et" into that new allocation from "from". +func makeslicecopy(et *_type, tolen int, fromlen int, from unsafe.Pointer) unsafe.Pointer { + var tomem, copymem uintptr + if uintptr(tolen) > uintptr(fromlen) { + var overflow bool + tomem, overflow = math.MulUintptr(et.size, uintptr(tolen)) + if overflow || tomem > maxAlloc || tolen < 0 { + panicmakeslicelen() + } + copymem = et.size * uintptr(fromlen) + } else { + // fromlen is a known good length providing and equal or greater than tolen, + // thereby making tolen a good slice length too as from and to slices have the + // same element width. + tomem = et.size * uintptr(tolen) + copymem = tomem + } + + var to unsafe.Pointer + if et.ptrdata == 0 { + to = mallocgc(tomem, nil, false) + if copymem < tomem { + memclrNoHeapPointers(add(to, copymem), tomem-copymem) + } + } else { + // Note: can't use rawmem (which avoids zeroing of memory), because then GC can scan uninitialized memory. + to = mallocgc(tomem, et, true) + if copymem > 0 && writeBarrier.enabled { + // Only shade the pointers in old.array since we know the destination slice to + // only contains nil pointers because it has been cleared during alloc. + bulkBarrierPreWriteSrcOnly(uintptr(to), uintptr(from), copymem) + } + } + + if raceenabled { + callerpc := getcallerpc() + pc := funcPC(makeslicecopy) + racereadrangepc(from, copymem, callerpc, pc) + } + if msanenabled { + msanread(from, copymem) + } + + memmove(to, from, copymem) + + return to +} + func makeslice(et *_type, len, cap int) unsafe.Pointer { mem, overflow := math.MulUintptr(et.size, uintptr(cap)) if overflow || mem > maxAlloc || len < 0 || len > cap { @@ -187,7 +236,7 @@ func growslice(et *_type, oldarray unsafe.Pointer, oldlen, oldcap, cap int) slic if lenmem > 0 && writeBarrier.enabled { // Only shade the pointers in old.array since we know the destination slice p // only contains nil pointers because it has been cleared during alloc. - bulkBarrierPreWriteSrcOnly(uintptr(p), uintptr(oldarray), lenmem) + bulkBarrierPreWriteSrcOnly(uintptr(p), uintptr(oldarray), lenmem-et.size+et.ptrdata) } } memmove(p, oldarray, lenmem) @@ -216,12 +265,12 @@ func slicecopy(toPtr unsafe.Pointer, toLen int, fmPtr unsafe.Pointer, fmLen int, if raceenabled { callerpc := getcallerpc() pc := funcPC(slicecopy) - racewriterangepc(toPtr, uintptr(n*int(width)), callerpc, pc) racereadrangepc(fmPtr, uintptr(n*int(width)), callerpc, pc) + racewriterangepc(toPtr, uintptr(n*int(width)), callerpc, pc) } if msanenabled { - msanwrite(toPtr, uintptr(n*int(width))) msanread(fmPtr, uintptr(n*int(width))) + msanwrite(toPtr, uintptr(n*int(width))) } size := uintptr(n) * width diff --git a/libgo/go/runtime/slice_test.go b/libgo/go/runtime/slice_test.go index 0463fc70a76..e963a43dd31 100644 --- a/libgo/go/runtime/slice_test.go +++ b/libgo/go/runtime/slice_test.go @@ -10,6 +10,84 @@ import ( const N = 20 +func BenchmarkMakeSliceCopy(b *testing.B) { + const length = 32 + var bytes = make([]byte, 8*length) + var ints = make([]int, length) + var ptrs = make([]*byte, length) + b.Run("mallocmove", func(b *testing.B) { + b.Run("Byte", func(b *testing.B) { + var x []byte + for i := 0; i < b.N; i++ { + x = make([]byte, len(bytes)) + copy(x, bytes) + } + }) + b.Run("Int", func(b *testing.B) { + var x []int + for i := 0; i < b.N; i++ { + x = make([]int, len(ints)) + copy(x, ints) + } + }) + b.Run("Ptr", func(b *testing.B) { + var x []*byte + for i := 0; i < b.N; i++ { + x = make([]*byte, len(ptrs)) + copy(x, ptrs) + } + + }) + }) + b.Run("makecopy", func(b *testing.B) { + b.Run("Byte", func(b *testing.B) { + var x []byte + for i := 0; i < b.N; i++ { + x = make([]byte, 8*length) + copy(x, bytes) + } + }) + b.Run("Int", func(b *testing.B) { + var x []int + for i := 0; i < b.N; i++ { + x = make([]int, length) + copy(x, ints) + } + }) + b.Run("Ptr", func(b *testing.B) { + var x []*byte + for i := 0; i < b.N; i++ { + x = make([]*byte, length) + copy(x, ptrs) + } + + }) + }) + b.Run("nilappend", func(b *testing.B) { + b.Run("Byte", func(b *testing.B) { + var x []byte + for i := 0; i < b.N; i++ { + x = append([]byte(nil), bytes...) + _ = x + } + }) + b.Run("Int", func(b *testing.B) { + var x []int + for i := 0; i < b.N; i++ { + x = append([]int(nil), ints...) + _ = x + } + }) + b.Run("Ptr", func(b *testing.B) { + var x []*byte + for i := 0; i < b.N; i++ { + x = append([]*byte(nil), ptrs...) + _ = x + } + }) + }) +} + type ( struct24 struct{ a, b, c int64 } struct32 struct{ a, b, c, d int64 } diff --git a/libgo/go/runtime/string.go b/libgo/go/runtime/string.go index 7b66a1b447d..c0058beee62 100644 --- a/libgo/go/runtime/string.go +++ b/libgo/go/runtime/string.go @@ -6,6 +6,7 @@ package runtime import ( "internal/bytealg" + "runtime/internal/sys" "unsafe" ) @@ -93,7 +94,11 @@ func slicebytetostring(buf *tmpBuf, ptr *byte, n int) (str string) { msanread(unsafe.Pointer(ptr), uintptr(n)) } if n == 1 { - stringStructOf(&str).str = unsafe.Pointer(&staticbytes[*ptr]) + p := unsafe.Pointer(&staticuint64s[*ptr]) + if sys.BigEndian { + p = add(p, 7) + } + stringStructOf(&str).str = p stringStructOf(&str).len = 1 return } @@ -228,12 +233,6 @@ func stringStructOf(sp *string) *stringStruct { } func intstring(buf *[4]byte, v int64) (s string) { - if v >= 0 && v < runeSelf { - stringStructOf(&s).str = unsafe.Pointer(&staticbytes[v]) - stringStructOf(&s).len = 1 - return - } - var b []byte if buf != nil { b = buf[:] diff --git a/libgo/go/runtime/string_test.go b/libgo/go/runtime/string_test.go index e388f706b5f..b9799739741 100644 --- a/libgo/go/runtime/string_test.go +++ b/libgo/go/runtime/string_test.go @@ -287,7 +287,7 @@ func TestStringOnStack(t *testing.T) { func TestIntString(t *testing.T) { // Non-escaping result of intstring. s := "" - for i := 0; i < 4; i++ { + for i := rune(0); i < 4; i++ { s += string(i+'0') + string(i+'0'+1) } if want := "01122334"; s != want { @@ -296,7 +296,7 @@ func TestIntString(t *testing.T) { // Escaping result of intstring. var a [4]string - for i := 0; i < 4; i++ { + for i := rune(0); i < 4; i++ { a[i] = string(i + '0') } s = a[0] + a[1] + a[2] + a[3] diff --git a/libgo/go/runtime/stubs.go b/libgo/go/runtime/stubs.go index 25b1836daf0..d0fe551eaf8 100644 --- a/libgo/go/runtime/stubs.go +++ b/libgo/go/runtime/stubs.go @@ -140,7 +140,7 @@ func fastrandn(n uint32) uint32 { //go:linkname sync_fastrand sync.fastrand func sync_fastrand() uint32 { return fastrand() } -// in asm_*.s +// in internal/bytealg/equal_*.s //go:noescape func memequal(a, b unsafe.Pointer, size uintptr) bool diff --git a/libgo/go/runtime/symtab.go b/libgo/go/runtime/symtab.go index 86734574070..bb0b61d6131 100644 --- a/libgo/go/runtime/symtab.go +++ b/libgo/go/runtime/symtab.go @@ -155,8 +155,8 @@ type Func struct { // given program counter address, or else nil. // // If pc represents multiple functions because of inlining, it returns -// the a *Func describing the innermost function, but with an entry -// of the outermost function. +// the *Func describing the innermost function, but with an entry of +// the outermost function. func FuncForPC(pc uintptr) *Func { name, _, _, _ := funcfileline(pc, -1, false) if name == "" { diff --git a/libgo/go/runtime/testdata/testprog/gc.go b/libgo/go/runtime/testdata/testprog/gc.go index cc16413ef5c..74732cd9f4b 100644 --- a/libgo/go/runtime/testdata/testprog/gc.go +++ b/libgo/go/runtime/testdata/testprog/gc.go @@ -11,6 +11,7 @@ import ( "runtime/debug" "sync/atomic" "time" + "unsafe" ) func init() { @@ -19,6 +20,7 @@ func init() { register("GCSys", GCSys) register("GCPhys", GCPhys) register("DeferLiveness", DeferLiveness) + register("GCZombie", GCZombie) } func GCSys() { @@ -150,16 +152,20 @@ func GCPhys() { // The page cache could hide 64 8-KiB pages from the scavenger today. maxPageCache = (8 << 10) * 64 + + // Reduce GOMAXPROCS down to 4 if it's greater. We need to bound the amount + // of memory held in the page cache because the scavenger can't reach it. + // The page cache will hold at most maxPageCache of memory per-P, so this + // bounds the amount of memory hidden from the scavenger to 4*maxPageCache + // at most. + maxProcs = 4 ) // Set GOGC so that this test operates under consistent assumptions. debug.SetGCPercent(100) - // Reduce GOMAXPROCS down to 4 if it's greater. We need to bound the amount - // of memory held in the page cache because the scavenger can't reach it. - // The page cache will hold at most maxPageCache of memory per-P, so this - // bounds the amount of memory hidden from the scavenger to 4*maxPageCache. procs := runtime.GOMAXPROCS(-1) - if procs > 4 { - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) + if procs > maxProcs { + defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs)) + procs = runtime.GOMAXPROCS(-1) } // Save objects which we want to survive, and condemn objects which we don't. // Note that we condemn objects in this way and release them all at once in @@ -260,3 +266,37 @@ func DeferLiveness() { func escape(x interface{}) { sink2 = x; sink2 = nil } var sink2 interface{} + +// Test zombie object detection and reporting. +func GCZombie() { + // Allocate several objects of unusual size (so free slots are + // unlikely to all be re-allocated by the runtime). + const size = 190 + const count = 8192 / size + keep := make([]*byte, 0, (count+1)/2) + free := make([]uintptr, 0, (count+1)/2) + zombies := make([]*byte, 0, len(free)) + for i := 0; i < count; i++ { + obj := make([]byte, size) + p := &obj[0] + if i%2 == 0 { + keep = append(keep, p) + } else { + free = append(free, uintptr(unsafe.Pointer(p))) + } + } + + // Free the unreferenced objects. + runtime.GC() + + // Bring the free objects back to life. + for _, p := range free { + zombies = append(zombies, (*byte)(unsafe.Pointer(p))) + } + + // GC should detect the zombie objects. + runtime.GC() + println("failed") + runtime.KeepAlive(keep) + runtime.KeepAlive(zombies) +} diff --git a/libgo/go/runtime/testdata/testprog/lockosthread.go b/libgo/go/runtime/testdata/testprog/lockosthread.go index 098cc4dd722..e9d7fdbc44a 100644 --- a/libgo/go/runtime/testdata/testprog/lockosthread.go +++ b/libgo/go/runtime/testdata/testprog/lockosthread.go @@ -220,7 +220,7 @@ func LockOSThreadTemplateThreadRace() { }() // Try to synchronize both LockOSThreads. - start := time.Now().Add(10*time.Millisecond) + start := time.Now().Add(10 * time.Millisecond) var wg sync.WaitGroup wg.Add(2) @@ -232,10 +232,10 @@ func LockOSThreadTemplateThreadRace() { // Add work to the local runq to trigger early startm // in handoffp. - go func(){}() + go func() {}() runtime.LockOSThread() - runtime.Gosched() // add a preemption point. + runtime.Gosched() // add a preemption point. wg.Done() }() } diff --git a/libgo/go/runtime/testdata/testprog/numcpu_freebsd.go b/libgo/go/runtime/testdata/testprog/numcpu_freebsd.go index 42ee1548830..aff36ec702b 100644 --- a/libgo/go/runtime/testdata/testprog/numcpu_freebsd.go +++ b/libgo/go/runtime/testdata/testprog/numcpu_freebsd.go @@ -85,7 +85,13 @@ func getList() ([]string, error) { if err != nil { return nil, fmt.Errorf("fail to execute '%s': %s", cmdline, err) } - pos := bytes.IndexRune(output, ':') + pos := bytes.IndexRune(output, '\n') + if pos == -1 { + return nil, fmt.Errorf("invalid output from '%s', '\\n' not found: %s", cmdline, output) + } + output = output[0:pos] + + pos = bytes.IndexRune(output, ':') if pos == -1 { return nil, fmt.Errorf("invalid output from '%s', ':' not found: %s", cmdline, output) } diff --git a/libgo/go/runtime/testdata/testprog/panicprint.go b/libgo/go/runtime/testdata/testprog/panicprint.go new file mode 100644 index 00000000000..c8deabe2ab1 --- /dev/null +++ b/libgo/go/runtime/testdata/testprog/panicprint.go @@ -0,0 +1,111 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +type MyBool bool +type MyComplex128 complex128 +type MyComplex64 complex64 +type MyFloat32 float32 +type MyFloat64 float64 +type MyInt int +type MyInt8 int8 +type MyInt16 int16 +type MyInt32 int32 +type MyInt64 int64 +type MyString string +type MyUint uint +type MyUint8 uint8 +type MyUint16 uint16 +type MyUint32 uint32 +type MyUint64 uint64 +type MyUintptr uintptr + +func panicCustomComplex64() { + panic(MyComplex64(0.11 + 3i)) +} + +func panicCustomComplex128() { + panic(MyComplex128(32.1 + 10i)) +} + +func panicCustomString() { + panic(MyString("Panic")) +} + +func panicCustomBool() { + panic(MyBool(true)) +} + +func panicCustomInt() { + panic(MyInt(93)) +} + +func panicCustomInt8() { + panic(MyInt8(93)) +} + +func panicCustomInt16() { + panic(MyInt16(93)) +} + +func panicCustomInt32() { + panic(MyInt32(93)) +} + +func panicCustomInt64() { + panic(MyInt64(93)) +} + +func panicCustomUint() { + panic(MyUint(93)) +} + +func panicCustomUint8() { + panic(MyUint8(93)) +} + +func panicCustomUint16() { + panic(MyUint16(93)) +} + +func panicCustomUint32() { + panic(MyUint32(93)) +} + +func panicCustomUint64() { + panic(MyUint64(93)) +} + +func panicCustomUintptr() { + panic(MyUintptr(93)) +} + +func panicCustomFloat64() { + panic(MyFloat64(-93.70)) +} + +func panicCustomFloat32() { + panic(MyFloat32(-93.70)) +} + +func init() { + register("panicCustomComplex64", panicCustomComplex64) + register("panicCustomComplex128", panicCustomComplex128) + register("panicCustomBool", panicCustomBool) + register("panicCustomFloat32", panicCustomFloat32) + register("panicCustomFloat64", panicCustomFloat64) + register("panicCustomInt", panicCustomInt) + register("panicCustomInt8", panicCustomInt8) + register("panicCustomInt16", panicCustomInt16) + register("panicCustomInt32", panicCustomInt32) + register("panicCustomInt64", panicCustomInt64) + register("panicCustomString", panicCustomString) + register("panicCustomUint", panicCustomUint) + register("panicCustomUint8", panicCustomUint8) + register("panicCustomUint16", panicCustomUint16) + register("panicCustomUint32", panicCustomUint32) + register("panicCustomUint64", panicCustomUint64) + register("panicCustomUintptr", panicCustomUintptr) +} diff --git a/libgo/go/runtime/testdata/testprogcgo/eintr.go b/libgo/go/runtime/testdata/testprogcgo/eintr.go new file mode 100644 index 00000000000..791ff1bedc0 --- /dev/null +++ b/libgo/go/runtime/testdata/testprogcgo/eintr.go @@ -0,0 +1,246 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !plan9,!windows + +package main + +/* +#include +#include +#include + +static int clearRestart(int sig) { + struct sigaction sa; + + memset(&sa, 0, sizeof sa); + if (sigaction(sig, NULL, &sa) < 0) { + return errno; + } + sa.sa_flags &=~ SA_RESTART; + if (sigaction(sig, &sa, NULL) < 0) { + return errno; + } + return 0; +} +*/ +import "C" + +import ( + "bytes" + "errors" + "fmt" + "io" + "io/ioutil" + "log" + "net" + "os" + "os/exec" + "sync" + "syscall" + "time" +) + +func init() { + register("EINTR", EINTR) + register("Block", Block) +} + +// Test various operations when a signal handler is installed without +// the SA_RESTART flag. This tests that the os and net APIs handle EINTR. +func EINTR() { + if errno := C.clearRestart(C.int(syscall.SIGURG)); errno != 0 { + log.Fatal(syscall.Errno(errno)) + } + if errno := C.clearRestart(C.int(syscall.SIGWINCH)); errno != 0 { + log.Fatal(syscall.Errno(errno)) + } + if errno := C.clearRestart(C.int(syscall.SIGCHLD)); errno != 0 { + log.Fatal(syscall.Errno(errno)) + } + + var wg sync.WaitGroup + testPipe(&wg) + testNet(&wg) + testExec(&wg) + wg.Wait() + fmt.Println("OK") +} + +// spin does CPU bound spinning and allocating for a millisecond, +// to get a SIGURG. +//go:noinline +func spin() (float64, []byte) { + stop := time.Now().Add(time.Millisecond) + r1 := 0.0 + r2 := make([]byte, 200) + for time.Now().Before(stop) { + for i := 1; i < 1e6; i++ { + r1 += r1 / float64(i) + r2 = append(r2, bytes.Repeat([]byte{byte(i)}, 100)...) + r2 = r2[100:] + } + } + return r1, r2 +} + +// winch sends a few SIGWINCH signals to the process. +func winch() { + ticker := time.NewTicker(100 * time.Microsecond) + defer ticker.Stop() + pid := syscall.Getpid() + for n := 10; n > 0; n-- { + syscall.Kill(pid, syscall.SIGWINCH) + <-ticker.C + } +} + +// sendSomeSignals triggers a few SIGURG and SIGWINCH signals. +func sendSomeSignals() { + done := make(chan struct{}) + go func() { + spin() + close(done) + }() + winch() + <-done +} + +// testPipe tests pipe operations. +func testPipe(wg *sync.WaitGroup) { + r, w, err := os.Pipe() + if err != nil { + log.Fatal(err) + } + if err := syscall.SetNonblock(int(r.Fd()), false); err != nil { + log.Fatal(err) + } + if err := syscall.SetNonblock(int(w.Fd()), false); err != nil { + log.Fatal(err) + } + wg.Add(2) + go func() { + defer wg.Done() + defer w.Close() + // Spin before calling Write so that the first ReadFull + // in the other goroutine will likely be interrupted + // by a signal. + sendSomeSignals() + // This Write will likely be interrupted by a signal + // as the other goroutine spins in the middle of reading. + // We write enough data that we should always fill the + // pipe buffer and need multiple write system calls. + if _, err := w.Write(bytes.Repeat([]byte{0}, 2<<20)); err != nil { + log.Fatal(err) + } + }() + go func() { + defer wg.Done() + defer r.Close() + b := make([]byte, 1<<20) + // This ReadFull will likely be interrupted by a signal, + // as the other goroutine spins before writing anything. + if _, err := io.ReadFull(r, b); err != nil { + log.Fatal(err) + } + // Spin after reading half the data so that the Write + // in the other goroutine will likely be interrupted + // before it completes. + sendSomeSignals() + if _, err := io.ReadFull(r, b); err != nil { + log.Fatal(err) + } + }() +} + +// testNet tests network operations. +func testNet(wg *sync.WaitGroup) { + ln, err := net.Listen("tcp4", "127.0.0.1:0") + if err != nil { + if errors.Is(err, syscall.EAFNOSUPPORT) || errors.Is(err, syscall.EPROTONOSUPPORT) { + return + } + log.Fatal(err) + } + wg.Add(2) + go func() { + defer wg.Done() + defer ln.Close() + c, err := ln.Accept() + if err != nil { + log.Fatal(err) + } + defer c.Close() + cf, err := c.(*net.TCPConn).File() + if err != nil { + log.Fatal(err) + } + defer cf.Close() + if err := syscall.SetNonblock(int(cf.Fd()), false); err != nil { + log.Fatal(err) + } + // See comments in testPipe. + sendSomeSignals() + if _, err := cf.Write(bytes.Repeat([]byte{0}, 2<<20)); err != nil { + log.Fatal(err) + } + }() + go func() { + defer wg.Done() + sendSomeSignals() + c, err := net.Dial("tcp", ln.Addr().String()) + if err != nil { + log.Fatal(err) + } + defer c.Close() + cf, err := c.(*net.TCPConn).File() + if err != nil { + log.Fatal(err) + } + defer cf.Close() + if err := syscall.SetNonblock(int(cf.Fd()), false); err != nil { + log.Fatal(err) + } + // See comments in testPipe. + b := make([]byte, 1<<20) + if _, err := io.ReadFull(cf, b); err != nil { + log.Fatal(err) + } + sendSomeSignals() + if _, err := io.ReadFull(cf, b); err != nil { + log.Fatal(err) + } + }() +} + +func testExec(wg *sync.WaitGroup) { + wg.Add(1) + go func() { + defer wg.Done() + cmd := exec.Command(os.Args[0], "Block") + stdin, err := cmd.StdinPipe() + if err != nil { + log.Fatal(err) + } + cmd.Stderr = new(bytes.Buffer) + cmd.Stdout = cmd.Stderr + if err := cmd.Start(); err != nil { + log.Fatal(err) + } + + go func() { + sendSomeSignals() + stdin.Close() + }() + + if err := cmd.Wait(); err != nil { + log.Fatalf("%v:\n%s", err, cmd.Stdout) + } + }() +} + +// Block blocks until stdin is closed. +func Block() { + io.Copy(ioutil.Discard, os.Stdin) +} diff --git a/libgo/go/runtime/testdata/testprogcgo/segv.go b/libgo/go/runtime/testdata/testprogcgo/segv.go new file mode 100644 index 00000000000..3237a8c69c6 --- /dev/null +++ b/libgo/go/runtime/testdata/testprogcgo/segv.go @@ -0,0 +1,56 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !plan9,!windows + +package main + +// static void nop() {} +import "C" + +import ( + "syscall" + "time" +) + +func init() { + register("Segv", Segv) + register("SegvInCgo", SegvInCgo) +} + +var Sum int + +func Segv() { + c := make(chan bool) + go func() { + close(c) + for i := 0; ; i++ { + Sum += i + } + }() + + <-c + + syscall.Kill(syscall.Getpid(), syscall.SIGSEGV) + + // Give the OS time to deliver the signal. + time.Sleep(time.Second) +} + +func SegvInCgo() { + c := make(chan bool) + go func() { + close(c) + for { + C.nop() + } + }() + + <-c + + syscall.Kill(syscall.Getpid(), syscall.SIGSEGV) + + // Give the OS time to deliver the signal. + time.Sleep(time.Second) +} diff --git a/libgo/go/runtime/testdata/testwinlibsignal/dummy.go b/libgo/go/runtime/testdata/testwinlibsignal/dummy.go new file mode 100644 index 00000000000..82dfd91c93a --- /dev/null +++ b/libgo/go/runtime/testdata/testwinlibsignal/dummy.go @@ -0,0 +1,10 @@ +// +build windows + +package main + +//export Dummy +func Dummy() int { + return 42 +} + +func main() {} diff --git a/libgo/go/runtime/time.go b/libgo/go/runtime/time.go index 27d88d43105..3cf13f14f2f 100644 --- a/libgo/go/runtime/time.go +++ b/libgo/go/runtime/time.go @@ -215,11 +215,18 @@ func stopTimer(t *timer) bool { // resetTimer resets an inactive timer, adding it to the heap. //go:linkname resetTimer time.resetTimer -func resetTimer(t *timer, when int64) { +// Reports whether the timer was modified before it was run. +func resetTimer(t *timer, when int64) bool { if raceenabled { racerelease(unsafe.Pointer(t)) } - resettimer(t, when) + return resettimer(t, when) +} + +// modTimer modifies an existing timer. +//go:linkname modTimer time.modTimer +func modTimer(t *timer, when, period int64, f func(interface{}, uintptr), arg interface{}, seq uintptr) { + modtimer(t, when, period, f, arg, seq) } // Go runtime. @@ -395,14 +402,16 @@ func dodeltimer0(pp *p) { } // modtimer modifies an existing timer. -// This is called by the netpoll code. -func modtimer(t *timer, when, period int64, f func(interface{}, uintptr), arg interface{}, seq uintptr) { +// This is called by the netpoll code or time.Ticker.Reset. +// Reports whether the timer was modified before it was run. +func modtimer(t *timer, when, period int64, f func(interface{}, uintptr), arg interface{}, seq uintptr) bool { if when < 0 { when = maxWhen } status := uint32(timerNoStatus) wasRemoved := false + var pending bool var mp *m loop: for { @@ -412,6 +421,7 @@ loop: // This could lead to a self-deadlock. See #38070. mp = acquirem() if atomic.Cas(&t.status, status, timerModifying) { + pending = true // timer not yet run break loop } releasem(mp) @@ -424,6 +434,7 @@ loop: // Act like addtimer. if atomic.Cas(&t.status, status, timerModifying) { wasRemoved = true + pending = false // timer already run or stopped break loop } releasem(mp) @@ -433,6 +444,7 @@ loop: mp = acquirem() if atomic.Cas(&t.status, status, timerModifying) { atomic.Xadd(&t.pp.ptr().deletedTimers, -1) + pending = false // timer already stopped break loop } releasem(mp) @@ -503,14 +515,17 @@ loop: wakeNetPoller(when) } } + + return pending } // resettimer resets the time when a timer should fire. // If used for an inactive timer, the timer will become active. // This should be called instead of addtimer if the timer value has been, // or may have been, used previously. -func resettimer(t *timer, when int64) { - modtimer(t, when, t.period, t.f, t.arg, t.seq) +// Reports whether the timer was modified before it was run. +func resettimer(t *timer, when int64) bool { + return modtimer(t, when, t.period, t.f, t.arg, t.seq) } // cleantimers cleans up the head of the timer queue. This speeds up @@ -518,10 +533,20 @@ func resettimer(t *timer, when int64) { // slows down addtimer. Reports whether no timer problems were found. // The caller must have locked the timers for pp. func cleantimers(pp *p) { + gp := getg() for { if len(pp.timers) == 0 { return } + + // This loop can theoretically run for a while, and because + // it is holding timersLock it cannot be preempted. + // If someone is trying to preempt us, just return. + // We can clean the timers later. + if gp.preemptStop { + return + } + t := pp.timers[0] if t.pp.ptr() != pp { throw("cleantimers: bad p") diff --git a/libgo/go/runtime/trace.go b/libgo/go/runtime/trace.go index 358674b5ae8..ce185fc37ce 100644 --- a/libgo/go/runtime/trace.go +++ b/libgo/go/runtime/trace.go @@ -181,9 +181,15 @@ func traceBufPtrOf(b *traceBuf) traceBufPtr { // Most clients should use the runtime/trace package or the testing package's // -test.trace flag instead of calling StartTrace directly. func StartTrace() error { - // Stop the world, so that we can take a consistent snapshot + // Stop the world so that we can take a consistent snapshot // of all goroutines at the beginning of the trace. - stopTheWorld("start tracing") + // Do not stop the world during GC so we ensure we always see + // a consistent view of GC-related events (e.g. a start is always + // paired with an end). + stopTheWorldGC("start tracing") + + // Prevent sysmon from running any code that could generate events. + lock(&sched.sysmonlock) // We are in stop-the-world, but syscalls can finish and write to trace concurrently. // Exitsyscall could check trace.enabled long before and then suddenly wake up @@ -194,7 +200,8 @@ func StartTrace() error { if trace.enabled || trace.shutdown { unlock(&trace.bufLock) - startTheWorld() + unlock(&sched.sysmonlock) + startTheWorldGC() return errorString("tracing is already enabled") } @@ -265,7 +272,9 @@ func StartTrace() error { unlock(&trace.bufLock) - startTheWorld() + unlock(&sched.sysmonlock) + + startTheWorldGC() return nil } @@ -274,14 +283,18 @@ func StartTrace() error { func StopTrace() { // Stop the world so that we can collect the trace buffers from all p's below, // and also to avoid races with traceEvent. - stopTheWorld("stop tracing") + stopTheWorldGC("stop tracing") + + // See the comment in StartTrace. + lock(&sched.sysmonlock) // See the comment in StartTrace. lock(&trace.bufLock) if !trace.enabled { unlock(&trace.bufLock) - startTheWorld() + unlock(&sched.sysmonlock) + startTheWorldGC() return } @@ -318,7 +331,9 @@ func StopTrace() { trace.shutdown = true unlock(&trace.bufLock) - startTheWorld() + unlock(&sched.sysmonlock) + + startTheWorldGC() // The world is started but we've set trace.shutdown, so new tracing can't start. // Wait for the trace reader to flush pending buffers and stop. @@ -859,6 +874,7 @@ func (tab *traceStackTable) dump() { tab.mem.drop() *tab = traceStackTable{} + lockInit(&((*tab).lock), lockRankTraceStackTab) } type traceFrame struct { diff --git a/libgo/go/runtime/trace/trace.go b/libgo/go/runtime/trace/trace.go index 7f9d72a846e..b34aef03c51 100644 --- a/libgo/go/runtime/trace/trace.go +++ b/libgo/go/runtime/trace/trace.go @@ -19,7 +19,7 @@ // command runs the test in the current directory and writes the trace // file (trace.out). // -// go test -trace=test.out +// go test -trace=trace.out // // This runtime/trace package provides APIs to add equivalent tracing // support to a standalone program. See the Example that demonstrates diff --git a/libgo/go/runtime/trace/trace_stack_test.go b/libgo/go/runtime/trace/trace_stack_test.go index 62c06e67d9d..cfc0419b72c 100644 --- a/libgo/go/runtime/trace/trace_stack_test.go +++ b/libgo/go/runtime/trace/trace_stack_test.go @@ -233,6 +233,7 @@ func TestTraceSymbolize(t *testing.T) { }}, {trace.EvGomaxprocs, []frame{ {"runtime.startTheWorld", 0}, // this is when the current gomaxprocs is logged. + {"runtime.startTheWorldGC", 0}, {"runtime.GOMAXPROCS", 0}, {"runtime/trace_test.TestTraceSymbolize", 0}, {"testing.tRunner", 0}, @@ -251,6 +252,7 @@ func TestTraceSymbolize(t *testing.T) { {trace.EvGoSysCall, []frame{ {"syscall.read", 0}, {"syscall.Read", 0}, + {"internal/poll.ignoringEINTR", 0}, {"internal/poll.(*FD).Read", 0}, {"os.(*File).read", 0}, {"os.(*File).Read", 0}, diff --git a/libgo/go/runtime/type.go b/libgo/go/runtime/type.go index 94abbb8e9f8..56b4fe6a111 100644 --- a/libgo/go/runtime/type.go +++ b/libgo/go/runtime/type.go @@ -45,7 +45,24 @@ type _type struct { } func (t *_type) string() string { - return *t._string + // For gccgo, try to strip out quoted strings. + s := *t._string + q := false + started := false + var start int + var end int + for i := 0; i < len(s); i++ { + if s[i] == '\t' { + q = !q + } else if !q { + if !started { + start = i + started = true + } + end = i + } + } + return s[start : end+1] } // pkgpath returns the path of the package where t was defined, if diff --git a/libgo/go/strconv/atoc.go b/libgo/go/strconv/atoc.go new file mode 100644 index 00000000000..55b7c23ee7a --- /dev/null +++ b/libgo/go/strconv/atoc.go @@ -0,0 +1,105 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package strconv + +const fnParseComplex = "ParseComplex" + +// convErr splits an error returned by parseFloatPrefix +// into a syntax or range error for ParseComplex. +func convErr(err error, s string) (syntax, range_ error) { + if x, ok := err.(*NumError); ok { + x.Func = fnParseComplex + x.Num = s + if x.Err == ErrRange { + return nil, x + } + } + return err, nil +} + +// ParseComplex converts the string s to a complex number +// with the precision specified by bitSize: 64 for complex64, or 128 for complex128. +// When bitSize=64, the result still has type complex128, but it will be +// convertible to complex64 without changing its value. +// +// The number represented by s must be of the form N, Ni, or N±Ni, where N stands +// for a floating-point number as recognized by ParseFloat, and i is the imaginary +// component. If the second N is unsigned, a + sign is required between the two components +// as indicated by the ±. If the second N is NaN, only a + sign is accepted. +// The form may be parenthesized and cannot contain any spaces. +// The resulting complex number consists of the two components converted by ParseFloat. +// +// The errors that ParseComplex returns have concrete type *NumError +// and include err.Num = s. +// +// If s is not syntactically well-formed, ParseComplex returns err.Err = ErrSyntax. +// +// If s is syntactically well-formed but either component is more than 1/2 ULP +// away from the largest floating point number of the given component's size, +// ParseComplex returns err.Err = ErrRange and c = ±Inf for the respective component. +func ParseComplex(s string, bitSize int) (complex128, error) { + size := 128 + if bitSize == 64 { + size = 32 // complex64 uses float32 parts + } + + orig := s + + // Remove parentheses, if any. + if len(s) >= 2 && s[0] == '(' && s[len(s)-1] == ')' { + s = s[1 : len(s)-1] + } + + var pending error // pending range error, or nil + + // Read real part (possibly imaginary part if followed by 'i'). + re, n, err := parseFloatPrefix(s, size) + if err != nil { + err, pending = convErr(err, orig) + if err != nil { + return 0, err + } + } + s = s[n:] + + // If we have nothing left, we're done. + if len(s) == 0 { + return complex(re, 0), pending + } + + // Otherwise, look at the next character. + switch s[0] { + case '+': + // Consume the '+' to avoid an error if we have "+NaNi", but + // do this only if we don't have a "++" (don't hide that error). + if len(s) > 1 && s[1] != '+' { + s = s[1:] + } + case '-': + // ok + case 'i': + // If 'i' is the last character, we only have an imaginary part. + if len(s) == 1 { + return complex(0, re), pending + } + fallthrough + default: + return 0, syntaxError(fnParseComplex, orig) + } + + // Read imaginary part. + im, n, err := parseFloatPrefix(s, size) + if err != nil { + err, pending = convErr(err, orig) + if err != nil { + return 0, err + } + } + s = s[n:] + if s != "i" { + return 0, syntaxError(fnParseComplex, orig) + } + return complex(re, im), pending +} diff --git a/libgo/go/strconv/atoc_test.go b/libgo/go/strconv/atoc_test.go new file mode 100644 index 00000000000..3aa421dd036 --- /dev/null +++ b/libgo/go/strconv/atoc_test.go @@ -0,0 +1,202 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package strconv_test + +import ( + "math" + "math/cmplx" + "reflect" + . "strconv" + "testing" +) + +var ( + infp0 = complex(math.Inf(+1), 0) + infm0 = complex(math.Inf(-1), 0) + inf0p = complex(0, math.Inf(+1)) + inf0m = complex(0, math.Inf(-1)) + + infpp = complex(math.Inf(+1), math.Inf(+1)) + infpm = complex(math.Inf(+1), math.Inf(-1)) + infmp = complex(math.Inf(-1), math.Inf(+1)) + infmm = complex(math.Inf(-1), math.Inf(-1)) +) + +type atocTest struct { + in string + out complex128 + err error +} + +func TestParseComplex(t *testing.T) { + tests := []atocTest{ + // Clearly invalid + {"", 0, ErrSyntax}, + {" ", 0, ErrSyntax}, + {"(", 0, ErrSyntax}, + {")", 0, ErrSyntax}, + {"i", 0, ErrSyntax}, + {"+i", 0, ErrSyntax}, + {"-i", 0, ErrSyntax}, + {"1I", 0, ErrSyntax}, + {"10 + 5i", 0, ErrSyntax}, + {"3+", 0, ErrSyntax}, + {"3+5", 0, ErrSyntax}, + {"3+5+5i", 0, ErrSyntax}, + + // Parentheses + {"()", 0, ErrSyntax}, + {"(i)", 0, ErrSyntax}, + {"(0)", 0, nil}, + {"(1i)", 1i, nil}, + {"(3.0+5.5i)", 3.0 + 5.5i, nil}, + {"(1)+1i", 0, ErrSyntax}, + {"(3.0+5.5i", 0, ErrSyntax}, + {"3.0+5.5i)", 0, ErrSyntax}, + + // NaNs + {"NaN", complex(math.NaN(), 0), nil}, + {"NANi", complex(0, math.NaN()), nil}, + {"nan+nAni", complex(math.NaN(), math.NaN()), nil}, + {"+NaN", 0, ErrSyntax}, + {"-NaN", 0, ErrSyntax}, + {"NaN-NaNi", 0, ErrSyntax}, + + // Infs + {"Inf", infp0, nil}, + {"+inf", infp0, nil}, + {"-inf", infm0, nil}, + {"Infinity", infp0, nil}, + {"+INFINITY", infp0, nil}, + {"-infinity", infm0, nil}, + {"+infi", inf0p, nil}, + {"0-infinityi", inf0m, nil}, + {"Inf+Infi", infpp, nil}, + {"+Inf-Infi", infpm, nil}, + {"-Infinity+Infi", infmp, nil}, + {"inf-inf", 0, ErrSyntax}, + + // Zeros + {"0", 0, nil}, + {"0i", 0, nil}, + {"-0.0i", 0, nil}, + {"0+0.0i", 0, nil}, + {"0e+0i", 0, nil}, + {"0e-0+0i", 0, nil}, + {"-0.0-0.0i", 0, nil}, + {"0e+012345", 0, nil}, + {"0x0p+012345i", 0, nil}, + {"0x0.00p-012345i", 0, nil}, + {"+0e-0+0e-0i", 0, nil}, + {"0e+0+0e+0i", 0, nil}, + {"-0e+0-0e+0i", 0, nil}, + + // Regular non-zeroes + {"0.1", 0.1, nil}, + {"0.1i", 0 + 0.1i, nil}, + {"0.123", 0.123, nil}, + {"0.123i", 0 + 0.123i, nil}, + {"0.123+0.123i", 0.123 + 0.123i, nil}, + {"99", 99, nil}, + {"+99", 99, nil}, + {"-99", -99, nil}, + {"+1i", 1i, nil}, + {"-1i", -1i, nil}, + {"+3+1i", 3 + 1i, nil}, + {"30+3i", 30 + 3i, nil}, + {"+3e+3-3e+3i", 3e+3 - 3e+3i, nil}, + {"+3e+3+3e+3i", 3e+3 + 3e+3i, nil}, + {"+3e+3+3e+3i+", 0, ErrSyntax}, + + // Separators + {"0.1", 0.1, nil}, + {"0.1i", 0 + 0.1i, nil}, + {"0.1_2_3", 0.123, nil}, + {"+0x_3p3i", 0x3p3i, nil}, + {"0_0+0x_0p0i", 0, nil}, + {"0x_10.3p-8+0x3p3i", 0x10.3p-8 + 0x3p3i, nil}, + {"+0x_1_0.3p-8+0x_3_0p3i", 0x10.3p-8 + 0x30p3i, nil}, + {"0x1_0.3p+8-0x_3p3i", 0x10.3p+8 - 0x3p3i, nil}, + + // Hexadecimals + {"0x10.3p-8+0x3p3i", 0x10.3p-8 + 0x3p3i, nil}, + {"+0x10.3p-8+0x3p3i", 0x10.3p-8 + 0x3p3i, nil}, + {"0x10.3p+8-0x3p3i", 0x10.3p+8 - 0x3p3i, nil}, + {"0x1p0", 1, nil}, + {"0x1p1", 2, nil}, + {"0x1p-1", 0.5, nil}, + {"0x1ep-1", 15, nil}, + {"-0x1ep-1", -15, nil}, + {"-0x2p3", -16, nil}, + {"0x1e2", 0, ErrSyntax}, + {"1p2", 0, ErrSyntax}, + {"0x1e2i", 0, ErrSyntax}, + + // ErrRange + // next float64 - too large + {"+0x1p1024", infp0, ErrRange}, + {"-0x1p1024", infm0, ErrRange}, + {"+0x1p1024i", inf0p, ErrRange}, + {"-0x1p1024i", inf0m, ErrRange}, + {"+0x1p1024+0x1p1024i", infpp, ErrRange}, + {"+0x1p1024-0x1p1024i", infpm, ErrRange}, + {"-0x1p1024+0x1p1024i", infmp, ErrRange}, + {"-0x1p1024-0x1p1024i", infmm, ErrRange}, + // the border is ...158079 + // borderline - okay + {"+0x1.fffffffffffff7fffp1023+0x1.fffffffffffff7fffp1023i", 1.7976931348623157e+308 + 1.7976931348623157e+308i, nil}, + {"+0x1.fffffffffffff7fffp1023-0x1.fffffffffffff7fffp1023i", 1.7976931348623157e+308 - 1.7976931348623157e+308i, nil}, + {"-0x1.fffffffffffff7fffp1023+0x1.fffffffffffff7fffp1023i", -1.7976931348623157e+308 + 1.7976931348623157e+308i, nil}, + {"-0x1.fffffffffffff7fffp1023-0x1.fffffffffffff7fffp1023i", -1.7976931348623157e+308 - 1.7976931348623157e+308i, nil}, + // borderline - too large + {"+0x1.fffffffffffff8p1023", infp0, ErrRange}, + {"-0x1fffffffffffff.8p+971", infm0, ErrRange}, + {"+0x1.fffffffffffff8p1023i", inf0p, ErrRange}, + {"-0x1fffffffffffff.8p+971i", inf0m, ErrRange}, + {"+0x1.fffffffffffff8p1023+0x1.fffffffffffff8p1023i", infpp, ErrRange}, + {"+0x1.fffffffffffff8p1023-0x1.fffffffffffff8p1023i", infpm, ErrRange}, + {"-0x1fffffffffffff.8p+971+0x1fffffffffffff.8p+971i", infmp, ErrRange}, + {"-0x1fffffffffffff8p+967-0x1fffffffffffff8p+967i", infmm, ErrRange}, + // a little too large + {"1e308+1e308i", 1e+308 + 1e+308i, nil}, + {"2e308+2e308i", infpp, ErrRange}, + {"1e309+1e309i", infpp, ErrRange}, + {"0x1p1025+0x1p1025i", infpp, ErrRange}, + {"2e308", infp0, ErrRange}, + {"1e309", infp0, ErrRange}, + {"0x1p1025", infp0, ErrRange}, + {"2e308i", inf0p, ErrRange}, + {"1e309i", inf0p, ErrRange}, + {"0x1p1025i", inf0p, ErrRange}, + // way too large + {"+1e310+1e310i", infpp, ErrRange}, + {"+1e310-1e310i", infpm, ErrRange}, + {"-1e310+1e310i", infmp, ErrRange}, + {"-1e310-1e310i", infmm, ErrRange}, + // under/overflow exponent + {"1e-4294967296", 0, nil}, + {"1e-4294967296i", 0, nil}, + {"1e-4294967296+1i", 1i, nil}, + {"1+1e-4294967296i", 1, nil}, + {"1e-4294967296+1e-4294967296i", 0, nil}, + {"1e+4294967296", infp0, ErrRange}, + {"1e+4294967296i", inf0p, ErrRange}, + {"1e+4294967296+1e+4294967296i", infpp, ErrRange}, + {"1e+4294967296-1e+4294967296i", infpm, ErrRange}, + } + for i := range tests { + test := &tests[i] + if test.err != nil { + test.err = &NumError{Func: "ParseComplex", Num: test.in, Err: test.err} + } + got, err := ParseComplex(test.in, 128) + if !reflect.DeepEqual(err, test.err) { + t.Fatalf("ParseComplex(%q, 128) = %v, %v; want %v, %v", test.in, got, err, test.out, test.err) + } + if !(cmplx.IsNaN(test.out) && cmplx.IsNaN(got)) && got != test.out { + t.Fatalf("ParseComplex(%q, 128) = %v, %v; want %v, %v", test.in, got, err, test.out, test.err) + } + } +} diff --git a/libgo/go/strconv/atof.go b/libgo/go/strconv/atof.go index 4dbe68b16b5..1f1d5ae146f 100644 --- a/libgo/go/strconv/atof.go +++ b/libgo/go/strconv/atof.go @@ -15,51 +15,61 @@ import "runtime" var optimize = true // set to false to force slow-path conversions for testing -func equalIgnoreCase(s1, s2 string) bool { - if len(s1) != len(s2) { - return false - } - for i := 0; i < len(s1); i++ { - c1 := s1[i] - if 'A' <= c1 && c1 <= 'Z' { - c1 += 'a' - 'A' +// commonPrefixLenIgnoreCase returns the length of the common +// prefix of s and prefix, with the character case of s ignored. +// The prefix argument must be all lower-case. +func commonPrefixLenIgnoreCase(s, prefix string) int { + n := len(prefix) + if n > len(s) { + n = len(s) + } + for i := 0; i < n; i++ { + c := s[i] + if 'A' <= c && c <= 'Z' { + c += 'a' - 'A' } - c2 := s2[i] - if 'A' <= c2 && c2 <= 'Z' { - c2 += 'a' - 'A' - } - if c1 != c2 { - return false + if c != prefix[i] { + return i } } - return true + return n } -func special(s string) (f float64, ok bool) { +// special returns the floating-point value for the special, +// possibly signed floating-point representations inf, infinity, +// and NaN. The result is ok if a prefix of s contains one +// of these representations and n is the length of that prefix. +// The character case is ignored. +func special(s string) (f float64, n int, ok bool) { if len(s) == 0 { - return + return 0, 0, false } + sign := 1 + nsign := 0 switch s[0] { - default: - return - case '+': - if equalIgnoreCase(s, "+inf") || equalIgnoreCase(s, "+infinity") { - return math.Inf(1), true + case '+', '-': + if s[0] == '-' { + sign = -1 } - case '-': - if equalIgnoreCase(s, "-inf") || equalIgnoreCase(s, "-infinity") { - return math.Inf(-1), true + nsign = 1 + s = s[1:] + fallthrough + case 'i', 'I': + n := commonPrefixLenIgnoreCase(s, "infinity") + // Anything longer than "inf" is ok, but if we + // don't have "infinity", only consume "inf". + if 3 < n && n < 8 { + n = 3 } - case 'n', 'N': - if equalIgnoreCase(s, "nan") { - return math.NaN(), true + if n == 3 || n == 8 { + return math.Inf(sign), nsign + n, true } - case 'i', 'I': - if equalIgnoreCase(s, "inf") || equalIgnoreCase(s, "infinity") { - return math.Inf(1), true + case 'n', 'N': + if commonPrefixLenIgnoreCase(s, "nan") == 3 { + return math.NaN(), 3, true } } - return + return 0, 0, false } func (b *decimal) set(s string) (ok bool) { @@ -159,11 +169,11 @@ func (b *decimal) set(s string) (ok bool) { return } -// readFloat reads a decimal mantissa and exponent from a float -// string representation. It returns ok==false if the number -// is invalid. -func readFloat(s string) (mantissa uint64, exp int, neg, trunc, hex, ok bool) { - i := 0 +// readFloat reads a decimal or hexadecimal mantissa and exponent from a float +// string representation in s; the number may be followed by other characters. +// readFloat reports the number of bytes consumed (i), and whether the number +// is valid (ok). +func readFloat(s string) (mantissa uint64, exp int, neg, trunc, hex bool, i int, ok bool) { underscores := false // optional sign @@ -194,6 +204,7 @@ func readFloat(s string) (mantissa uint64, exp int, neg, trunc, hex, ok bool) { nd := 0 ndMant := 0 dp := 0 +loop: for ; i < len(s); i++ { switch c := s[i]; true { case c == '_': @@ -202,7 +213,7 @@ func readFloat(s string) (mantissa uint64, exp int, neg, trunc, hex, ok bool) { case c == '.': if sawdot { - return + break loop } sawdot = true dp = nd @@ -286,15 +297,11 @@ func readFloat(s string) (mantissa uint64, exp int, neg, trunc, hex, ok bool) { return } - if i != len(s) { - return - } - if mantissa != 0 { exp = dp - ndMant } - if underscores && !underscoreOK(s) { + if underscores && !underscoreOK(s[:i]) { return } @@ -560,26 +567,26 @@ func atofHex(s string, flt *floatInfo, mantissa uint64, exp int, neg, trunc bool const fnParseFloat = "ParseFloat" -func atof32(s string) (f float32, err error) { - if val, ok := special(s); ok { - return float32(val), nil +func atof32(s string) (f float32, n int, err error) { + if val, n, ok := special(s); ok { + return float32(val), n, nil } - mantissa, exp, neg, trunc, hex, ok := readFloat(s) + mantissa, exp, neg, trunc, hex, n, ok := readFloat(s) if !ok { - return 0, syntaxError(fnParseFloat, s) + return 0, n, syntaxError(fnParseFloat, s) } if hex { - f, err := atofHex(s, &float32info, mantissa, exp, neg, trunc) - return float32(f), err + f, err := atofHex(s[:n], &float32info, mantissa, exp, neg, trunc) + return float32(f), n, err } if optimize { // Try pure floating-point arithmetic conversion. if !trunc { if f, ok := atof32exact(mantissa, exp, neg); ok { - return f, nil + return f, n, nil } } // Try another fast path. @@ -590,42 +597,43 @@ func atof32(s string) (f float32, err error) { if ovf { err = rangeError(fnParseFloat, s) } - return f, err + return f, n, err } } // Slow fallback. var d decimal - if !d.set(s) { - return 0, syntaxError(fnParseFloat, s) + if !d.set(s[:n]) { + return 0, n, syntaxError(fnParseFloat, s) } b, ovf := d.floatBits(&float32info) f = math.Float32frombits(uint32(b)) if ovf { err = rangeError(fnParseFloat, s) } - return f, err + return f, n, err } -func atof64(s string) (f float64, err error) { - if val, ok := special(s); ok { - return val, nil +func atof64(s string) (f float64, n int, err error) { + if val, n, ok := special(s); ok { + return val, n, nil } - mantissa, exp, neg, trunc, hex, ok := readFloat(s) + mantissa, exp, neg, trunc, hex, n, ok := readFloat(s) if !ok { - return 0, syntaxError(fnParseFloat, s) + return 0, n, syntaxError(fnParseFloat, s) } if hex { - return atofHex(s, &float64info, mantissa, exp, neg, trunc) + f, err := atofHex(s[:n], &float64info, mantissa, exp, neg, trunc) + return f, n, err } if optimize { // Try pure floating-point arithmetic conversion. if !trunc { if f, ok := atof64exact(mantissa, exp, neg); ok { - return f, nil + return f, n, nil } } // Try another fast path. @@ -636,21 +644,21 @@ func atof64(s string) (f float64, err error) { if ovf { err = rangeError(fnParseFloat, s) } - return f, err + return f, n, err } } // Slow fallback. var d decimal - if !d.set(s) { - return 0, syntaxError(fnParseFloat, s) + if !d.set(s[:n]) { + return 0, n, syntaxError(fnParseFloat, s) } b, ovf := d.floatBits(&float64info) f = math.Float64frombits(b) if ovf { err = rangeError(fnParseFloat, s) } - return f, err + return f, n, err } // ParseFloat converts the string s to a floating-point number @@ -675,12 +683,20 @@ func atof64(s string) (f float64, err error) { // away from the largest floating point number of the given size, // ParseFloat returns f = ±Inf, err.Err = ErrRange. // -// ParseFloat recognizes the strings "NaN", "+Inf", and "-Inf" as their -// respective special floating point values. It ignores case when matching. +// ParseFloat recognizes the strings "NaN", and the (possibly signed) strings "Inf" and "Infinity" +// as their respective special floating point values. It ignores case when matching. func ParseFloat(s string, bitSize int) (float64, error) { + f, n, err := parseFloatPrefix(s, bitSize) + if err == nil && n != len(s) { + return 0, syntaxError(fnParseFloat, s) + } + return f, err +} + +func parseFloatPrefix(s string, bitSize int) (float64, int, error) { if bitSize == 32 { - f, err := atof32(s) - return float64(f), err + f, n, err := atof32(s) + return float64(f), n, err } return atof64(s) } diff --git a/libgo/go/strconv/atof_test.go b/libgo/go/strconv/atof_test.go index abe6c644661..545d989c41c 100644 --- a/libgo/go/strconv/atof_test.go +++ b/libgo/go/strconv/atof_test.go @@ -479,6 +479,28 @@ func initAtofOnce() { } } +func TestParseFloatPrefix(t *testing.T) { + for i := range atoftests { + test := &atoftests[i] + if test.err != nil { + continue + } + // Adding characters that do not extend a number should not invalidate it. + // Test a few. The "i" and "init" cases test that we accept "infi", "infinit" + // correctly as "inf" with suffix. + for _, suffix := range []string{" ", "q", "+", "-", "<", "=", ">", "(", ")", "i", "init"} { + in := test.in + suffix + _, n, err := ParseFloatPrefix(in, 64) + if err != nil { + t.Errorf("ParseFloatPrefix(%q, 64): err = %v; want no error", in, err) + } + if n != len(test.in) { + t.Errorf("ParseFloatPrefix(%q, 64): n = %d; want %d", in, n, len(test.in)) + } + } + } +} + func testAtof(t *testing.T, opt bool) { initAtof() oldopt := SetOptimize(opt) diff --git a/libgo/go/strconv/atoi.go b/libgo/go/strconv/atoi.go index a4a8a37fb42..f6c4efaef60 100644 --- a/libgo/go/strconv/atoi.go +++ b/libgo/go/strconv/atoi.go @@ -22,7 +22,7 @@ var ErrSyntax = errors.New("invalid syntax") // A NumError records a failed conversion. type NumError struct { - Func string // the failing function (ParseBool, ParseInt, ParseUint, ParseFloat) + Func string // the failing function (ParseBool, ParseInt, ParseUint, ParseFloat, ParseComplex) Num string // the input Err error // the reason the conversion failed (e.g. ErrRange, ErrSyntax, etc.) } @@ -96,7 +96,7 @@ func ParseUint(s string, base int, bitSize int) (uint64, error) { } if bitSize == 0 { - bitSize = int(IntSize) + bitSize = IntSize } else if bitSize < 0 || bitSize > 64 { return 0, bitSizeError(fnParseUint, s0, bitSize) } @@ -203,7 +203,7 @@ func ParseInt(s string, base int, bitSize int) (i int64, err error) { } if bitSize == 0 { - bitSize = int(IntSize) + bitSize = IntSize } cutoff := uint64(1 << uint(bitSize-1)) diff --git a/libgo/go/strconv/ctoa.go b/libgo/go/strconv/ctoa.go new file mode 100644 index 00000000000..c16a2e579cf --- /dev/null +++ b/libgo/go/strconv/ctoa.go @@ -0,0 +1,27 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package strconv + +// FormatComplex converts the complex number c to a string of the +// form (a+bi) where a and b are the real and imaginary parts, +// formatted according to the format fmt and precision prec. +// +// The format fmt and precision prec have the same meaning as in FormatFloat. +// It rounds the result assuming that the original was obtained from a complex +// value of bitSize bits, which must be 64 for complex64 and 128 for complex128. +func FormatComplex(c complex128, fmt byte, prec, bitSize int) string { + if bitSize != 64 && bitSize != 128 { + panic("invalid bitSize") + } + bitSize >>= 1 // complex64 uses float32 internally + + // Check if imaginary part has a sign. If not, add one. + im := FormatFloat(imag(c), fmt, prec, bitSize) + if im[0] != '+' && im[0] != '-' { + im = "+" + im + } + + return "(" + FormatFloat(real(c), fmt, prec, bitSize) + im + "i)" +} diff --git a/libgo/go/strconv/extfloat.go b/libgo/go/strconv/extfloat.go index 2a2dd7a4084..793a34d83fb 100644 --- a/libgo/go/strconv/extfloat.go +++ b/libgo/go/strconv/extfloat.go @@ -231,8 +231,30 @@ var uint64pow10 = [...]uint64{ // float32 depending on flt. func (f *extFloat) AssignDecimal(mantissa uint64, exp10 int, neg bool, trunc bool, flt *floatInfo) (ok bool) { const uint64digits = 19 + + // Errors (in the "numerical approximation" sense, not the "Go's error + // type" sense) in this function are measured as multiples of 1/8 of a ULP, + // so that "1/2 of a ULP" can be represented in integer arithmetic. + // + // The C++ double-conversion library also uses this 8x scaling factor: + // https://github.com/google/double-conversion/blob/f4cb2384/double-conversion/strtod.cc#L291 + // but this Go implementation has a bug, where it forgets to scale other + // calculations (further below in this function) by the same number. The + // C++ implementation does not forget: + // https://github.com/google/double-conversion/blob/f4cb2384/double-conversion/strtod.cc#L366 + // + // Scaling the "errors" in the "is mant_extra in the range (halfway ± + // errors)" check, but not scaling the other values, means that we return + // ok=false (and fall back to a slower atof code path) more often than we + // could. This affects performance but not correctness. + // + // Longer term, we could fix the forgot-to-scale bug (and look carefully + // for correctness regressions; https://codereview.appspot.com/5494068 + // landed in 2011), or replace this atof algorithm with a faster one (e.g. + // Ryu). Shorter term, this comment will suffice. const errorscale = 8 - errors := 0 // An upper bound for error, computed in errorscale*ulp. + + errors := 0 // An upper bound for error, computed in ULP/errorscale. if trunc { // the decimal number was truncated. errors += errorscale / 2 diff --git a/libgo/go/strconv/internal_test.go b/libgo/go/strconv/internal_test.go index d0fa80edfb6..bb4a418b30f 100644 --- a/libgo/go/strconv/internal_test.go +++ b/libgo/go/strconv/internal_test.go @@ -17,3 +17,7 @@ func SetOptimize(b bool) bool { optimize = b return old } + +func ParseFloatPrefix(s string, bitSize int) (float64, int, error) { + return parseFloatPrefix(s, bitSize) +} diff --git a/libgo/go/strconv/quote_test.go b/libgo/go/strconv/quote_test.go index cdc9aafd559..f1faf137bda 100644 --- a/libgo/go/strconv/quote_test.go +++ b/libgo/go/strconv/quote_test.go @@ -180,39 +180,39 @@ type canBackquoteTest struct { var canbackquotetests = []canBackquoteTest{ {"`", false}, - {string(0), false}, - {string(1), false}, - {string(2), false}, - {string(3), false}, - {string(4), false}, - {string(5), false}, - {string(6), false}, - {string(7), false}, - {string(8), false}, - {string(9), true}, // \t - {string(10), false}, - {string(11), false}, - {string(12), false}, - {string(13), false}, - {string(14), false}, - {string(15), false}, - {string(16), false}, - {string(17), false}, - {string(18), false}, - {string(19), false}, - {string(20), false}, - {string(21), false}, - {string(22), false}, - {string(23), false}, - {string(24), false}, - {string(25), false}, - {string(26), false}, - {string(27), false}, - {string(28), false}, - {string(29), false}, - {string(30), false}, - {string(31), false}, - {string(0x7F), false}, + {string(rune(0)), false}, + {string(rune(1)), false}, + {string(rune(2)), false}, + {string(rune(3)), false}, + {string(rune(4)), false}, + {string(rune(5)), false}, + {string(rune(6)), false}, + {string(rune(7)), false}, + {string(rune(8)), false}, + {string(rune(9)), true}, // \t + {string(rune(10)), false}, + {string(rune(11)), false}, + {string(rune(12)), false}, + {string(rune(13)), false}, + {string(rune(14)), false}, + {string(rune(15)), false}, + {string(rune(16)), false}, + {string(rune(17)), false}, + {string(rune(18)), false}, + {string(rune(19)), false}, + {string(rune(20)), false}, + {string(rune(21)), false}, + {string(rune(22)), false}, + {string(rune(23)), false}, + {string(rune(24)), false}, + {string(rune(25)), false}, + {string(rune(26)), false}, + {string(rune(27)), false}, + {string(rune(28)), false}, + {string(rune(29)), false}, + {string(rune(30)), false}, + {string(rune(31)), false}, + {string(rune(0x7F)), false}, {`' !"#$%&'()*+,-./:;<=>?@[\]^_{|}~`, true}, {`0123456789`, true}, {`ABCDEFGHIJKLMNOPQRSTUVWXYZ`, true}, diff --git a/libgo/go/strings/strings.go b/libgo/go/strings/strings.go index 238d657f61b..d6f5cea6e69 100644 --- a/libgo/go/strings/strings.go +++ b/libgo/go/strings/strings.go @@ -36,43 +36,6 @@ func explode(s string, n int) []string { return a } -// primeRK is the prime base used in Rabin-Karp algorithm. -const primeRK = 16777619 - -// hashStr returns the hash and the appropriate multiplicative -// factor for use in Rabin-Karp algorithm. -func hashStr(sep string) (uint32, uint32) { - hash := uint32(0) - for i := 0; i < len(sep); i++ { - hash = hash*primeRK + uint32(sep[i]) - } - var pow, sq uint32 = 1, primeRK - for i := len(sep); i > 0; i >>= 1 { - if i&1 != 0 { - pow *= sq - } - sq *= sq - } - return hash, pow -} - -// hashStrRev returns the hash of the reverse of sep and the -// appropriate multiplicative factor for use in Rabin-Karp algorithm. -func hashStrRev(sep string) (uint32, uint32) { - hash := uint32(0) - for i := len(sep) - 1; i >= 0; i-- { - hash = hash*primeRK + uint32(sep[i]) - } - var pow, sq uint32 = 1, primeRK - for i := len(sep); i > 0; i >>= 1 { - if i&1 != 0 { - pow *= sq - } - sq *= sq - } - return hash, pow -} - // Count counts the number of non-overlapping instances of substr in s. // If substr is an empty string, Count returns 1 + the number of Unicode code points in s. func Count(s, substr string) int { @@ -126,17 +89,17 @@ func LastIndex(s, substr string) int { return -1 } // Rabin-Karp search from the end of the string - hashss, pow := hashStrRev(substr) + hashss, pow := bytealg.HashStrRev(substr) last := len(s) - n var h uint32 for i := len(s) - 1; i >= last; i-- { - h = h*primeRK + uint32(s[i]) + h = h*bytealg.PrimeRK + uint32(s[i]) } if h == hashss && s[last:] == substr { return last } for i := last - 1; i >= 0; i-- { - h *= primeRK + h *= bytealg.PrimeRK h += uint32(s[i]) h -= pow * uint32(s[i+n]) if h == hashss && s[i:i+n] == substr { @@ -180,6 +143,14 @@ func IndexAny(s, chars string) int { // Avoid scanning all of s. return -1 } + if len(chars) == 1 { + // Avoid scanning all of s. + r := rune(chars[0]) + if r >= utf8.RuneSelf { + r = utf8.RuneError + } + return IndexRune(s, r) + } if len(s) > 8 { if as, isASCII := makeASCIISet(chars); isASCII { for i := 0; i < len(s); i++ { @@ -191,10 +162,8 @@ func IndexAny(s, chars string) int { } } for i, c := range s { - for _, m := range chars { - if c == m { - return i - } + if IndexRune(chars, c) >= 0 { + return i } } return -1 @@ -208,6 +177,16 @@ func LastIndexAny(s, chars string) int { // Avoid scanning all of s. return -1 } + if len(s) == 1 { + rc := rune(s[0]) + if rc >= utf8.RuneSelf { + rc = utf8.RuneError + } + if IndexRune(chars, rc) >= 0 { + return 0 + } + return -1 + } if len(s) > 8 { if as, isASCII := makeASCIISet(chars); isASCII { for i := len(s) - 1; i >= 0; i-- { @@ -218,13 +197,25 @@ func LastIndexAny(s, chars string) int { return -1 } } + if len(chars) == 1 { + rc := rune(chars[0]) + if rc >= utf8.RuneSelf { + rc = utf8.RuneError + } + for i := len(s); i > 0; { + r, size := utf8.DecodeLastRuneInString(s[:i]) + i -= size + if rc == r { + return i + } + } + return -1 + } for i := len(s); i > 0; { r, size := utf8.DecodeLastRuneInString(s[:i]) i -= size - for _, c := range chars { - if r == c { - return i - } + if IndexRune(chars, r) >= 0 { + return i } } return -1 @@ -378,8 +369,9 @@ func Fields(s string) []string { // FieldsFunc splits the string s at each run of Unicode code points c satisfying f(c) // and returns an array of slices of s. If all code points in s satisfy f(c) or the // string is empty, an empty slice is returned. -// FieldsFunc makes no guarantees about the order in which it calls f(c). -// If f does not return consistent results for a given c, FieldsFunc may crash. +// +// FieldsFunc makes no guarantees about the order in which it calls f(c) +// and assumes that f always returns the same value for a given c. func FieldsFunc(s string, f func(rune) bool) []string { // A span is used to record a slice of s of the form s[start:end]. // The start index is inclusive and the end index is exclusive. @@ -390,25 +382,29 @@ func FieldsFunc(s string, f func(rune) bool) []string { spans := make([]span, 0, 32) // Find the field start and end indices. - wasField := false - fromIndex := 0 - for i, rune := range s { + // Doing this in a separate pass (rather than slicing the string s + // and collecting the result substrings right away) is significantly + // more efficient, possibly due to cache effects. + start := -1 // valid span start if >= 0 + for end, rune := range s { if f(rune) { - if wasField { - spans = append(spans, span{start: fromIndex, end: i}) - wasField = false + if start >= 0 { + spans = append(spans, span{start, end}) + // Set start to a negative value. + // Note: using -1 here consistently and reproducibly + // slows down this code by a several percent on amd64. + start = ^start } } else { - if !wasField { - fromIndex = i - wasField = true + if start < 0 { + start = end } } } // Last field might end at EOF. - if wasField { - spans = append(spans, span{fromIndex, len(s)}) + if start >= 0 { + spans = append(spans, span{start, len(s)}) } // Create strings from recorded field indices. @@ -837,7 +833,7 @@ func makeCutsetFunc(cutset string) func(rune) bool { // Trim returns a slice of the string s with all leading and // trailing Unicode code points contained in cutset removed. -func Trim(s string, cutset string) string { +func Trim(s, cutset string) string { if s == "" || cutset == "" { return s } @@ -848,7 +844,7 @@ func Trim(s string, cutset string) string { // Unicode code points contained in cutset removed. // // To remove a prefix, use TrimPrefix instead. -func TrimLeft(s string, cutset string) string { +func TrimLeft(s, cutset string) string { if s == "" || cutset == "" { return s } @@ -859,7 +855,7 @@ func TrimLeft(s string, cutset string) string { // Unicode code points contained in cutset removed. // // To remove a suffix, use TrimSuffix instead. -func TrimRight(s string, cutset string) string { +func TrimRight(s, cutset string) string { if s == "" || cutset == "" { return s } @@ -1053,11 +1049,11 @@ func Index(s, substr string) int { if s[i] != c0 { // IndexByte is faster than bytealg.IndexString, so use it as long as // we're not getting lots of false positives. - o := IndexByte(s[i:t], c0) + o := IndexByte(s[i+1:t], c0) if o < 0 { return -1 } - i += o + i += o + 1 } if s[i+1] == c1 && s[i:i+n] == substr { return i @@ -1082,11 +1078,11 @@ func Index(s, substr string) int { fails := 0 for i < t { if s[i] != c0 { - o := IndexByte(s[i:t], c0) + o := IndexByte(s[i+1:t], c0) if o < 0 { return -1 } - i += o + i += o + 1 } if s[i+1] == c1 && s[i:i+n] == substr { return i @@ -1095,7 +1091,7 @@ func Index(s, substr string) int { fails++ if fails >= 4+i>>4 && i < t { // See comment in ../bytes/bytes.go. - j := indexRabinKarp(s[i:], substr) + j := bytealg.IndexRabinKarp(s[i:], substr) if j < 0 { return -1 } @@ -1104,26 +1100,3 @@ func Index(s, substr string) int { } return -1 } - -func indexRabinKarp(s, substr string) int { - // Rabin-Karp search - hashss, pow := hashStr(substr) - n := len(substr) - var h uint32 - for i := 0; i < n; i++ { - h = h*primeRK + uint32(s[i]) - } - if h == hashss && s[:n] == substr { - return 0 - } - for i := n; i < len(s); { - h *= primeRK - h += uint32(s[i]) - h -= pow * uint32(s[i-n]) - i++ - if h == hashss && s[i-n:i] == substr { - return i - n - } - } - return -1 -} diff --git a/libgo/go/strings/strings_test.go b/libgo/go/strings/strings_test.go index 7eddce5233f..095e4821148 100644 --- a/libgo/go/strings/strings_test.go +++ b/libgo/go/strings/strings_test.go @@ -154,6 +154,7 @@ var indexAnyTests = []IndexTest{ {"", "abc", -1}, {"a", "", -1}, {"a", "a", 0}, + {"\x80", "\xffb", 0}, {"aaa", "a", 0}, {"abc", "xyz", -1}, {"abc", "xcz", 2}, @@ -164,6 +165,7 @@ var indexAnyTests = []IndexTest{ {dots + dots + dots, " ", -1}, {"012abcba210", "\xffb", 4}, {"012\x80bcb\x80210", "\xffb", 3}, + {"0123456\xcf\x80abc", "\xcfb\x80", 10}, } var lastIndexAnyTests = []IndexTest{ @@ -172,6 +174,7 @@ var lastIndexAnyTests = []IndexTest{ {"", "abc", -1}, {"a", "", -1}, {"a", "a", 0}, + {"\x80", "\xffb", 0}, {"aaa", "a", 2}, {"abc", "xyz", -1}, {"abc", "ab", 1}, @@ -182,6 +185,7 @@ var lastIndexAnyTests = []IndexTest{ {dots + dots + dots, " ", -1}, {"012abcba210", "\xffb", 6}, {"012\x80bcb\x80210", "\xffb", 7}, + {"0123456\xcf\x80abc", "\xcfb\x80", 10}, } // Execute f on each test case. funcName should be the name of f; it's used @@ -682,8 +686,8 @@ func TestMap(t *testing.T) { } return r } - s := string(utf8.RuneSelf) + string(utf8.MaxRune) - r := string(utf8.MaxRune) + string(utf8.RuneSelf) // reverse of s + s := string(rune(utf8.RuneSelf)) + string(utf8.MaxRune) + r := string(utf8.MaxRune) + string(rune(utf8.RuneSelf)) // reverse of s m = Map(encode, s) if m != r { t.Errorf("encoding not handled correctly: expected %q got %q", r, m) @@ -1791,10 +1795,24 @@ func BenchmarkRepeat(b *testing.B) { } func BenchmarkIndexAnyASCII(b *testing.B) { - x := Repeat("#", 4096) // Never matches set - cs := "0123456789abcdef" - for k := 1; k <= 4096; k <<= 4 { - for j := 1; j <= 16; j <<= 1 { + x := Repeat("#", 2048) // Never matches set + cs := "0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz" + for k := 1; k <= 2048; k <<= 4 { + for j := 1; j <= 64; j <<= 1 { + b.Run(fmt.Sprintf("%d:%d", k, j), func(b *testing.B) { + for i := 0; i < b.N; i++ { + IndexAny(x[:k], cs[:j]) + } + }) + } + } +} + +func BenchmarkIndexAnyUTF8(b *testing.B) { + x := Repeat("#", 2048) // Never matches set + cs := "你好世界, hello world. 你好世界, hello world. 你好世界, hello world." + for k := 1; k <= 2048; k <<= 4 { + for j := 1; j <= 64; j <<= 1 { b.Run(fmt.Sprintf("%d:%d", k, j), func(b *testing.B) { for i := 0; i < b.N; i++ { IndexAny(x[:k], cs[:j]) @@ -1804,6 +1822,34 @@ func BenchmarkIndexAnyASCII(b *testing.B) { } } +func BenchmarkLastIndexAnyASCII(b *testing.B) { + x := Repeat("#", 2048) // Never matches set + cs := "0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz" + for k := 1; k <= 2048; k <<= 4 { + for j := 1; j <= 64; j <<= 1 { + b.Run(fmt.Sprintf("%d:%d", k, j), func(b *testing.B) { + for i := 0; i < b.N; i++ { + LastIndexAny(x[:k], cs[:j]) + } + }) + } + } +} + +func BenchmarkLastIndexAnyUTF8(b *testing.B) { + x := Repeat("#", 2048) // Never matches set + cs := "你好世界, hello world. 你好世界, hello world. 你好世界, hello world." + for k := 1; k <= 2048; k <<= 4 { + for j := 1; j <= 64; j <<= 1 { + b.Run(fmt.Sprintf("%d:%d", k, j), func(b *testing.B) { + for i := 0; i < b.N; i++ { + LastIndexAny(x[:k], cs[:j]) + } + }) + } + } +} + func BenchmarkTrimASCII(b *testing.B) { cs := "0123456789abcdef" for k := 1; k <= 4096; k <<= 4 { diff --git a/libgo/go/sync/atomic/atomic_test.go b/libgo/go/sync/atomic/atomic_test.go index 286eadc6cdf..83e7c8d7632 100644 --- a/libgo/go/sync/atomic/atomic_test.go +++ b/libgo/go/sync/atomic/atomic_test.go @@ -153,6 +153,21 @@ func TestSwapUintptr(t *testing.T) { } } +var global [1024]byte + +func testPointers() []unsafe.Pointer { + var pointers []unsafe.Pointer + // globals + for i := 0; i < 10; i++ { + pointers = append(pointers, unsafe.Pointer(&global[1< delta; delta += delta { - k := SwapPointer(&x.i, unsafe.Pointer(delta)) - if uintptr(x.i) != delta || uintptr(k) != j { - t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k) + var j unsafe.Pointer + + for _, p := range testPointers() { + k := SwapPointer(&x.i, p) + if x.i != p || k != j { + t.Fatalf("p=%p i=%p j=%p k=%p", p, x.i, j, k) } - j = delta + j = p } if x.before != magicptr || x.after != magicptr { t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr) @@ -456,20 +472,20 @@ func TestCompareAndSwapPointer(t *testing.T) { magicptr := uintptr(m) x.before = magicptr x.after = magicptr - for val := uintptr(1 << 16); val+val > val; val += val { - x.i = unsafe.Pointer(val) - if !CompareAndSwapPointer(&x.i, unsafe.Pointer(val), unsafe.Pointer(val+1)) { - t.Fatalf("should have swapped %#x %#x", val, val+1) + q := unsafe.Pointer(new(byte)) + for _, p := range testPointers() { + x.i = p + if !CompareAndSwapPointer(&x.i, p, q) { + t.Fatalf("should have swapped %p %p", p, q) } - if x.i != unsafe.Pointer(val+1) { - t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1) + if x.i != q { + t.Fatalf("wrong x.i after swap: x.i=%p want %p", x.i, q) } - x.i = unsafe.Pointer(val + 1) - if CompareAndSwapPointer(&x.i, unsafe.Pointer(val), unsafe.Pointer(val+2)) { - t.Fatalf("should not have swapped %#x %#x", val, val+2) + if CompareAndSwapPointer(&x.i, p, nil) { + t.Fatalf("should not have swapped %p nil", p) } - if x.i != unsafe.Pointer(val+1) { - t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1) + if x.i != q { + t.Fatalf("wrong x.i after swap: x.i=%p want %p", x.i, q) } } if x.before != magicptr || x.after != magicptr { @@ -595,12 +611,12 @@ func TestLoadPointer(t *testing.T) { magicptr := uintptr(m) x.before = magicptr x.after = magicptr - for delta := uintptr(1 << 16); delta+delta > delta; delta += delta { + for _, p := range testPointers() { + x.i = p k := LoadPointer(&x.i) - if k != x.i { - t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k) + if k != p { + t.Fatalf("p=%x k=%x", p, k) } - x.i = unsafe.Pointer(uintptr(x.i) + delta) } if x.before != magicptr || x.after != magicptr { t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr) @@ -730,13 +746,11 @@ func TestStorePointer(t *testing.T) { magicptr := uintptr(m) x.before = magicptr x.after = magicptr - v := unsafe.Pointer(uintptr(0)) - for delta := uintptr(1 << 16); delta+delta > delta; delta += delta { - StorePointer(&x.i, unsafe.Pointer(v)) - if x.i != v { - t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v) + for _, p := range testPointers() { + StorePointer(&x.i, p) + if x.i != p { + t.Fatalf("x.i=%p p=%p", x.i, p) } - v = unsafe.Pointer(uintptr(v) + delta) } if x.before != magicptr || x.after != magicptr { t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr) diff --git a/libgo/go/sync/atomic/doc.go b/libgo/go/sync/atomic/doc.go index 108b76b8049..ff4ad80049b 100644 --- a/libgo/go/sync/atomic/doc.go +++ b/libgo/go/sync/atomic/doc.go @@ -143,8 +143,3 @@ func StoreUintptr(addr *uintptr, val uintptr) // StorePointer atomically stores val into *addr. func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer) - -// Helper for ARM. Linker will discard on other systems -func panic64() { - panic("sync/atomic: broken 64-bit atomic operations (buggy QEMU)") -} diff --git a/libgo/go/sync/atomic/value_test.go b/libgo/go/sync/atomic/value_test.go index fd69ba30dc3..f2897663404 100644 --- a/libgo/go/sync/atomic/value_test.go +++ b/libgo/go/sync/atomic/value_test.go @@ -91,10 +91,11 @@ func TestValueConcurrent(t *testing.T) { } for _, test := range tests { var v Value - done := make(chan bool) + done := make(chan bool, p) for i := 0; i < p; i++ { go func() { r := rand.New(rand.NewSource(rand.Int63())) + expected := true loop: for j := 0; j < N; j++ { x := test[r.Intn(len(test))] @@ -106,9 +107,10 @@ func TestValueConcurrent(t *testing.T) { } } t.Logf("loaded unexpected value %+v, want %+v", x, test) - done <- false + expected = false + break } - done <- true + done <- expected }() } for i := 0; i < p; i++ { diff --git a/libgo/go/sync/map.go b/libgo/go/sync/map.go index c6aa3088565..a61e2ebdd67 100644 --- a/libgo/go/sync/map.go +++ b/libgo/go/sync/map.go @@ -263,8 +263,9 @@ func (e *entry) tryLoadOrStore(i interface{}) (actual interface{}, loaded, ok bo } } -// Delete deletes the value for a key. -func (m *Map) Delete(key interface{}) { +// LoadAndDelete deletes the value for a key, returning the previous value if any. +// The loaded result reports whether the key was present. +func (m *Map) LoadAndDelete(key interface{}) (value interface{}, loaded bool) { read, _ := m.read.Load().(readOnly) e, ok := read.m[key] if !ok && read.amended { @@ -272,23 +273,33 @@ func (m *Map) Delete(key interface{}) { read, _ = m.read.Load().(readOnly) e, ok = read.m[key] if !ok && read.amended { - delete(m.dirty, key) + e, ok = m.dirty[key] + // Regardless of whether the entry was present, record a miss: this key + // will take the slow path until the dirty map is promoted to the read + // map. + m.missLocked() } m.mu.Unlock() } if ok { - e.delete() + return e.delete() } + return nil, false } -func (e *entry) delete() (hadValue bool) { +// Delete deletes the value for a key. +func (m *Map) Delete(key interface{}) { + m.LoadAndDelete(key) +} + +func (e *entry) delete() (value interface{}, ok bool) { for { p := atomic.LoadPointer(&e.p) if p == nil || p == expunged { - return false + return nil, false } if atomic.CompareAndSwapPointer(&e.p, p, nil) { - return true + return *(*interface{})(p), true } } } diff --git a/libgo/go/sync/map_bench_test.go b/libgo/go/sync/map_bench_test.go index e6a8badddba..cf0a3d7fded 100644 --- a/libgo/go/sync/map_bench_test.go +++ b/libgo/go/sync/map_bench_test.go @@ -144,6 +144,66 @@ func BenchmarkLoadOrStoreCollision(b *testing.B) { }) } +func BenchmarkLoadAndDeleteBalanced(b *testing.B) { + const hits, misses = 128, 128 + + benchMap(b, bench{ + setup: func(b *testing.B, m mapInterface) { + if _, ok := m.(*DeepCopyMap); ok { + b.Skip("DeepCopyMap has quadratic running time.") + } + for i := 0; i < hits; i++ { + m.LoadOrStore(i, i) + } + // Prime the map to get it into a steady state. + for i := 0; i < hits*2; i++ { + m.Load(i % hits) + } + }, + + perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) { + for ; pb.Next(); i++ { + j := i % (hits + misses) + if j < hits { + m.LoadAndDelete(j) + } else { + m.LoadAndDelete(i) + } + } + }, + }) +} + +func BenchmarkLoadAndDeleteUnique(b *testing.B) { + benchMap(b, bench{ + setup: func(b *testing.B, m mapInterface) { + if _, ok := m.(*DeepCopyMap); ok { + b.Skip("DeepCopyMap has quadratic running time.") + } + }, + + perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) { + for ; pb.Next(); i++ { + m.LoadAndDelete(i) + } + }, + }) +} + +func BenchmarkLoadAndDeleteCollision(b *testing.B) { + benchMap(b, bench{ + setup: func(_ *testing.B, m mapInterface) { + m.LoadOrStore(0, 0) + }, + + perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) { + for ; pb.Next(); i++ { + m.LoadAndDelete(0) + } + }, + }) +} + func BenchmarkRange(b *testing.B) { const mapSize = 1 << 10 @@ -213,3 +273,17 @@ func BenchmarkAdversarialDelete(b *testing.B) { }, }) } + +func BenchmarkDeleteCollision(b *testing.B) { + benchMap(b, bench{ + setup: func(_ *testing.B, m mapInterface) { + m.LoadOrStore(0, 0) + }, + + perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) { + for ; pb.Next(); i++ { + m.Delete(0) + } + }, + }) +} diff --git a/libgo/go/sync/map_reference_test.go b/libgo/go/sync/map_reference_test.go index 9f27b07c329..d105a24e926 100644 --- a/libgo/go/sync/map_reference_test.go +++ b/libgo/go/sync/map_reference_test.go @@ -16,6 +16,7 @@ type mapInterface interface { Load(interface{}) (interface{}, bool) Store(key, value interface{}) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool) + LoadAndDelete(key interface{}) (value interface{}, loaded bool) Delete(interface{}) Range(func(key, value interface{}) (shouldContinue bool)) } @@ -56,6 +57,18 @@ func (m *RWMutexMap) LoadOrStore(key, value interface{}) (actual interface{}, lo return actual, loaded } +func (m *RWMutexMap) LoadAndDelete(key interface{}) (value interface{}, loaded bool) { + m.mu.Lock() + value, loaded = m.dirty[key] + if !loaded { + m.mu.Unlock() + return nil, false + } + delete(m.dirty, key) + m.mu.Unlock() + return value, loaded +} + func (m *RWMutexMap) Delete(key interface{}) { m.mu.Lock() delete(m.dirty, key) @@ -124,6 +137,16 @@ func (m *DeepCopyMap) LoadOrStore(key, value interface{}) (actual interface{}, l return actual, loaded } +func (m *DeepCopyMap) LoadAndDelete(key interface{}) (value interface{}, loaded bool) { + m.mu.Lock() + dirty := m.dirty() + value, loaded = dirty[key] + delete(dirty, key) + m.clean.Store(dirty) + m.mu.Unlock() + return +} + func (m *DeepCopyMap) Delete(key interface{}) { m.mu.Lock() dirty := m.dirty() diff --git a/libgo/go/sync/map_test.go b/libgo/go/sync/map_test.go index b60a1c7bede..4ae989a6d5d 100644 --- a/libgo/go/sync/map_test.go +++ b/libgo/go/sync/map_test.go @@ -16,13 +16,14 @@ import ( type mapOp string const ( - opLoad = mapOp("Load") - opStore = mapOp("Store") - opLoadOrStore = mapOp("LoadOrStore") - opDelete = mapOp("Delete") + opLoad = mapOp("Load") + opStore = mapOp("Store") + opLoadOrStore = mapOp("LoadOrStore") + opLoadAndDelete = mapOp("LoadAndDelete") + opDelete = mapOp("Delete") ) -var mapOps = [...]mapOp{opLoad, opStore, opLoadOrStore, opDelete} +var mapOps = [...]mapOp{opLoad, opStore, opLoadOrStore, opLoadAndDelete, opDelete} // mapCall is a quick.Generator for calls on mapInterface. type mapCall struct { @@ -39,6 +40,8 @@ func (c mapCall) apply(m mapInterface) (interface{}, bool) { return nil, false case opLoadOrStore: return m.LoadOrStore(c.k, c.v) + case opLoadAndDelete: + return m.LoadAndDelete(c.k) case opDelete: m.Delete(c.k) return nil, false diff --git a/libgo/go/sync/runtime.go b/libgo/go/sync/runtime.go index 3ad44e786fb..de2b0a3ccd2 100644 --- a/libgo/go/sync/runtime.go +++ b/libgo/go/sync/runtime.go @@ -28,16 +28,6 @@ func runtime_SemacquireMutex(s *uint32, lifo bool, skipframes int) // runtime_Semrelease's caller. func runtime_Semrelease(s *uint32, handoff bool, skipframes int) -// Approximation of notifyList in runtime/sema.go. Size and alignment must -// agree. -type notifyList struct { - wait uint32 - notify uint32 - lock uintptr - head unsafe.Pointer - tail unsafe.Pointer -} - // See runtime/sema.go for documentation. func runtime_notifyListAdd(l *notifyList) uint32 diff --git a/libgo/go/sync/runtime2.go b/libgo/go/sync/runtime2.go new file mode 100644 index 00000000000..931edad9f1c --- /dev/null +++ b/libgo/go/sync/runtime2.go @@ -0,0 +1,15 @@ +// +build !goexperiment.staticlockranking + +package sync + +import "unsafe" + +// Approximation of notifyList in runtime/sema.go. Size and alignment must +// agree. +type notifyList struct { + wait uint32 + notify uint32 + lock uintptr // key field of the mutex + head unsafe.Pointer + tail unsafe.Pointer +} diff --git a/libgo/go/sync/runtime2_lockrank.go b/libgo/go/sync/runtime2_lockrank.go new file mode 100644 index 00000000000..5a68e901fa8 --- /dev/null +++ b/libgo/go/sync/runtime2_lockrank.go @@ -0,0 +1,18 @@ +// +build goexperiment.staticlockranking + +package sync + +import "unsafe" + +// Approximation of notifyList in runtime/sema.go. Size and alignment must +// agree. +type notifyList struct { + wait uint32 + notify uint32 + rank int // rank field of the mutex + pad int // pad field of the mutex + lock uintptr // key field of the mutex + + head unsafe.Pointer + tail unsafe.Pointer +} diff --git a/libgo/go/sync/rwmutex_test.go b/libgo/go/sync/rwmutex_test.go index 9ee8864cebb..c98e69fd07d 100644 --- a/libgo/go/sync/rwmutex_test.go +++ b/libgo/go/sync/rwmutex_test.go @@ -59,6 +59,7 @@ func reader(rwm *RWMutex, num_iterations int, activity *int32, cdone chan bool) rwm.RLock() n := atomic.AddInt32(activity, 1) if n < 1 || n >= 10000 { + rwm.RUnlock() panic(fmt.Sprintf("wlock(%d)\n", n)) } for i := 0; i < 100; i++ { @@ -74,6 +75,7 @@ func writer(rwm *RWMutex, num_iterations int, activity *int32, cdone chan bool) rwm.Lock() n := atomic.AddInt32(activity, 10000) if n != 10000 { + rwm.Unlock() panic(fmt.Sprintf("wlock(%d)\n", n)) } for i := 0; i < 100; i++ { diff --git a/libgo/go/syscall/env_plan9.go b/libgo/go/syscall/env_plan9.go deleted file mode 100644 index e403a25e314..00000000000 --- a/libgo/go/syscall/env_plan9.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Plan 9 environment variables. - -package syscall - -import ( - "errors" -) - -var ( - errZeroLengthKey = errors.New("zero length key") - errShortWrite = errors.New("i/o count too small") -) - -func readenv(key string) (string, error) { - fd, err := open("/env/"+key, O_RDONLY) - if err != nil { - return "", err - } - defer Close(fd) - l, _ := Seek(fd, 0, 2) - Seek(fd, 0, 0) - buf := make([]byte, l) - n, err := Read(fd, buf) - if err != nil { - return "", err - } - if n > 0 && buf[n-1] == 0 { - buf = buf[:n-1] - } - return string(buf), nil -} - -func writeenv(key, value string) error { - fd, err := create("/env/"+key, O_RDWR, 0666) - if err != nil { - return err - } - defer Close(fd) - b := []byte(value) - n, err := Write(fd, b) - if err != nil { - return err - } - if n != len(b) { - return errShortWrite - } - return nil -} - -func Getenv(key string) (value string, found bool) { - if len(key) == 0 { - return "", false - } - v, err := readenv(key) - if err != nil { - return "", false - } - return v, true -} - -func Setenv(key, value string) error { - if len(key) == 0 { - return errZeroLengthKey - } - err := writeenv(key, value) - if err != nil { - return err - } - return nil -} - -func Clearenv() { - // Creating a new environment group using rfork(RFCENVG) can race - // with access to files in /env (e.g. from Setenv or Getenv). - // Remove all environment variables in current environment group instead. - fd, err := open("/env", O_RDONLY) - if err != nil { - return - } - defer Close(fd) - files, err := readdirnames(fd) - if err != nil { - return - } - for _, key := range files { - Remove("/env/" + key) - } -} - -func Unsetenv(key string) error { - if len(key) == 0 { - return errZeroLengthKey - } - Remove("/env/" + key) - return nil -} - -func Environ() []string { - fd, err := open("/env", O_RDONLY) - if err != nil { - return nil - } - defer Close(fd) - files, err := readdirnames(fd) - if err != nil { - return nil - } - ret := make([]string, 0, len(files)) - - for _, key := range files { - v, err := readenv(key) - if err != nil { - continue - } - ret = append(ret, key+"="+v) - } - return ret -} diff --git a/libgo/go/syscall/env_unix.go b/libgo/go/syscall/env_unix.go index 3564f7f38c4..c56b6b8a1c5 100644 --- a/libgo/go/syscall/env_unix.go +++ b/libgo/go/syscall/env_unix.go @@ -2,13 +2,16 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris plan9 // Unix environment variables. package syscall -import "sync" +import ( + "runtime" + "sync" +) var ( // envOnce guards initialization by copyenv, which populates env. @@ -100,9 +103,12 @@ func Setenv(key, value string) error { return EINVAL } } - for i := 0; i < len(value); i++ { - if value[i] == 0 { - return EINVAL + // On Plan 9, null is used as a separator, eg in $path. + if runtime.GOOS != "plan9" { + for i := 0; i < len(value); i++ { + if value[i] == 0 { + return EINVAL + } } } diff --git a/libgo/go/syscall/exec_bsd.go b/libgo/go/syscall/exec_bsd.go index a241e2101f4..7e06943f13e 100644 --- a/libgo/go/syscall/exec_bsd.go +++ b/libgo/go/syscall/exec_bsd.go @@ -15,12 +15,23 @@ type SysProcAttr struct { Credential *Credential // Credential. Ptrace bool // Enable tracing. Setsid bool // Create session. - Setpgid bool // Set process group ID to Pgid, or, if Pgid == 0, to new pid. - Setctty bool // Set controlling terminal to fd Ctty - Noctty bool // Detach fd 0 from controlling terminal - Ctty int // Controlling TTY fd - Foreground bool // Place child's process group in foreground. (Implies Setpgid. Uses Ctty as fd of controlling TTY) - Pgid int // Child's process group ID if Setpgid. + // Setpgid sets the process group ID of the child to Pgid, + // or, if Pgid == 0, to the new child's process ID. + Setpgid bool + // Setctty sets the controlling terminal of the child to + // file descriptor Ctty. Ctty must be a descriptor number + // in the child process: an index into ProcAttr.Files. + // This is only meaningful if Setsid is true. + Setctty bool + Noctty bool // Detach fd 0 from controlling terminal + Ctty int // Controlling TTY fd + // Foreground places the child process group in the foreground. + // This implies Setpgid. The Ctty field must be set to + // the descriptor of the controlling TTY. + // Unlike Setctty, in this case Ctty must be a descriptor + // number in the parent process. + Foreground bool + Pgid int // Child's process group ID if Setpgid. } // Implemented in runtime package. diff --git a/libgo/go/syscall/exec_darwin.go b/libgo/go/syscall/exec_darwin.go index ac1ead3a2b3..f035d555535 100644 --- a/libgo/go/syscall/exec_darwin.go +++ b/libgo/go/syscall/exec_darwin.go @@ -13,12 +13,23 @@ type SysProcAttr struct { Credential *Credential // Credential. Ptrace bool // Enable tracing. Setsid bool // Create session. - Setpgid bool // Set process group ID to Pgid, or, if Pgid == 0, to new pid. - Setctty bool // Set controlling terminal to fd Ctty - Noctty bool // Detach fd 0 from controlling terminal - Ctty int // Controlling TTY fd - Foreground bool // Place child's process group in foreground. (Implies Setpgid. Uses Ctty as fd of controlling TTY) - Pgid int // Child's process group ID if Setpgid. + // Setpgid sets the process group ID of the child to Pgid, + // or, if Pgid == 0, to the new child's process ID. + Setpgid bool + // Setctty sets the controlling terminal of the child to + // file descriptor Ctty. Ctty must be a descriptor number + // in the child process: an index into ProcAttr.Files. + // This is only meaningful if Setsid is true. + Setctty bool + Noctty bool // Detach fd 0 from controlling terminal + Ctty int // Controlling TTY fd + // Foreground places the child process group in the foreground. + // This implies Setpgid. The Ctty field must be set to + // the descriptor of the controlling TTY. + // Unlike Setctty, in this case Ctty must be a descriptor + // number in the parent process. + Foreground bool + Pgid int // Child's process group ID if Setpgid. } // Implemented in runtime package. diff --git a/libgo/go/syscall/exec_linux.go b/libgo/go/syscall/exec_linux.go index f842cdc85bf..2f0a34fef0b 100644 --- a/libgo/go/syscall/exec_linux.go +++ b/libgo/go/syscall/exec_linux.go @@ -36,13 +36,24 @@ type SysProcAttr struct { // Ptrace tells the child to call ptrace(PTRACE_TRACEME). // Call runtime.LockOSThread before starting a process with this set, // and don't call UnlockOSThread until done with PtraceSyscall calls. - Ptrace bool - Setsid bool // Create session. - Setpgid bool // Set process group ID to Pgid, or, if Pgid == 0, to new pid. - Setctty bool // Set controlling terminal to fd Ctty (only meaningful if Setsid is set) - Noctty bool // Detach fd 0 from controlling terminal - Ctty int // Controlling TTY fd - Foreground bool // Place child's process group in foreground. (Implies Setpgid. Uses Ctty as fd of controlling TTY) + Ptrace bool + Setsid bool // Create session. + // Setpgid sets the process group ID of the child to Pgid, + // or, if Pgid == 0, to the new child's process ID. + Setpgid bool + // Setctty sets the controlling terminal of the child to + // file descriptor Ctty. Ctty must be a descriptor number + // in the child process: an index into ProcAttr.Files. + // This is only meaningful if Setsid is true. + Setctty bool + Noctty bool // Detach fd 0 from controlling terminal + Ctty int // Controlling TTY fd + // Foreground places the child process group in the foreground. + // This implies Setpgid. The Ctty field must be set to + // the descriptor of the controlling TTY. + // Unlike Setctty, in this case Ctty must be a descriptor + // number in the parent process. + Foreground bool Pgid int // Child's process group ID if Setpgid. Pdeathsig Signal // Signal that the process will get when its parent dies (Linux only) Cloneflags uintptr // Flags for clone calls (Linux only) @@ -443,11 +454,16 @@ func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, att // Pass 1: look for fd[i] < i and move those up above len(fd) // so that pass 2 won't stomp on an fd it needs later. if pipe < nextfd { - err1 = raw_dup2(pipe, nextfd) - if err1 != 0 { + err1 = raw_dup3(pipe, nextfd, O_CLOEXEC) + if err1 == ENOSYS { + err1 = raw_dup2(pipe, nextfd) + if err1 != 0 { + goto childerror + } + raw_fcntl(nextfd, F_SETFD, FD_CLOEXEC) + } else if err1 != 0 { goto childerror } - raw_fcntl(nextfd, F_SETFD, FD_CLOEXEC) pipe = nextfd nextfd++ } @@ -456,11 +472,16 @@ func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, att if nextfd == pipe { // don't stomp on pipe nextfd++ } - err1 = raw_dup2(fd[i], nextfd) - if err1 != 0 { + err1 = raw_dup3(fd[i], nextfd, O_CLOEXEC) + if err1 == ENOSYS { + err1 = raw_dup2(fd[i], nextfd) + if err1 != 0 { + goto childerror + } + raw_fcntl(nextfd, F_SETFD, FD_CLOEXEC) + } else if err1 != 0 { goto childerror } - raw_fcntl(nextfd, F_SETFD, FD_CLOEXEC) fd[i] = nextfd nextfd++ } diff --git a/libgo/go/syscall/exec_unix.go b/libgo/go/syscall/exec_unix.go index e6e4ae2b06b..7c6d9425ab3 100644 --- a/libgo/go/syscall/exec_unix.go +++ b/libgo/go/syscall/exec_unix.go @@ -9,6 +9,7 @@ package syscall import ( + errorspkg "errors" "internal/bytealg" "runtime" "sync" @@ -63,6 +64,9 @@ import ( //sysnb raw_dup2(oldfd int, newfd int) (err Errno) //dup2(oldfd _C_int, newfd _C_int) _C_int +//sysnb raw_dup3(oldfd int, newfd int, flags int) (err Errno) +//dup3(oldfd _C_int, newfd _C_int, flags _C_int) _C_int + //sysnb raw_kill(pid Pid_t, sig Signal) (err Errno) //kill(pid Pid_t, sig _C_int) _C_int @@ -241,6 +245,15 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) } } + // Both Setctty and Foreground use the Ctty field, + // but they give it slightly different meanings. + if sys.Setctty && sys.Foreground { + return 0, errorspkg.New("both Setctty and Foreground set in SysProcAttr") + } + if sys.Setctty && sys.Ctty >= len(attr.Files) { + return 0, errorspkg.New("Setctty set but Ctty not valid in child") + } + // Acquire the fork lock so that no other threads // create new fds that are not yet close-on-exec // before we fork. @@ -261,7 +274,12 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) // Read child error status from pipe. Close(p[1]) - n, err = readlen(p[0], (*byte)(unsafe.Pointer(&err1)), int(unsafe.Sizeof(err1))) + for { + n, err = readlen(p[0], (*byte)(unsafe.Pointer(&err1)), int(unsafe.Sizeof(err1))) + if err != EINTR { + break + } + } Close(p[0]) if err != nil || n != 0 { if n == int(unsafe.Sizeof(err1)) { diff --git a/libgo/go/syscall/exec_unix_test.go b/libgo/go/syscall/exec_unix_test.go index 3bd95bd07e4..fab80e75c58 100644 --- a/libgo/go/syscall/exec_unix_test.go +++ b/libgo/go/syscall/exec_unix_test.go @@ -217,3 +217,31 @@ func TestForeground(t *testing.T) { signal.Reset() } + +// Test a couple of cases that SysProcAttr can't handle. Issue 29458. +func TestInvalidExec(t *testing.T) { + t.Parallel() + t.Run("SetCtty-Foreground", func(t *testing.T) { + t.Parallel() + cmd := create(t) + cmd.proc.SysProcAttr = &syscall.SysProcAttr{ + Setctty: true, + Foreground: true, + Ctty: 0, + } + if err := cmd.proc.Start(); err == nil { + t.Error("expected error setting both SetCtty and Foreground") + } + }) + t.Run("invalid-Ctty", func(t *testing.T) { + t.Parallel() + cmd := create(t) + cmd.proc.SysProcAttr = &syscall.SysProcAttr{ + Setctty: true, + Ctty: 3, + } + if err := cmd.proc.Start(); err == nil { + t.Error("expected error with invalid Ctty value") + } + }) +} diff --git a/libgo/go/syscall/fs_js.go b/libgo/go/syscall/fs_js.go index 16d9f58b8c4..262ec28afdd 100644 --- a/libgo/go/syscall/fs_js.go +++ b/libgo/go/syscall/fs_js.go @@ -102,6 +102,10 @@ func Open(path string, openmode int, perm uint32) (int, error) { } } + if path[0] != '/' { + cwd := jsProcess.Call("cwd").String() + path = cwd + "/" + path + } f := &jsFile{ path: path, entries: entries, @@ -495,7 +499,7 @@ func fsCall(name string, args ...interface{}) (js.Value, error) { } c := make(chan callResult, 1) - jsFS.Call(name, append(args, js.FuncOf(func(this js.Value, args []js.Value) interface{} { + f := js.FuncOf(func(this js.Value, args []js.Value) interface{} { var res callResult if len(args) >= 1 { // on Node.js 8, fs.utimes calls the callback without any arguments @@ -511,7 +515,9 @@ func fsCall(name string, args ...interface{}) (js.Value, error) { c <- res return nil - }))...) + }) + defer f.Release() + jsFS.Call(name, append(args, f)...) res := <-c return res.val, res.err } diff --git a/libgo/go/syscall/js/func.go b/libgo/go/syscall/js/func.go index 6c145c9da6f..da4cf68774d 100644 --- a/libgo/go/syscall/js/func.go +++ b/libgo/go/syscall/js/func.go @@ -22,19 +22,24 @@ type Func struct { id uint32 } -// FuncOf returns a wrapped function. +// FuncOf returns a function to be used by JavaScript. // -// Invoking the JavaScript function will synchronously call the Go function fn with the value of JavaScript's -// "this" keyword and the arguments of the invocation. -// The return value of the invocation is the result of the Go function mapped back to JavaScript according to ValueOf. +// The Go function fn is called with the value of JavaScript's "this" keyword and the +// arguments of the invocation. The return value of the invocation is +// the result of the Go function mapped back to JavaScript according to ValueOf. // -// A wrapped function triggered during a call from Go to JavaScript gets executed on the same goroutine. -// A wrapped function triggered by JavaScript's event loop gets executed on an extra goroutine. -// Blocking operations in the wrapped function will block the event loop. -// As a consequence, if one wrapped function blocks, other wrapped funcs will not be processed. -// A blocking function should therefore explicitly start a new goroutine. +// Invoking the wrapped Go function from JavaScript will +// pause the event loop and spawn a new goroutine. +// Other wrapped functions which are triggered during a call from Go to JavaScript +// get executed on the same goroutine. // -// Func.Release must be called to free up resources when the function will not be used any more. +// As a consequence, if one wrapped function blocks, JavaScript's event loop +// is blocked until that function returns. Hence, calling any async JavaScript +// API, which requires the event loop, like fetch (http.Client), will cause an +// immediate deadlock. Therefore a blocking function should explicitly start a +// new goroutine. +// +// Func.Release must be called to free up resources when the function will not be invoked any more. func FuncOf(fn func(this Value, args []Value) interface{}) Func { funcsMu.Lock() id := nextFuncID @@ -49,6 +54,7 @@ func FuncOf(fn func(this Value, args []Value) interface{}) Func { // Release frees up resources allocated for the function. // The function must not be invoked after calling Release. +// It is allowed to call Release while the function is still running. func (c Func) Release() { funcsMu.Lock() delete(funcs, c.id) diff --git a/libgo/go/syscall/js/js.go b/libgo/go/syscall/js/js.go index 8a043991711..a48bbd4dd79 100644 --- a/libgo/go/syscall/js/js.go +++ b/libgo/go/syscall/js/js.go @@ -565,28 +565,28 @@ func (e *ValueError) Error() string { return "syscall/js: call of " + e.Method + " on " + e.Type.String() } -// CopyBytesToGo copies bytes from the Uint8Array src to dst. +// CopyBytesToGo copies bytes from src to dst. +// It panics if src is not an Uint8Array or Uint8ClampedArray. // It returns the number of bytes copied, which will be the minimum of the lengths of src and dst. -// CopyBytesToGo panics if src is not an Uint8Array. func CopyBytesToGo(dst []byte, src Value) int { n, ok := copyBytesToGo(dst, src.ref) runtime.KeepAlive(src) if !ok { - panic("syscall/js: CopyBytesToGo: expected src to be an Uint8Array") + panic("syscall/js: CopyBytesToGo: expected src to be an Uint8Array or Uint8ClampedArray") } return n } func copyBytesToGo(dst []byte, src ref) (int, bool) -// CopyBytesToJS copies bytes from src to the Uint8Array dst. +// CopyBytesToJS copies bytes from src to dst. +// It panics if dst is not an Uint8Array or Uint8ClampedArray. // It returns the number of bytes copied, which will be the minimum of the lengths of src and dst. -// CopyBytesToJS panics if dst is not an Uint8Array. func CopyBytesToJS(dst Value, src []byte) int { n, ok := copyBytesToJS(dst.ref, src) runtime.KeepAlive(dst) if !ok { - panic("syscall/js: CopyBytesToJS: expected dst to be an Uint8Array") + panic("syscall/js: CopyBytesToJS: expected dst to be an Uint8Array or Uint8ClampedArray") } return n } diff --git a/libgo/go/syscall/js/js_test.go b/libgo/go/syscall/js/js_test.go index fea4c135afc..5fc9107d402 100644 --- a/libgo/go/syscall/js/js_test.go +++ b/libgo/go/syscall/js/js_test.go @@ -591,3 +591,14 @@ func BenchmarkDOM(b *testing.B) { document.Get("body").Call("removeChild", div) } } + +func TestGlobal(t *testing.T) { + ident := js.FuncOf(func(this js.Value, args []js.Value) interface{} { + return args[0] + }) + defer ident.Release() + + if got := ident.Invoke(js.Global()); !got.Equal(js.Global()) { + t.Errorf("got %#v, want %#v", got, js.Global()) + } +} diff --git a/libgo/go/syscall/security_windows.go b/libgo/go/syscall/security_windows.go index 3a757596066..67102b69297 100644 --- a/libgo/go/syscall/security_windows.go +++ b/libgo/go/syscall/security_windows.go @@ -163,7 +163,7 @@ func (sid *SID) String() (string, error) { return "", e } defer LocalFree((Handle)(unsafe.Pointer(s))) - return utf16PtrToString(s, 256), nil + return utf16PtrToString(s), nil } // Len returns the length, in bytes, of a valid security identifier sid. diff --git a/libgo/go/syscall/syscall_unix.go b/libgo/go/syscall/syscall_unix.go index 16e4d480b02..4d963fbd938 100644 --- a/libgo/go/syscall/syscall_unix.go +++ b/libgo/go/syscall/syscall_unix.go @@ -8,6 +8,7 @@ package syscall import ( "internal/race" + "internal/unsafeheader" "runtime" "sync" "unsafe" @@ -55,15 +56,12 @@ func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (d return nil, errno } - // Slice memory layout - var sl = struct { - addr uintptr - len int - cap int - }{addr, length, length} - - // Use unsafe to turn sl into a []byte. - b := *(*[]byte)(unsafe.Pointer(&sl)) + // Use unsafe to turn addr into a []byte. + var b []byte + hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b)) + hdr.Data = unsafe.Pointer(addr) + hdr.Cap = length + hdr.Len = length // Register mapping in m and return it. p := &b[cap(b)-1] diff --git a/libgo/go/syscall/syscall_unix_test.go b/libgo/go/syscall/syscall_unix_test.go index b99e07dd38b..a6b70d40dac 100644 --- a/libgo/go/syscall/syscall_unix_test.go +++ b/libgo/go/syscall/syscall_unix_test.go @@ -72,7 +72,7 @@ func _() { // Thus this test also verifies that the Flock_t structure can be // roundtripped with F_SETLK and F_GETLK. func TestFcntlFlock(t *testing.T) { - if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { + if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" { t.Skip("skipping; no child processes allowed on iOS") } flock := syscall.Flock_t{ diff --git a/libgo/go/testing/helper_test.go b/libgo/go/testing/helper_test.go index fe8ff056abc..7ce58c67fbc 100644 --- a/libgo/go/testing/helper_test.go +++ b/libgo/go/testing/helper_test.go @@ -33,6 +33,8 @@ helperfuncs_test.go:45: 5 helperfuncs_test.go:21: 6 helperfuncs_test.go:44: 7 helperfuncs_test.go:56: 8 +helperfuncs_test.go:64: 9 +helperfuncs_test.go:60: 10 ` lines := strings.Split(buf.String(), "\n") durationRE := regexp.MustCompile(`\(.*\)$`) diff --git a/libgo/go/testing/helperfuncs_test.go b/libgo/go/testing/helperfuncs_test.go index f2d54b3a991..df0476ed732 100644 --- a/libgo/go/testing/helperfuncs_test.go +++ b/libgo/go/testing/helperfuncs_test.go @@ -54,6 +54,17 @@ func testHelper(t *T) { // has no effect. t.Helper() t.Error("8") + + // Check that right caller is reported for func passed to Cleanup when + // multiple cleanup functions have been registered. + t.Cleanup(func() { + t.Helper() + t.Error("10") + }) + t.Cleanup(func() { + t.Helper() + t.Error("9") + }) } func parallelTestHelper(t *T) { diff --git a/libgo/go/testing/testing.go b/libgo/go/testing/testing.go index 9f47eb8584f..6f0935850bd 100644 --- a/libgo/go/testing/testing.go +++ b/libgo/go/testing/testing.go @@ -37,17 +37,17 @@ // https://golang.org/cmd/go/#hdr-Testing_flags // // A sample benchmark function looks like this: -// func BenchmarkHello(b *testing.B) { +// func BenchmarkRandInt(b *testing.B) { // for i := 0; i < b.N; i++ { -// fmt.Sprintf("hello") +// rand.Int() // } // } // // The benchmark function must run the target code b.N times. // During benchmark execution, b.N is adjusted until the benchmark function lasts // long enough to be timed reliably. The output -// BenchmarkHello 10000000 282 ns/op -// means that the loop ran 10000000 times at a speed of 282 ns per loop. +// BenchmarkRandInt-8 68453040 17.8 ns/op +// means that the loop ran 68453040 times at a speed of 17.8 ns per loop. // // If a benchmark needs some expensive setup before running, the timer // may be reset: @@ -217,10 +217,14 @@ // // then the generated test will call TestMain(m) instead of running the tests // directly. TestMain runs in the main goroutine and can do whatever setup -// and teardown is necessary around a call to m.Run. It should then call -// os.Exit with the result of m.Run. When TestMain is called, flag.Parse has -// not been run. If TestMain depends on command-line flags, including those -// of the testing package, it should call flag.Parse explicitly. +// and teardown is necessary around a call to m.Run. m.Run will return an exit +// code that may be passed to os.Exit. If TestMain returns, the test wrapper +// will pass the result of m.Run to os.Exit itself. +// +// When TestMain is called, flag.Parse has not been run. If TestMain depends on +// command-line flags, including those of the testing package, it should call +// flag.Parse explicitly. Command line flags are always parsed by the time test +// or benchmark functions run. // // A simple implementation of TestMain is: // @@ -238,6 +242,7 @@ import ( "fmt" "internal/race" "io" + "io/ioutil" "os" "runtime" "runtime/debug" @@ -379,15 +384,17 @@ const maxStackLen = 50 // common holds the elements common between T and B and // captures common methods such as Errorf. type common struct { - mu sync.RWMutex // guards this group of fields - output []byte // Output generated by test or benchmark. - w io.Writer // For flushToParent. - ran bool // Test or benchmark (or one of its subtests) was executed. - failed bool // Test or benchmark has failed. - skipped bool // Test of benchmark has been skipped. - done bool // Test is finished and all subtests have completed. - helpers map[string]struct{} // functions to be skipped when writing file/line info - cleanup func() // optional function to be called at the end of the test + mu sync.RWMutex // guards this group of fields + output []byte // Output generated by test or benchmark. + w io.Writer // For flushToParent. + ran bool // Test or benchmark (or one of its subtests) was executed. + failed bool // Test or benchmark has failed. + skipped bool // Test of benchmark has been skipped. + done bool // Test is finished and all subtests have completed. + helpers map[string]struct{} // functions to be skipped when writing file/line info + cleanup func() // optional function to be called at the end of the test + cleanupName string // Name of the cleanup function. + cleanupPc []uintptr // The stack trace at the point where Cleanup was called. chatty bool // A copy of the chatty flag. bench bool // Whether the current test is a benchmark. @@ -405,6 +412,11 @@ type common struct { barrier chan bool // To signal parallel subtests they may start. signal chan bool // To signal a test is done. sub []*T // Queue of subtests to be run in parallel. + + tempDirOnce sync.Once + tempDir string + tempDirErr error + tempDirSeq int32 } // Short reports whether the -test.short flag is set. @@ -464,6 +476,10 @@ func (c *common) frameSkip(skip int) runtime.Frame { var firstFrame, prevFrame, frame runtime.Frame for more := true; more; prevFrame = frame { frame, more = frames.Next() + if frame.Function == c.cleanupName { + frames = runtime.CallersFrames(c.cleanupPc) + continue + } if firstFrame.PC == 0 { firstFrame = frame } @@ -601,6 +617,7 @@ type TB interface { SkipNow() Skipf(format string, args ...interface{}) Skipped() bool + TempDir() string // A private method to prevent users implementing the // interface and so future additions to it will not @@ -866,12 +883,64 @@ func (c *common) Cleanup(f func()) { c.mu.Lock() defer c.mu.Unlock() oldCleanup := c.cleanup + oldCleanupPc := c.cleanupPc c.cleanup = func() { if oldCleanup != nil { - defer oldCleanup() + defer func() { + c.cleanupPc = oldCleanupPc + oldCleanup() + }() } + c.cleanupName = callerName(0) f() } + var pc [maxStackLen]uintptr + // Skip two extra frames to account for this function and runtime.Callers itself. + n := runtime.Callers(2, pc[:]) + c.cleanupPc = pc[:n] +} + +var tempDirReplacer struct { + sync.Once + r *strings.Replacer +} + +// TempDir returns a temporary directory for the test to use. +// The directory is automatically removed by Cleanup when the test and +// all its subtests complete. +// Each subsequent call to t.TempDir returns a unique directory; +// if the directory creation fails, TempDir terminates the test by calling Fatal. +func (c *common) TempDir() string { + // Use a single parent directory for all the temporary directories + // created by a test, each numbered sequentially. + c.tempDirOnce.Do(func() { + c.Helper() + + // ioutil.TempDir doesn't like path separators in its pattern, + // so mangle the name to accommodate subtests. + tempDirReplacer.Do(func() { + tempDirReplacer.r = strings.NewReplacer("/", "_", "\\", "_", ":", "_") + }) + pattern := tempDirReplacer.r.Replace(c.Name()) + + c.tempDir, c.tempDirErr = ioutil.TempDir("", pattern) + if c.tempDirErr == nil { + c.Cleanup(func() { + if err := os.RemoveAll(c.tempDir); err != nil { + c.Errorf("TempDir RemoveAll cleanup: %v", err) + } + }) + } + }) + if c.tempDirErr != nil { + c.Fatalf("TempDir: %v", c.tempDirErr) + } + seq := atomic.AddInt32(&c.tempDirSeq, 1) + dir := fmt.Sprintf("%s%c%03d", c.tempDir, os.PathSeparator, seq) + if err := os.Mkdir(dir, 0777); err != nil { + c.Fatalf("TempDir: %v", err) + } + return dir } // panicHanding is an argument to runCleanup. @@ -1132,10 +1201,20 @@ func (t *T) Run(name string, f func(t *T)) bool { return !t.failed } +// Deadline reports the time at which the test binary will have +// exceeded the timeout specified by the -timeout flag. +// +// The ok result is false if the -timeout flag indicates “no timeout” (0). +func (t *T) Deadline() (deadline time.Time, ok bool) { + deadline = t.context.deadline + return deadline, !deadline.IsZero() +} + // testContext holds all fields that are common to all tests. This includes // synchronization primitives to run at most *parallel tests. type testContext struct { - match *matcher + match *matcher + deadline time.Time mu sync.Mutex @@ -1221,6 +1300,10 @@ type M struct { afterOnce sync.Once numRun int + + // value to pass to os.Exit, the outer test func main + // harness calls os.Exit with this code. See #34129. + exitCode int } // testDeps is an internal interface of functionality that is @@ -1251,7 +1334,11 @@ func MainStart(deps testDeps, tests []InternalTest, benchmarks []InternalBenchma } // Run runs the tests. It returns an exit code to pass to os.Exit. -func (m *M) Run() int { +func (m *M) Run() (code int) { + defer func() { + code = m.exitCode + }() + // Count the number of calls to m.Run. // We only ever expected 1, but we didn't enforce that, // and now there are tests in the wild that call m.Run multiple times. @@ -1268,21 +1355,23 @@ func (m *M) Run() int { if *parallel < 1 { fmt.Fprintln(os.Stderr, "testing: -parallel can only be given a positive integer") flag.Usage() - return 2 + m.exitCode = 2 + return } if len(*matchList) != 0 { listTests(m.deps.MatchString, m.tests, m.benchmarks, m.examples) - return 0 + m.exitCode = 0 + return } parseCpuList() m.before() defer m.after() - m.startAlarm() + deadline := m.startAlarm() haveExamples = len(m.examples) > 0 - testRan, testOk := runTests(m.deps.MatchString, m.tests) + testRan, testOk := runTests(m.deps.MatchString, m.tests, deadline) exampleRan, exampleOk := runExamples(m.deps.MatchString, m.examples) m.stopAlarm() if !testRan && !exampleRan && *matchBenchmarks == "" { @@ -1290,11 +1379,13 @@ func (m *M) Run() int { } if !testOk || !exampleOk || !runBenchmarks(m.deps.ImportPath(), m.deps.MatchString, m.benchmarks) || race.Errors() > 0 { fmt.Println("FAIL") - return 1 + m.exitCode = 1 + return } fmt.Println("PASS") - return 0 + m.exitCode = 0 + return } func (t *T) report() { @@ -1340,14 +1431,18 @@ func listTests(matchString func(pat, str string) (bool, error), tests []Internal // RunTests is an internal function but exported because it is cross-package; // it is part of the implementation of the "go test" command. func RunTests(matchString func(pat, str string) (bool, error), tests []InternalTest) (ok bool) { - ran, ok := runTests(matchString, tests) + var deadline time.Time + if *timeout > 0 { + deadline = time.Now().Add(*timeout) + } + ran, ok := runTests(matchString, tests, deadline) if !ran && !haveExamples { fmt.Fprintln(os.Stderr, "testing: warning: no tests to run") } return ok } -func runTests(matchString func(pat, str string) (bool, error), tests []InternalTest) (ran, ok bool) { +func runTests(matchString func(pat, str string) (bool, error), tests []InternalTest, deadline time.Time) (ran, ok bool) { ok = true for _, procs := range cpuList { runtime.GOMAXPROCS(procs) @@ -1356,6 +1451,7 @@ func runTests(matchString func(pat, str string) (bool, error), tests []InternalT break } ctx := newTestContext(*parallel, newMatcher(matchString, *match, "-test.run")) + ctx.deadline = deadline t := &T{ common: common{ signal: make(chan bool), @@ -1537,14 +1633,18 @@ func toOutputDir(path string) string { } // startAlarm starts an alarm if requested. -func (m *M) startAlarm() { - if *timeout > 0 { - m.timer = time.AfterFunc(*timeout, func() { - m.after() - debug.SetTraceback("all") - panic(fmt.Sprintf("test timed out after %v", *timeout)) - }) +func (m *M) startAlarm() time.Time { + if *timeout <= 0 { + return time.Time{} } + + deadline := time.Now().Add(*timeout) + m.timer = time.AfterFunc(*timeout, func() { + m.after() + debug.SetTraceback("all") + panic(fmt.Sprintf("test timed out after %v", *timeout)) + }) + return deadline } // stopAlarm turns off the alarm. diff --git a/libgo/go/testing/testing_test.go b/libgo/go/testing/testing_test.go index 45e44683b43..dbef7066e0e 100644 --- a/libgo/go/testing/testing_test.go +++ b/libgo/go/testing/testing_test.go @@ -5,7 +5,9 @@ package testing_test import ( + "io/ioutil" "os" + "path/filepath" "testing" ) @@ -16,3 +18,63 @@ import ( func TestMain(m *testing.M) { os.Exit(m.Run()) } + +func TestTempDir(t *testing.T) { + testTempDir(t) + t.Run("InSubtest", testTempDir) + t.Run("test/subtest", testTempDir) + t.Run("test\\subtest", testTempDir) + t.Run("test:subtest", testTempDir) + t.Run("test/..", testTempDir) + t.Run("../test", testTempDir) +} + +func testTempDir(t *testing.T) { + dirCh := make(chan string, 1) + t.Cleanup(func() { + // Verify directory has been removed. + select { + case dir := <-dirCh: + fi, err := os.Stat(dir) + if os.IsNotExist(err) { + // All good + return + } + if err != nil { + t.Fatal(err) + } + t.Errorf("directory %q stil exists: %v, isDir=%v", dir, fi, fi.IsDir()) + default: + if !t.Failed() { + t.Fatal("never received dir channel") + } + } + }) + + dir := t.TempDir() + if dir == "" { + t.Fatal("expected dir") + } + dir2 := t.TempDir() + if dir == dir2 { + t.Fatal("subsequent calls to TempDir returned the same directory") + } + if filepath.Dir(dir) != filepath.Dir(dir2) { + t.Fatalf("calls to TempDir do not share a parent; got %q, %q", dir, dir2) + } + dirCh <- dir + fi, err := os.Stat(dir) + if err != nil { + t.Fatal(err) + } + if !fi.IsDir() { + t.Errorf("dir %q is not a dir", dir) + } + fis, err := ioutil.ReadDir(dir) + if err != nil { + t.Fatal(err) + } + if len(fis) > 0 { + t.Errorf("unexpected %d files in TempDir: %v", len(fis), fis) + } +} diff --git a/libgo/go/text/template/exec_test.go b/libgo/go/text/template/exec_test.go index f92ac6f92ff..be7147a8395 100644 --- a/libgo/go/text/template/exec_test.go +++ b/libgo/go/text/template/exec_test.go @@ -911,9 +911,9 @@ func TestJSEscaping(t *testing.T) { {`Go "jump" \`, `Go \"jump\" \\`}, {`Yukihiro says "今日は世界"`, `Yukihiro says \"今日は世界\"`}, {"unprintable \uFDFF", `unprintable \uFDFF`}, - {``, `\x3Chtml\x3E`}, - {`no = in attributes`, `no \x3D in attributes`}, - {`' does not become HTML entity`, `\x26#x27; does not become HTML entity`}, + {``, `\u003Chtml\u003E`}, + {`no = in attributes`, `no \u003D in attributes`}, + {`' does not become HTML entity`, `\u0026#x27; does not become HTML entity`}, } for _, tc := range testCases { s := JSEscapeString(tc.in) diff --git a/libgo/go/text/template/funcs.go b/libgo/go/text/template/funcs.go index 46125bc2168..1b6940a84ae 100644 --- a/libgo/go/text/template/funcs.go +++ b/libgo/go/text/template/funcs.go @@ -12,6 +12,7 @@ import ( "net/url" "reflect" "strings" + "sync" "unicode" "unicode/utf8" ) @@ -29,31 +30,49 @@ import ( // type can return interface{} or reflect.Value. type FuncMap map[string]interface{} -var builtins = FuncMap{ - "and": and, - "call": call, - "html": HTMLEscaper, - "index": index, - "slice": slice, - "js": JSEscaper, - "len": length, - "not": not, - "or": or, - "print": fmt.Sprint, - "printf": fmt.Sprintf, - "println": fmt.Sprintln, - "urlquery": URLQueryEscaper, - - // Comparisons - "eq": eq, // == - "ge": ge, // >= - "gt": gt, // > - "le": le, // <= - "lt": lt, // < - "ne": ne, // != -} - -var builtinFuncs = createValueFuncs(builtins) +// builtins returns the FuncMap. +// It is not a global variable so the linker can dead code eliminate +// more when this isn't called. See golang.org/issue/36021. +// TODO: revert this back to a global map once golang.org/issue/2559 is fixed. +func builtins() FuncMap { + return FuncMap{ + "and": and, + "call": call, + "html": HTMLEscaper, + "index": index, + "slice": slice, + "js": JSEscaper, + "len": length, + "not": not, + "or": or, + "print": fmt.Sprint, + "printf": fmt.Sprintf, + "println": fmt.Sprintln, + "urlquery": URLQueryEscaper, + + // Comparisons + "eq": eq, // == + "ge": ge, // >= + "gt": gt, // > + "le": le, // <= + "lt": lt, // < + "ne": ne, // != + } +} + +var builtinFuncsOnce struct { + sync.Once + v map[string]reflect.Value +} + +// builtinFuncsOnce lazily computes & caches the builtinFuncs map. +// TODO: revert this back to a global map once golang.org/issue/2559 is fixed. +func builtinFuncs() map[string]reflect.Value { + builtinFuncsOnce.Do(func() { + builtinFuncsOnce.v = createValueFuncs(builtins()) + }) + return builtinFuncsOnce.v +} // createValueFuncs turns a FuncMap into a map[string]reflect.Value func createValueFuncs(funcMap FuncMap) map[string]reflect.Value { @@ -125,7 +144,7 @@ func findFunction(name string, tmpl *Template) (reflect.Value, bool) { return fn, true } } - if fn := builtinFuncs[name]; fn.IsValid() { + if fn := builtinFuncs()[name]; fn.IsValid() { return fn, true } return reflect.Value{}, false @@ -185,41 +204,41 @@ func indexArg(index reflect.Value, cap int) (int, error) { // arguments. Thus "index x 1 2 3" is, in Go syntax, x[1][2][3]. Each // indexed item must be a map, slice, or array. func index(item reflect.Value, indexes ...reflect.Value) (reflect.Value, error) { - v := indirectInterface(item) - if !v.IsValid() { + item = indirectInterface(item) + if !item.IsValid() { return reflect.Value{}, fmt.Errorf("index of untyped nil") } - for _, i := range indexes { - index := indirectInterface(i) + for _, index := range indexes { + index = indirectInterface(index) var isNil bool - if v, isNil = indirect(v); isNil { + if item, isNil = indirect(item); isNil { return reflect.Value{}, fmt.Errorf("index of nil pointer") } - switch v.Kind() { + switch item.Kind() { case reflect.Array, reflect.Slice, reflect.String: - x, err := indexArg(index, v.Len()) + x, err := indexArg(index, item.Len()) if err != nil { return reflect.Value{}, err } - v = v.Index(x) + item = item.Index(x) case reflect.Map: - index, err := prepareArg(index, v.Type().Key()) + index, err := prepareArg(index, item.Type().Key()) if err != nil { return reflect.Value{}, err } - if x := v.MapIndex(index); x.IsValid() { - v = x + if x := item.MapIndex(index); x.IsValid() { + item = x } else { - v = reflect.Zero(v.Type().Elem()) + item = reflect.Zero(item.Type().Elem()) } case reflect.Invalid: - // the loop holds invariant: v.IsValid() + // the loop holds invariant: item.IsValid() panic("unreachable") default: - return reflect.Value{}, fmt.Errorf("can't index item of type %s", v.Type()) + return reflect.Value{}, fmt.Errorf("can't index item of type %s", item.Type()) } } - return v, nil + return item, nil } // Slicing. @@ -229,29 +248,27 @@ func index(item reflect.Value, indexes ...reflect.Value) (reflect.Value, error) // is x[:], "slice x 1" is x[1:], and "slice x 1 2 3" is x[1:2:3]. The first // argument must be a string, slice, or array. func slice(item reflect.Value, indexes ...reflect.Value) (reflect.Value, error) { - var ( - cap int - v = indirectInterface(item) - ) - if !v.IsValid() { + item = indirectInterface(item) + if !item.IsValid() { return reflect.Value{}, fmt.Errorf("slice of untyped nil") } if len(indexes) > 3 { return reflect.Value{}, fmt.Errorf("too many slice indexes: %d", len(indexes)) } - switch v.Kind() { + var cap int + switch item.Kind() { case reflect.String: if len(indexes) == 3 { return reflect.Value{}, fmt.Errorf("cannot 3-index slice a string") } - cap = v.Len() + cap = item.Len() case reflect.Array, reflect.Slice: - cap = v.Cap() + cap = item.Cap() default: - return reflect.Value{}, fmt.Errorf("can't slice item of type %s", v.Type()) + return reflect.Value{}, fmt.Errorf("can't slice item of type %s", item.Type()) } // set default values for cases item[:], item[i:]. - idx := [3]int{0, v.Len()} + idx := [3]int{0, item.Len()} for i, index := range indexes { x, err := indexArg(index, cap) if err != nil { @@ -264,32 +281,28 @@ func slice(item reflect.Value, indexes ...reflect.Value) (reflect.Value, error) return reflect.Value{}, fmt.Errorf("invalid slice index: %d > %d", idx[0], idx[1]) } if len(indexes) < 3 { - return v.Slice(idx[0], idx[1]), nil + return item.Slice(idx[0], idx[1]), nil } // given item[i:j:k], make sure i <= j <= k. if idx[1] > idx[2] { return reflect.Value{}, fmt.Errorf("invalid slice index: %d > %d", idx[1], idx[2]) } - return v.Slice3(idx[0], idx[1], idx[2]), nil + return item.Slice3(idx[0], idx[1], idx[2]), nil } // Length // length returns the length of the item, with an error if it has no defined length. -func length(item interface{}) (int, error) { - v := reflect.ValueOf(item) - if !v.IsValid() { - return 0, fmt.Errorf("len of untyped nil") - } - v, isNil := indirect(v) +func length(item reflect.Value) (int, error) { + item, isNil := indirect(item) if isNil { return 0, fmt.Errorf("len of nil pointer") } - switch v.Kind() { + switch item.Kind() { case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String: - return v.Len(), nil + return item.Len(), nil } - return 0, fmt.Errorf("len of type %s", v.Type()) + return 0, fmt.Errorf("len of type %s", item.Type()) } // Function invocation @@ -297,11 +310,11 @@ func length(item interface{}) (int, error) { // call returns the result of evaluating the first argument as a function. // The function must return 1 result, or 2 results, the second of which is an error. func call(fn reflect.Value, args ...reflect.Value) (reflect.Value, error) { - v := indirectInterface(fn) - if !v.IsValid() { + fn = indirectInterface(fn) + if !fn.IsValid() { return reflect.Value{}, fmt.Errorf("call of nil") } - typ := v.Type() + typ := fn.Type() if typ.Kind() != reflect.Func { return reflect.Value{}, fmt.Errorf("non-function of type %s", typ) } @@ -322,7 +335,7 @@ func call(fn reflect.Value, args ...reflect.Value) (reflect.Value, error) { } argv := make([]reflect.Value, len(args)) for i, arg := range args { - value := indirectInterface(arg) + arg = indirectInterface(arg) // Compute the expected type. Clumsy because of variadics. argType := dddType if !typ.IsVariadic() || i < numIn-1 { @@ -330,11 +343,11 @@ func call(fn reflect.Value, args ...reflect.Value) (reflect.Value, error) { } var err error - if argv[i], err = prepareArg(value, argType); err != nil { + if argv[i], err = prepareArg(arg, argType); err != nil { return reflect.Value{}, fmt.Errorf("arg %d: %s", i, err) } } - return safeCall(v, argv) + return safeCall(fn, argv) } // safeCall runs fun.Call(args), and returns the resulting value and error, if @@ -440,52 +453,52 @@ func basicKind(v reflect.Value) (kind, error) { // eq evaluates the comparison a == b || a == c || ... func eq(arg1 reflect.Value, arg2 ...reflect.Value) (bool, error) { - v1 := indirectInterface(arg1) - if v1 != zero { - if t1 := v1.Type(); !t1.Comparable() { - return false, fmt.Errorf("uncomparable type %s: %v", t1, v1) + arg1 = indirectInterface(arg1) + if arg1 != zero { + if t1 := arg1.Type(); !t1.Comparable() { + return false, fmt.Errorf("uncomparable type %s: %v", t1, arg1) } } if len(arg2) == 0 { return false, errNoComparison } - k1, _ := basicKind(v1) + k1, _ := basicKind(arg1) for _, arg := range arg2 { - v2 := indirectInterface(arg) - k2, _ := basicKind(v2) + arg = indirectInterface(arg) + k2, _ := basicKind(arg) truth := false if k1 != k2 { // Special case: Can compare integer values regardless of type's sign. switch { case k1 == intKind && k2 == uintKind: - truth = v1.Int() >= 0 && uint64(v1.Int()) == v2.Uint() + truth = arg1.Int() >= 0 && uint64(arg1.Int()) == arg.Uint() case k1 == uintKind && k2 == intKind: - truth = v2.Int() >= 0 && v1.Uint() == uint64(v2.Int()) + truth = arg.Int() >= 0 && arg1.Uint() == uint64(arg.Int()) default: return false, errBadComparison } } else { switch k1 { case boolKind: - truth = v1.Bool() == v2.Bool() + truth = arg1.Bool() == arg.Bool() case complexKind: - truth = v1.Complex() == v2.Complex() + truth = arg1.Complex() == arg.Complex() case floatKind: - truth = v1.Float() == v2.Float() + truth = arg1.Float() == arg.Float() case intKind: - truth = v1.Int() == v2.Int() + truth = arg1.Int() == arg.Int() case stringKind: - truth = v1.String() == v2.String() + truth = arg1.String() == arg.String() case uintKind: - truth = v1.Uint() == v2.Uint() + truth = arg1.Uint() == arg.Uint() default: - if v2 == zero { - truth = v1 == v2 + if arg == zero { + truth = arg1 == arg } else { - if t2 := v2.Type(); !t2.Comparable() { - return false, fmt.Errorf("uncomparable type %s: %v", t2, v2) + if t2 := arg.Type(); !t2.Comparable() { + return false, fmt.Errorf("uncomparable type %s: %v", t2, arg) } - truth = v1.Interface() == v2.Interface() + truth = arg1.Interface() == arg.Interface() } } } @@ -505,13 +518,13 @@ func ne(arg1, arg2 reflect.Value) (bool, error) { // lt evaluates the comparison a < b. func lt(arg1, arg2 reflect.Value) (bool, error) { - v1 := indirectInterface(arg1) - k1, err := basicKind(v1) + arg1 = indirectInterface(arg1) + k1, err := basicKind(arg1) if err != nil { return false, err } - v2 := indirectInterface(arg2) - k2, err := basicKind(v2) + arg2 = indirectInterface(arg2) + k2, err := basicKind(arg2) if err != nil { return false, err } @@ -520,9 +533,9 @@ func lt(arg1, arg2 reflect.Value) (bool, error) { // Special case: Can compare integer values regardless of type's sign. switch { case k1 == intKind && k2 == uintKind: - truth = v1.Int() < 0 || uint64(v1.Int()) < v2.Uint() + truth = arg1.Int() < 0 || uint64(arg1.Int()) < arg2.Uint() case k1 == uintKind && k2 == intKind: - truth = v2.Int() >= 0 && v1.Uint() < uint64(v2.Int()) + truth = arg2.Int() >= 0 && arg1.Uint() < uint64(arg2.Int()) default: return false, errBadComparison } @@ -531,13 +544,13 @@ func lt(arg1, arg2 reflect.Value) (bool, error) { case boolKind, complexKind: return false, errBadComparisonType case floatKind: - truth = v1.Float() < v2.Float() + truth = arg1.Float() < arg2.Float() case intKind: - truth = v1.Int() < v2.Int() + truth = arg1.Int() < arg2.Int() case stringKind: - truth = v1.String() < v2.String() + truth = arg1.String() < arg2.String() case uintKind: - truth = v1.Uint() < v2.Uint() + truth = arg1.Uint() < arg2.Uint() default: panic("invalid kind") } @@ -640,10 +653,10 @@ var ( jsBackslash = []byte(`\\`) jsApos = []byte(`\'`) jsQuot = []byte(`\"`) - jsLt = []byte(`\x3C`) - jsGt = []byte(`\x3E`) - jsAmp = []byte(`\x26`) - jsEq = []byte(`\x3D`) + jsLt = []byte(`\u003C`) + jsGt = []byte(`\u003E`) + jsAmp = []byte(`\u0026`) + jsEq = []byte(`\u003D`) ) // JSEscape writes to w the escaped JavaScript equivalent of the plain text data b. diff --git a/libgo/go/text/template/link_test.go b/libgo/go/text/template/link_test.go new file mode 100644 index 00000000000..4eac7e67551 --- /dev/null +++ b/libgo/go/text/template/link_test.go @@ -0,0 +1,64 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package template_test + +import ( + "bytes" + "internal/testenv" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "testing" +) + +// Issue 36021: verify that text/template doesn't prevent the linker from removing +// unused methods. +func TestLinkerGC(t *testing.T) { + if testing.Short() { + t.Skip("skipping in short mode") + } + testenv.MustHaveGoBuild(t) + const prog = `package main + +import ( + _ "text/template" +) + +type T struct{} + +func (t *T) Unused() { println("THIS SHOULD BE ELIMINATED") } +func (t *T) Used() {} + +var sink *T + +func main() { + var t T + sink = &t + t.Used() +} +` + td, err := ioutil.TempDir("", "text_template_TestDeadCodeElimination") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(td) + + if err := ioutil.WriteFile(filepath.Join(td, "x.go"), []byte(prog), 0644); err != nil { + t.Fatal(err) + } + cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", "x.exe", "x.go") + cmd.Dir = td + if out, err := cmd.CombinedOutput(); err != nil { + t.Fatalf("go build: %v, %s", err, out) + } + slurp, err := ioutil.ReadFile(filepath.Join(td, "x.exe")) + if err != nil { + t.Fatal(err) + } + if bytes.Contains(slurp, []byte("THIS SHOULD BE ELIMINATED")) { + t.Error("binary contains code that should be deadcode eliminated") + } +} diff --git a/libgo/go/text/template/multi_test.go b/libgo/go/text/template/multi_test.go index 5769470ff90..34d2378e387 100644 --- a/libgo/go/text/template/multi_test.go +++ b/libgo/go/text/template/multi_test.go @@ -242,7 +242,7 @@ func TestAddParseTree(t *testing.T) { t.Fatal(err) } // Add a new parse tree. - tree, err := parse.Parse("cloneText3", cloneText3, "", "", nil, builtins) + tree, err := parse.Parse("cloneText3", cloneText3, "", "", nil, builtins()) if err != nil { t.Fatal(err) } @@ -359,6 +359,7 @@ func TestEmptyTemplate(t *testing.T) { in string want string }{ + {[]string{"x", "y"}, "", "y"}, {[]string{""}, "once", ""}, {[]string{"", ""}, "twice", ""}, {[]string{"{{.}}", "{{.}}"}, "twice", "twice"}, diff --git a/libgo/go/text/template/parse/node.go b/libgo/go/text/template/parse/node.go index 1c116ea6fab..dddc7752a2e 100644 --- a/libgo/go/text/template/parse/node.go +++ b/libgo/go/text/template/parse/node.go @@ -349,7 +349,7 @@ func (i *IdentifierNode) Copy() Node { return NewIdentifier(i.Ident).SetTree(i.tr).SetPos(i.Pos) } -// AssignNode holds a list of variable names, possibly with chained field +// VariableNode holds a list of variable names, possibly with chained field // accesses. The dollar sign is part of the (first) name. type VariableNode struct { NodeType diff --git a/libgo/go/text/template/template.go b/libgo/go/text/template/template.go index e0c096207c7..ec26eb4c50a 100644 --- a/libgo/go/text/template/template.go +++ b/libgo/go/text/template/template.go @@ -198,7 +198,7 @@ func (t *Template) Lookup(name string) *Template { func (t *Template) Parse(text string) (*Template, error) { t.init() t.muFuncs.RLock() - trees, err := parse.Parse(t.name, text, t.leftDelim, t.rightDelim, t.parseFuncs, builtins) + trees, err := parse.Parse(t.name, text, t.leftDelim, t.rightDelim, t.parseFuncs, builtins()) t.muFuncs.RUnlock() if err != nil { return nil, err diff --git a/libgo/go/time/embed.go b/libgo/go/time/embed.go new file mode 100644 index 00000000000..cb4fdac4efa --- /dev/null +++ b/libgo/go/time/embed.go @@ -0,0 +1,12 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file is used with build tag timetzdata to embed tzdata into +// the binary. + +// +build timetzdata + +package time + +import _ "time/tzdata" diff --git a/libgo/go/time/example_test.go b/libgo/go/time/example_test.go index 5a037daeafb..0afb18aba6b 100644 --- a/libgo/go/time/example_test.go +++ b/libgo/go/time/example_test.go @@ -50,10 +50,11 @@ func ExampleDuration_Round() { } func ExampleDuration_String() { - t1 := time.Date(2016, time.August, 15, 0, 0, 0, 0, time.UTC) - t2 := time.Date(2017, time.February, 16, 0, 0, 0, 0, time.UTC) - fmt.Println(t2.Sub(t1).String()) - // Output: 4440h0m0s + fmt.Println(1*time.Hour + 2*time.Minute + 300*time.Millisecond) + fmt.Println(300 * time.Millisecond) + // Output: + // 1h2m0.3s + // 300ms } func ExampleDuration_Truncate() { @@ -206,7 +207,7 @@ func ExampleNewTicker() { func ExampleTime_Format() { // Parse a time value from a string in the standard Unix format. - t, err := time.Parse(time.UnixDate, "Sat Mar 7 11:06:39 PST 2015") + t, err := time.Parse(time.UnixDate, "Wed Feb 25 11:06:39 PST 2015") if err != nil { // Always check errors even if they should not happen. panic(err) } @@ -245,35 +246,15 @@ func ExampleTime_Format() { fmt.Printf("error: for %q got %q; expected %q\n", layout, got, want) return } - fmt.Printf("%-15s %q gives %q\n", name, layout, got) + fmt.Printf("%-16s %q gives %q\n", name, layout, got) } // Print a header in our output. fmt.Printf("\nFormats:\n\n") - // A simple starter example. - do("Basic", "Mon Jan 2 15:04:05 MST 2006", "Sat Mar 7 11:06:39 PST 2015") - - // For fixed-width printing of values, such as the date, that may be one or - // two characters (7 vs. 07), use an _ instead of a space in the layout string. - // Here we print just the day, which is 2 in our layout string and 7 in our - // value. - do("No pad", "<2>", "<7>") - - // An underscore represents a space pad, if the date only has one digit. - do("Spaces", "<_2>", "< 7>") - - // A "0" indicates zero padding for single-digit values. - do("Zeros", "<02>", "<07>") - - // If the value is already the right width, padding is not used. - // For instance, the second (05 in the reference time) in our value is 39, - // so it doesn't need padding, but the minutes (04, 06) does. - do("Suppressed pad", "04:05", "06:39") - - // The predefined constant Unix uses an underscore to pad the day. - // Compare with our simple starter example. - do("Unix", time.UnixDate, "Sat Mar 7 11:06:39 PST 2015") + // Simple starter examples. + do("Basic full date", "Mon Jan 2 15:04:05 MST 2006", "Wed Feb 25 11:06:39 PST 2015") + do("Basic short date", "2006/01/02", "2015/02/25") // The hour of the reference time is 15, or 3PM. The layout can express // it either way, and since our value is the morning we should see it as @@ -284,13 +265,13 @@ func ExampleTime_Format() { // and some digits, that is taken as a fraction of a second even if // the layout string does not represent the fractional second. // Here we add a fractional second to our time value used above. - t, err = time.Parse(time.UnixDate, "Sat Mar 7 11:06:39.1234 PST 2015") + t, err = time.Parse(time.UnixDate, "Wed Feb 25 11:06:39.1234 PST 2015") if err != nil { panic(err) } // It does not appear in the output if the layout string does not contain // a representation of the fractional second. - do("No fraction", time.UnixDate, "Sat Mar 7 11:06:39 PST 2015") + do("No fraction", time.UnixDate, "Wed Feb 25 11:06:39 PST 2015") // Fractional seconds can be printed by adding a run of 0s or 9s after // a decimal point in the seconds value in the layout string. @@ -302,22 +283,64 @@ func ExampleTime_Format() { do("9s for fraction", "15:04:05.99999999", "11:06:39.1234") // Output: - // default format: 2015-03-07 11:06:39 -0800 PST - // Unix format: Sat Mar 7 11:06:39 PST 2015 - // Same, in UTC: Sat Mar 7 19:06:39 UTC 2015 + // default format: 2015-02-25 11:06:39 -0800 PST + // Unix format: Wed Feb 25 11:06:39 PST 2015 + // Same, in UTC: Wed Feb 25 19:06:39 UTC 2015 // // Formats: // - // Basic "Mon Jan 2 15:04:05 MST 2006" gives "Sat Mar 7 11:06:39 PST 2015" - // No pad "<2>" gives "<7>" - // Spaces "<_2>" gives "< 7>" - // Zeros "<02>" gives "<07>" - // Suppressed pad "04:05" gives "06:39" - // Unix "Mon Jan _2 15:04:05 MST 2006" gives "Sat Mar 7 11:06:39 PST 2015" - // AM/PM "3PM==3pm==15h" gives "11AM==11am==11h" - // No fraction "Mon Jan _2 15:04:05 MST 2006" gives "Sat Mar 7 11:06:39 PST 2015" - // 0s for fraction "15:04:05.00000" gives "11:06:39.12340" - // 9s for fraction "15:04:05.99999999" gives "11:06:39.1234" + // Basic full date "Mon Jan 2 15:04:05 MST 2006" gives "Wed Feb 25 11:06:39 PST 2015" + // Basic short date "2006/01/02" gives "2015/02/25" + // AM/PM "3PM==3pm==15h" gives "11AM==11am==11h" + // No fraction "Mon Jan _2 15:04:05 MST 2006" gives "Wed Feb 25 11:06:39 PST 2015" + // 0s for fraction "15:04:05.00000" gives "11:06:39.12340" + // 9s for fraction "15:04:05.99999999" gives "11:06:39.1234" + +} + +func ExampleTime_Format_pad() { + // Parse a time value from a string in the standard Unix format. + t, err := time.Parse(time.UnixDate, "Sat Mar 7 11:06:39 PST 2015") + if err != nil { // Always check errors even if they should not happen. + panic(err) + } + + // Define a helper function to make the examples' output look nice. + do := func(name, layout, want string) { + got := t.Format(layout) + if want != got { + fmt.Printf("error: for %q got %q; expected %q\n", layout, got, want) + return + } + fmt.Printf("%-16s %q gives %q\n", name, layout, got) + } + + // The predefined constant Unix uses an underscore to pad the day. + do("Unix", time.UnixDate, "Sat Mar 7 11:06:39 PST 2015") + + // For fixed-width printing of values, such as the date, that may be one or + // two characters (7 vs. 07), use an _ instead of a space in the layout string. + // Here we print just the day, which is 2 in our layout string and 7 in our + // value. + do("No pad", "<2>", "<7>") + + // An underscore represents a space pad, if the date only has one digit. + do("Spaces", "<_2>", "< 7>") + + // A "0" indicates zero padding for single-digit values. + do("Zeros", "<02>", "<07>") + + // If the value is already the right width, padding is not used. + // For instance, the second (05 in the reference time) in our value is 39, + // so it doesn't need padding, but the minutes (04, 06) does. + do("Suppressed pad", "04:05", "06:39") + + // Output: + // Unix "Mon Jan _2 15:04:05 MST 2006" gives "Sat Mar 7 11:06:39 PST 2015" + // No pad "<2>" gives "<7>" + // Spaces "<_2>" gives "< 7>" + // Zeros "<02>" gives "<07>" + // Suppressed pad "04:05" gives "06:39" } @@ -357,7 +380,7 @@ func ExampleParse() { // 2013-02-03 00:00:00 +0000 UTC // 2006-01-02 15:04:05 +0000 UTC // 2006-01-02 15:04:05 +0700 +0700 - // error parsing time "2006-01-02T15:04:05Z07:00": extra text: 07:00 + // error parsing time "2006-01-02T15:04:05Z07:00": extra text: "07:00" } func ExampleParseInLocation() { diff --git a/libgo/go/time/export_test.go b/libgo/go/time/export_test.go index 442c8da4a6e..f4a8cd9b72a 100644 --- a/libgo/go/time/export_test.go +++ b/libgo/go/time/export_test.go @@ -36,8 +36,43 @@ var ( ReadFile = readFile LoadTzinfo = loadTzinfo NextStdChunk = nextStdChunk + Tzset = tzset + TzsetName = tzsetName + TzsetOffset = tzsetOffset ) +func LoadFromEmbeddedTZData(zone string) (string, error) { + return loadFromEmbeddedTZData(zone) +} + +type RuleKind int + +const ( + RuleJulian = RuleKind(ruleJulian) + RuleDOY = RuleKind(ruleDOY) + RuleMonthWeekDay = RuleKind(ruleMonthWeekDay) +) + +type Rule struct { + Kind RuleKind + Day int + Week int + Mon int + Time int +} + +func TzsetRule(s string) (Rule, string, bool) { + r, rs, ok := tzsetRule(s) + rr := Rule{ + Kind: RuleKind(r.kind), + Day: r.day, + Week: r.week, + Mon: r.mon, + Time: r.time, + } + return rr, rs, ok +} + // StdChunkNames maps from nextStdChunk results to the matched strings. var StdChunkNames = map[int]string{ 0: "", diff --git a/libgo/go/time/format.go b/libgo/go/time/format.go index 9beb5d9a48f..f11fb7ed304 100644 --- a/libgo/go/time/format.go +++ b/libgo/go/time/format.go @@ -67,7 +67,7 @@ import "errors" // that insist on that format, and RFC3339 should be preferred for new protocols. // RFC3339, RFC822, RFC822Z, RFC1123, and RFC1123Z are useful for formatting; // when used with time.Parse they do not accept all the time formats -// permitted by the RFCs. +// permitted by the RFCs and they do accept time formats not formally defined. // The RFC3339Nano format removes trailing zeros from the seconds field // and thus may not sort correctly once formatted. const ( @@ -856,7 +856,7 @@ func parse(layout, value string, defaultLocation, local *Location) (Time, error) } if std == 0 { if len(value) != 0 { - return Time{}, &ParseError{alayout, avalue, "", value, ": extra text: " + value} + return Time{}, &ParseError{alayout, avalue, "", value, ": extra text: " + quote(value)} } break } @@ -1112,7 +1112,7 @@ func parse(layout, value string, defaultLocation, local *Location) (Time, error) return Time{}, &ParseError{alayout, avalue, "", value, ": day-of-year out of range"} } if m == 0 { - m = yday/31 + 1 + m = (yday-1)/31 + 1 if int(daysBefore[m]) < yday { m++ } @@ -1390,7 +1390,7 @@ func ParseDuration(s string) (Duration, error) { return 0, nil } if s == "" { - return 0, errors.New("time: invalid duration " + orig) + return 0, errors.New("time: invalid duration " + quote(orig)) } for s != "" { var ( @@ -1402,13 +1402,13 @@ func ParseDuration(s string) (Duration, error) { // The next character must be [0-9.] if !(s[0] == '.' || '0' <= s[0] && s[0] <= '9') { - return 0, errors.New("time: invalid duration " + orig) + return 0, errors.New("time: invalid duration " + quote(orig)) } // Consume [0-9]* pl := len(s) v, s, err = leadingInt(s) if err != nil { - return 0, errors.New("time: invalid duration " + orig) + return 0, errors.New("time: invalid duration " + quote(orig)) } pre := pl != len(s) // whether we consumed anything before a period @@ -1422,7 +1422,7 @@ func ParseDuration(s string) (Duration, error) { } if !pre && !post { // no digits (e.g. ".s" or "-.s") - return 0, errors.New("time: invalid duration " + orig) + return 0, errors.New("time: invalid duration " + quote(orig)) } // Consume unit. @@ -1434,17 +1434,17 @@ func ParseDuration(s string) (Duration, error) { } } if i == 0 { - return 0, errors.New("time: missing unit in duration " + orig) + return 0, errors.New("time: missing unit in duration " + quote(orig)) } u := s[:i] s = s[i:] unit, ok := unitMap[u] if !ok { - return 0, errors.New("time: unknown unit " + u + " in duration " + orig) + return 0, errors.New("time: unknown unit " + quote(u) + " in duration " + quote(orig)) } if v > (1<<63-1)/unit { // overflow - return 0, errors.New("time: invalid duration " + orig) + return 0, errors.New("time: invalid duration " + quote(orig)) } v *= unit if f > 0 { @@ -1453,13 +1453,13 @@ func ParseDuration(s string) (Duration, error) { v += int64(float64(f) * (float64(unit) / scale)) if v < 0 { // overflow - return 0, errors.New("time: invalid duration " + orig) + return 0, errors.New("time: invalid duration " + quote(orig)) } } d += v if d < 0 { // overflow - return 0, errors.New("time: invalid duration " + orig) + return 0, errors.New("time: invalid duration " + quote(orig)) } } diff --git a/libgo/go/time/format_test.go b/libgo/go/time/format_test.go index 3dbb7742c33..676117c4386 100644 --- a/libgo/go/time/format_test.go +++ b/libgo/go/time/format_test.go @@ -538,12 +538,12 @@ var parseErrorTests = []ParseErrorTest{ {"Mon Jan _2 15:04:05.000 2006", "Thu Feb 4 23:00:59.-123 2010", "fractional second out of range"}, // issue 4502. StampNano requires exactly 9 digits of precision. {StampNano, "Dec 7 11:22:01.000000", `cannot parse ".000000" as ".000000000"`}, - {StampNano, "Dec 7 11:22:01.0000000000", "extra text: 0"}, + {StampNano, "Dec 7 11:22:01.0000000000", `extra text: "0"`}, // issue 4493. Helpful errors. - {RFC3339, "2006-01-02T15:04:05Z07:00", `parsing time "2006-01-02T15:04:05Z07:00": extra text: 07:00`}, + {RFC3339, "2006-01-02T15:04:05Z07:00", `parsing time "2006-01-02T15:04:05Z07:00": extra text: "07:00"`}, {RFC3339, "2006-01-02T15:04_abc", `parsing time "2006-01-02T15:04_abc" as "2006-01-02T15:04:05Z07:00": cannot parse "_abc" as ":"`}, {RFC3339, "2006-01-02T15:04:05_abc", `parsing time "2006-01-02T15:04:05_abc" as "2006-01-02T15:04:05Z07:00": cannot parse "_abc" as "Z07:00"`}, - {RFC3339, "2006-01-02T15:04:05Z_abc", `parsing time "2006-01-02T15:04:05Z_abc": extra text: _abc`}, + {RFC3339, "2006-01-02T15:04:05Z_abc", `parsing time "2006-01-02T15:04:05Z_abc": extra text: "_abc"`}, // invalid second followed by optional fractional seconds {RFC3339, "2010-02-04T21:00:67.012345678-08:00", "second out of range"}, // issue 21113 @@ -758,3 +758,17 @@ func TestParseMonthOutOfRange(t *testing.T) { } } } + +// Issue 37387. +func TestParseYday(t *testing.T) { + t.Parallel() + for i := 1; i <= 365; i++ { + d := fmt.Sprintf("2020-%03d", i) + tm, err := Parse("2006-002", d) + if err != nil { + t.Errorf("unexpected error for %s: %v", d, err) + } else if tm.Year() != 2020 || tm.YearDay() != i { + t.Errorf("got year %d yearday %d, want %d %d", tm.Year(), tm.YearDay(), 2020, i) + } + } +} diff --git a/libgo/go/time/internal_test.go b/libgo/go/time/internal_test.go index 1e14f6c50ce..70944f99b48 100644 --- a/libgo/go/time/internal_test.go +++ b/libgo/go/time/internal_test.go @@ -72,12 +72,13 @@ func CheckRuntimeTimerOverflow() { resetTimer(r, 0) }() - // If the test fails, we will hang here until the timeout in the testing package - // fires, which is 10 minutes. It would be nice to catch the problem sooner, - // but there is no reliable way to guarantee that timerproc schedules without - // doing something involving timerproc itself. Previous failed attempts have - // tried calling runtime.Gosched and runtime.GC, but neither is reliable. - // So we fall back to hope: We hope we don't hang here. + // If the test fails, we will hang here until the timeout in the + // testing package fires, which is 10 minutes. It would be nice to + // catch the problem sooner, but there is no reliable way to guarantee + // that timers are run without doing something involving the scheduler. + // Previous failed attempts have tried calling runtime.Gosched and + // runtime.GC, but neither is reliable. So we fall back to hope: + // We hope we don't hang here. <-t.C } diff --git a/libgo/go/time/sleep.go b/libgo/go/time/sleep.go index 37de846b114..22ffd68282b 100644 --- a/libgo/go/time/sleep.go +++ b/libgo/go/time/sleep.go @@ -38,7 +38,8 @@ func when(d Duration) int64 { func startTimer(*runtimeTimer) func stopTimer(*runtimeTimer) bool -func resetTimer(*runtimeTimer, int64) +func resetTimer(*runtimeTimer, int64) bool +func modTimer(t *runtimeTimer, when, period int64, f func(interface{}, uintptr), arg interface{}, seq uintptr) // The Timer type represents a single event. // When the Timer expires, the current time will be sent on C, @@ -122,9 +123,7 @@ func (t *Timer) Reset(d Duration) bool { panic("time: Reset called on uninitialized Timer") } w := when(d) - active := stopTimer(&t.r) - resetTimer(&t.r, w) - return active + return resetTimer(&t.r, w) } func sendTime(c interface{}, seq uintptr) { diff --git a/libgo/go/time/tick.go b/libgo/go/time/tick.go index e4cd43aa82a..152d5a706be 100644 --- a/libgo/go/time/tick.go +++ b/libgo/go/time/tick.go @@ -46,6 +46,15 @@ func (t *Ticker) Stop() { stopTimer(&t.r) } +// Reset stops a ticker and resets its period to the specified duration. +// The next tick will arrive after the new period elapses. +func (t *Ticker) Reset(d Duration) { + if t.r.f == nil { + panic("time: Reset called on uninitialized Ticker") + } + modTimer(&t.r, when(d), int64(d), t.r.f, t.r.arg, t.r.seq) +} + // Tick is a convenience wrapper for NewTicker providing access to the ticking // channel only. While Tick is useful for clients that have no need to shut down // the Ticker, be aware that without a way to shut it down the underlying diff --git a/libgo/go/time/tick_test.go b/libgo/go/time/tick_test.go index 71ea3672b86..c0c6e76b53f 100644 --- a/libgo/go/time/tick_test.go +++ b/libgo/go/time/tick_test.go @@ -22,7 +22,12 @@ func TestTicker(t *testing.T) { // On Darwin ARM64 the tick frequency seems limited. Issue 35692. if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" { - count = 5 + // The following test will run ticker count/2 times then reset + // the ticker to double the duration for the rest of count/2. + // Since tick frequency is limited on Darwin ARM64, use even + // number to give the ticks more time to let the test pass. + // See CL 220638. + count = 6 delta = 100 * Millisecond } @@ -36,13 +41,17 @@ func TestTicker(t *testing.T) { for i := 0; i < 5; i++ { ticker := NewTicker(delta) t0 := Now() - for i := 0; i < count; i++ { + for i := 0; i < count/2; i++ { + <-ticker.C + } + ticker.Reset(delta * 2) + for i := count / 2; i < count; i++ { <-ticker.C } ticker.Stop() t1 := Now() dt := t1.Sub(t0) - target := delta * Duration(count) + target := 3 * delta * Duration(count/2) slop := target * 2 / 10 if dt < target-slop || dt > target+slop { errs = append(errs, fmt.Sprintf("%d %s ticks took %s, expected [%s,%s]", count, delta, dt, target-slop, target+slop)) @@ -118,3 +127,24 @@ func BenchmarkTicker(b *testing.B) { ticker.Stop() }) } + +func BenchmarkTickerReset(b *testing.B) { + benchmark(b, func(n int) { + ticker := NewTicker(Nanosecond) + for i := 0; i < n; i++ { + ticker.Reset(Nanosecond * 2) + } + ticker.Stop() + }) +} + +func BenchmarkTickerResetNaive(b *testing.B) { + benchmark(b, func(n int) { + ticker := NewTicker(Nanosecond) + for i := 0; i < n; i++ { + ticker.Stop() + ticker = NewTicker(Nanosecond * 2) + } + ticker.Stop() + }) +} diff --git a/libgo/go/time/time.go b/libgo/go/time/time.go index 5dc9fa68ac1..8ae62308e5b 100644 --- a/libgo/go/time/time.go +++ b/libgo/go/time/time.go @@ -252,7 +252,9 @@ func (t Time) Before(u Time) bool { if t.wall&u.wall&hasMonotonic != 0 { return t.ext < u.ext } - return t.sec() < u.sec() || t.sec() == u.sec() && t.nsec() < u.nsec() + ts := t.sec() + us := u.sec() + return ts < us || ts == us && t.nsec() < u.nsec() } // Equal reports whether t and u represent the same time instant. @@ -285,25 +287,10 @@ const ( December ) -var months = [...]string{ - "January", - "February", - "March", - "April", - "May", - "June", - "July", - "August", - "September", - "October", - "November", - "December", -} - // String returns the English name of the month ("January", "February", ...). func (m Month) String() string { if January <= m && m <= December { - return months[m-1] + return longMonthNames[m-1] } buf := make([]byte, 20) n := fmtInt(buf, uint64(m)) @@ -323,20 +310,10 @@ const ( Saturday ) -var days = [...]string{ - "Sunday", - "Monday", - "Tuesday", - "Wednesday", - "Thursday", - "Friday", - "Saturday", -} - // String returns the English name of the day ("Sunday", "Monday", ...). func (d Weekday) String() string { if Sunday <= d && d <= Saturday { - return days[d] + return longDayNames[d] } buf := make([]byte, 20) n := fmtInt(buf, uint64(d)) @@ -535,58 +512,26 @@ func absWeekday(abs uint64) Weekday { // week 52 or 53 of year n-1, and Dec 29 to Dec 31 might belong to week 1 // of year n+1. func (t Time) ISOWeek() (year, week int) { - year, month, day, yday := t.date(true) - wday := int(t.Weekday()+6) % 7 // weekday but Monday = 0. - const ( - Mon int = iota - Tue - Wed - Thu - Fri - Sat - Sun - ) - - // Calculate week as number of Mondays in year up to - // and including today, plus 1 because the first week is week 0. - // Putting the + 1 inside the numerator as a + 7 keeps the - // numerator from being negative, which would cause it to - // round incorrectly. - week = (yday - wday + 7) / 7 - - // The week number is now correct under the assumption - // that the first Monday of the year is in week 1. - // If Jan 1 is a Tuesday, Wednesday, or Thursday, the first Monday - // is actually in week 2. - jan1wday := (wday - yday + 7*53) % 7 - if Tue <= jan1wday && jan1wday <= Thu { - week++ + // According to the rule that the first calendar week of a calendar year is + // the week including the first Thursday of that year, and that the last one is + // the week immediately preceding the first calendar week of the next calendar year. + // See https://www.iso.org/obp/ui#iso:std:iso:8601:-1:ed-1:v1:en:term:3.1.1.23 for details. + + // weeks start with Monday + // Monday Tuesday Wednesday Thursday Friday Saturday Sunday + // 1 2 3 4 5 6 7 + // +3 +2 +1 0 -1 -2 -3 + // the offset to Thursday + abs := t.abs() + d := Thursday - absWeekday(abs) + // handle Sunday + if d == 4 { + d = -3 } - - // If the week number is still 0, we're in early January but in - // the last week of last year. - if week == 0 { - year-- - week = 52 - // A year has 53 weeks when Jan 1 or Dec 31 is a Thursday, - // meaning Jan 1 of the next year is a Friday - // or it was a leap year and Jan 1 of the next year is a Saturday. - if jan1wday == Fri || (jan1wday == Sat && isLeap(year)) { - week++ - } - } - - // December 29 to 31 are in week 1 of next year if - // they are after the last Thursday of the year and - // December 31 is a Monday, Tuesday, or Wednesday. - if month == December && day >= 29 && wday < Thu { - if dec31wday := (wday + 31 - day) % 7; Mon <= dec31wday && dec31wday <= Wed { - year++ - week = 1 - } - } - - return + // find the Thursday of the calendar week + abs += uint64(d) * secondsPerDay + year, _, _, yday := absDate(abs, false) + return year, yday/7 + 1 } // Clock returns the hour, minute, and second within the day specified by t. @@ -1074,6 +1019,34 @@ func daysIn(m Month, year int) int { return int(daysBefore[m] - daysBefore[m-1]) } +// daysSinceEpoch takes a year and returns the number of days from +// the absolute epoch to the start of that year. +// This is basically (year - zeroYear) * 365, but accounting for leap days. +func daysSinceEpoch(year int) uint64 { + y := uint64(int64(year) - absoluteZeroYear) + + // Add in days from 400-year cycles. + n := y / 400 + y -= 400 * n + d := daysPer400Years * n + + // Add in 100-year cycles. + n = y / 100 + y -= 100 * n + d += daysPer100Years * n + + // Add in 4-year cycles. + n = y / 4 + y -= 4 * n + d += daysPer4Years * n + + // Add in non-leap years. + n = y + d += 365 * n + + return d +} + // Provided by package runtime. func now() (sec int64, nsec int32, mono int64) @@ -1382,28 +1355,8 @@ func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) T hour, min = norm(hour, min, 60) day, hour = norm(day, hour, 24) - y := uint64(int64(year) - absoluteZeroYear) - // Compute days since the absolute epoch. - - // Add in days from 400-year cycles. - n := y / 400 - y -= 400 * n - d := daysPer400Years * n - - // Add in 100-year cycles. - n = y / 100 - y -= 100 * n - d += daysPer100Years * n - - // Add in 4-year cycles. - n = y / 4 - y -= 4 * n - d += daysPer4Years * n - - // Add in non-leap years. - n = y - d += 365 * n + d := daysSinceEpoch(year) // Add in days before this month. d += uint64(daysBefore[month-1]) diff --git a/libgo/go/time/time_test.go b/libgo/go/time/time_test.go index 2fc23c4feeb..154198a1ce6 100644 --- a/libgo/go/time/time_test.go +++ b/libgo/go/time/time_test.go @@ -66,6 +66,13 @@ var nanoutctests = []TimeTest{ var localtests = []TimeTest{ {0, parsedTime{1969, December, 31, 16, 0, 0, 0, Wednesday, -8 * 60 * 60, "PST"}}, {1221681866, parsedTime{2008, September, 17, 13, 4, 26, 0, Wednesday, -7 * 60 * 60, "PDT"}}, + {2159200800, parsedTime{2038, June, 3, 11, 0, 0, 0, Thursday, -7 * 60 * 60, "PDT"}}, + {2152173599, parsedTime{2038, March, 14, 1, 59, 59, 0, Sunday, -8 * 60 * 60, "PST"}}, + {2152173600, parsedTime{2038, March, 14, 3, 0, 0, 0, Sunday, -7 * 60 * 60, "PDT"}}, + {2152173601, parsedTime{2038, March, 14, 3, 0, 1, 0, Sunday, -7 * 60 * 60, "PDT"}}, + {2172733199, parsedTime{2038, November, 7, 1, 59, 59, 0, Sunday, -7 * 60 * 60, "PDT"}}, + {2172733200, parsedTime{2038, November, 7, 1, 0, 0, 0, Sunday, -8 * 60 * 60, "PST"}}, + {2172733201, parsedTime{2038, November, 7, 1, 0, 1, 0, Sunday, -8 * 60 * 60, "PST"}}, } var nanolocaltests = []TimeTest{ @@ -810,86 +817,103 @@ func TestNotJSONEncodableTime(t *testing.T) { var parseDurationTests = []struct { in string - ok bool want Duration }{ // simple - {"0", true, 0}, - {"5s", true, 5 * Second}, - {"30s", true, 30 * Second}, - {"1478s", true, 1478 * Second}, + {"0", 0}, + {"5s", 5 * Second}, + {"30s", 30 * Second}, + {"1478s", 1478 * Second}, // sign - {"-5s", true, -5 * Second}, - {"+5s", true, 5 * Second}, - {"-0", true, 0}, - {"+0", true, 0}, + {"-5s", -5 * Second}, + {"+5s", 5 * Second}, + {"-0", 0}, + {"+0", 0}, // decimal - {"5.0s", true, 5 * Second}, - {"5.6s", true, 5*Second + 600*Millisecond}, - {"5.s", true, 5 * Second}, - {".5s", true, 500 * Millisecond}, - {"1.0s", true, 1 * Second}, - {"1.00s", true, 1 * Second}, - {"1.004s", true, 1*Second + 4*Millisecond}, - {"1.0040s", true, 1*Second + 4*Millisecond}, - {"100.00100s", true, 100*Second + 1*Millisecond}, + {"5.0s", 5 * Second}, + {"5.6s", 5*Second + 600*Millisecond}, + {"5.s", 5 * Second}, + {".5s", 500 * Millisecond}, + {"1.0s", 1 * Second}, + {"1.00s", 1 * Second}, + {"1.004s", 1*Second + 4*Millisecond}, + {"1.0040s", 1*Second + 4*Millisecond}, + {"100.00100s", 100*Second + 1*Millisecond}, // different units - {"10ns", true, 10 * Nanosecond}, - {"11us", true, 11 * Microsecond}, - {"12µs", true, 12 * Microsecond}, // U+00B5 - {"12μs", true, 12 * Microsecond}, // U+03BC - {"13ms", true, 13 * Millisecond}, - {"14s", true, 14 * Second}, - {"15m", true, 15 * Minute}, - {"16h", true, 16 * Hour}, + {"10ns", 10 * Nanosecond}, + {"11us", 11 * Microsecond}, + {"12µs", 12 * Microsecond}, // U+00B5 + {"12μs", 12 * Microsecond}, // U+03BC + {"13ms", 13 * Millisecond}, + {"14s", 14 * Second}, + {"15m", 15 * Minute}, + {"16h", 16 * Hour}, // composite durations - {"3h30m", true, 3*Hour + 30*Minute}, - {"10.5s4m", true, 4*Minute + 10*Second + 500*Millisecond}, - {"-2m3.4s", true, -(2*Minute + 3*Second + 400*Millisecond)}, - {"1h2m3s4ms5us6ns", true, 1*Hour + 2*Minute + 3*Second + 4*Millisecond + 5*Microsecond + 6*Nanosecond}, - {"39h9m14.425s", true, 39*Hour + 9*Minute + 14*Second + 425*Millisecond}, + {"3h30m", 3*Hour + 30*Minute}, + {"10.5s4m", 4*Minute + 10*Second + 500*Millisecond}, + {"-2m3.4s", -(2*Minute + 3*Second + 400*Millisecond)}, + {"1h2m3s4ms5us6ns", 1*Hour + 2*Minute + 3*Second + 4*Millisecond + 5*Microsecond + 6*Nanosecond}, + {"39h9m14.425s", 39*Hour + 9*Minute + 14*Second + 425*Millisecond}, // large value - {"52763797000ns", true, 52763797000 * Nanosecond}, + {"52763797000ns", 52763797000 * Nanosecond}, // more than 9 digits after decimal point, see https://golang.org/issue/6617 - {"0.3333333333333333333h", true, 20 * Minute}, + {"0.3333333333333333333h", 20 * Minute}, // 9007199254740993 = 1<<53+1 cannot be stored precisely in a float64 - {"9007199254740993ns", true, (1<<53 + 1) * Nanosecond}, + {"9007199254740993ns", (1<<53 + 1) * Nanosecond}, // largest duration that can be represented by int64 in nanoseconds - {"9223372036854775807ns", true, (1<<63 - 1) * Nanosecond}, - {"9223372036854775.807us", true, (1<<63 - 1) * Nanosecond}, - {"9223372036s854ms775us807ns", true, (1<<63 - 1) * Nanosecond}, + {"9223372036854775807ns", (1<<63 - 1) * Nanosecond}, + {"9223372036854775.807us", (1<<63 - 1) * Nanosecond}, + {"9223372036s854ms775us807ns", (1<<63 - 1) * Nanosecond}, // large negative value - {"-9223372036854775807ns", true, -1<<63 + 1*Nanosecond}, + {"-9223372036854775807ns", -1<<63 + 1*Nanosecond}, // huge string; issue 15011. - {"0.100000000000000000000h", true, 6 * Minute}, + {"0.100000000000000000000h", 6 * Minute}, // This value tests the first overflow check in leadingFraction. - {"0.830103483285477580700h", true, 49*Minute + 48*Second + 372539827*Nanosecond}, - - // errors - {"", false, 0}, - {"3", false, 0}, - {"-", false, 0}, - {"s", false, 0}, - {".", false, 0}, - {"-.", false, 0}, - {".s", false, 0}, - {"+.s", false, 0}, - {"3000000h", false, 0}, // overflow - {"9223372036854775808ns", false, 0}, // overflow - {"9223372036854775.808us", false, 0}, // overflow - {"9223372036854ms775us808ns", false, 0}, // overflow - // largest negative value of type int64 in nanoseconds should fail - // see https://go-review.googlesource.com/#/c/2461/ - {"-9223372036854775808ns", false, 0}, + {"0.830103483285477580700h", 49*Minute + 48*Second + 372539827*Nanosecond}, } func TestParseDuration(t *testing.T) { for _, tc := range parseDurationTests { d, err := ParseDuration(tc.in) - if tc.ok && (err != nil || d != tc.want) { + if err != nil || d != tc.want { t.Errorf("ParseDuration(%q) = %v, %v, want %v, nil", tc.in, d, err, tc.want) - } else if !tc.ok && err == nil { + } + } +} + +var parseDurationErrorTests = []struct { + in string + expect string +}{ + // invalid + {"", `""`}, + {"3", `"3"`}, + {"-", `"-"`}, + {"s", `"s"`}, + {".", `"."`}, + {"-.", `"-."`}, + {".s", `".s"`}, + {"+.s", `"+.s"`}, + {"1d", `"1d"`}, + // overflow + {"9223372036854775810ns", `"9223372036854775810ns"`}, + {"9223372036854775808ns", `"9223372036854775808ns"`}, + // largest negative value of type int64 in nanoseconds should fail + // see https://go-review.googlesource.com/#/c/2461/ + {"-9223372036854775808ns", `"-9223372036854775808ns"`}, + {"9223372036854776us", `"9223372036854776us"`}, + {"3000000h", `"3000000h"`}, + {"9223372036854775.808us", `"9223372036854775.808us"`}, + {"9223372036854ms775us808ns", `"9223372036854ms775us808ns"`}, +} + +func TestParseDurationErrors(t *testing.T) { + for _, tc := range parseDurationErrorTests { + _, err := ParseDuration(tc.in) + if err == nil { t.Errorf("ParseDuration(%q) = _, nil, want _, non-nil", tc.in) + } else if !strings.Contains(err.Error(), tc.expect) { + t.Errorf("ParseDuration(%q) = _, %q, error does not contain %q", tc.in, err, tc.expect) } } } @@ -1348,6 +1372,13 @@ func BenchmarkDay(b *testing.B) { } } +func BenchmarkISOWeek(b *testing.B) { + t := Now() + for i := 0; i < b.N; i++ { + _, _ = t.ISOWeek() + } +} + func TestMarshalBinaryZeroTime(t *testing.T) { t0 := Time{} enc, err := t0.MarshalBinary() diff --git a/libgo/go/time/tzdata/generate_zipdata.go b/libgo/go/time/tzdata/generate_zipdata.go new file mode 100644 index 00000000000..d8b47e7878c --- /dev/null +++ b/libgo/go/time/tzdata/generate_zipdata.go @@ -0,0 +1,78 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +// This program generates zipdata.go from $GOROOT/lib/time/zoneinfo.zip. +package main + +import ( + "bufio" + "fmt" + "io/ioutil" + "os" + "strconv" +) + +// header is put at the start of the generated file. +// The string addition avoids this file (generate_zipdata.go) from +// matching the "generated file" regexp. +const header = `// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +` + `// Code generated by generate_zipdata. DO NOT EDIT. + +// This file contains an embedded zip archive that contains time zone +// files compiled using the code and data maintained as part of the +// IANA Time Zone Database. +// The IANA asserts that the data is in the public domain. + +// For more information, see +// https://www.iana.org/time-zones +// ftp://ftp.iana.org/tz/code/tz-link.htm +// http://tools.ietf.org/html/rfc6557 + +package tzdata + +const zipdata = ` + +func main() { + // We should be run in the $GOROOT/src/time/tzdata directory. + data, err := ioutil.ReadFile("../../../lib/time/zoneinfo.zip") + if err != nil { + die("cannot find zoneinfo.zip file: %v", err) + } + + of, err := os.Create("zipdata.go") + if err != nil { + die("%v", err) + } + + buf := bufio.NewWriter(of) + buf.WriteString(header) + + ds := string(data) + i := 0 + const chunk = 60 + for ; i+chunk < len(data); i += chunk { + if i > 0 { + buf.WriteRune('\t') + } + fmt.Fprintf(buf, "%s +\n", strconv.Quote(ds[i:i+chunk])) + } + fmt.Fprintf(buf, "\t%s\n", strconv.Quote(ds[i:])) + + if err := buf.Flush(); err != nil { + die("error writing to zipdata.go: %v", err) + } + if err := of.Close(); err != nil { + die("error closing zipdata.go: %v", err) + } +} + +func die(format string, args ...interface{}) { + fmt.Fprintf(os.Stderr, format+"\n", args...) + os.Exit(1) +} diff --git a/libgo/go/time/tzdata/tzdata.go b/libgo/go/time/tzdata/tzdata.go new file mode 100644 index 00000000000..fd6d6e3fc10 --- /dev/null +++ b/libgo/go/time/tzdata/tzdata.go @@ -0,0 +1,109 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:generate go run generate_zipdata.go + +// Package tzdata provides an embedded copy of the timezone database. +// If this package is imported anywhere in the program, then if +// the time package cannot find tzdata files on the system, +// it will use this embedded information. +// +// Importing this package will increase the size of a program by about +// 800 KB. +// +// This package should normally be imported by a program's main package, +// not by a library. Libraries normally shouldn't decide whether to +// include the timezone database in a program. +// +// This package will be automatically imported if you build with +// -tags timetzdata. +package tzdata + +// The test for this package is time/tzdata_test.go. + +import ( + "errors" + "syscall" + _ "unsafe" // for go:linkname +) + +// registerLoadFromEmbeddedTZData is defined in package time. +//go:linkname registerLoadFromEmbeddedTZData time.registerLoadFromEmbeddedTZData +func registerLoadFromEmbeddedTZData(func(string) (string, error)) + +func init() { + registerLoadFromEmbeddedTZData(loadFromEmbeddedTZData) +} + +// get4s returns the little-endian 32-bit value at the start of s. +func get4s(s string) int { + if len(s) < 4 { + return 0 + } + return int(s[0]) | int(s[1])<<8 | int(s[2])<<16 | int(s[3])<<24 +} + +// get2s returns the little-endian 16-bit value at the start of s. +func get2s(s string) int { + if len(s) < 2 { + return 0 + } + return int(s[0]) | int(s[1])<<8 +} + +// loadFromEmbeddedTZData returns the contents of the file with the given +// name in an uncompressed zip file, where the contents of the file can +// be found in embeddedTzdata. +// This is similar to time.loadTzinfoFromZip. +func loadFromEmbeddedTZData(name string) (string, error) { + const ( + zecheader = 0x06054b50 + zcheader = 0x02014b50 + ztailsize = 22 + + zheadersize = 30 + zheader = 0x04034b50 + ) + + z := zipdata + + idx := len(z) - ztailsize + n := get2s(z[idx+10:]) + idx = get4s(z[idx+16:]) + + for i := 0; i < n; i++ { + // See time.loadTzinfoFromZip for zip entry layout. + if get4s(z[idx:]) != zcheader { + break + } + meth := get2s(z[idx+10:]) + size := get4s(z[idx+24:]) + namelen := get2s(z[idx+28:]) + xlen := get2s(z[idx+30:]) + fclen := get2s(z[idx+32:]) + off := get4s(z[idx+42:]) + zname := z[idx+46 : idx+46+namelen] + idx += 46 + namelen + xlen + fclen + if zname != name { + continue + } + if meth != 0 { + return "", errors.New("unsupported compression for " + name + " in embedded tzdata") + } + + // See time.loadTzinfoFromZip for zip per-file header layout. + idx = off + if get4s(z[idx:]) != zheader || + get2s(z[idx+8:]) != meth || + get2s(z[idx+26:]) != namelen || + z[idx+30:idx+30+namelen] != name { + return "", errors.New("corrupt embedded tzdata") + } + xlen = get2s(z[idx+28:]) + idx += 30 + namelen + xlen + return z[idx : idx+size], nil + } + + return "", syscall.ENOENT +} diff --git a/libgo/go/time/tzdata/zipdata.go b/libgo/go/time/tzdata/zipdata.go new file mode 100644 index 00000000000..483d6740881 --- /dev/null +++ b/libgo/go/time/tzdata/zipdata.go @@ -0,0 +1,13060 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by generate_zipdata. DO NOT EDIT. + +// This file contains an embedded zip archive that contains time zone +// files compiled using the code and data maintained as part of the +// IANA Time Zone Database. +// The IANA asserts that the data is in the public domain. + +// For more information, see +// https://www.iana.org/time-zones +// ftp://ftp.iana.org/tz/code/tz-link.htm +// http://tools.ietf.org/html/rfc6557 + +package tzdata + +const zipdata = "PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x1c\x00Africa/UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00" + + "\x04\x14\x00\x00\x00PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPo\xa5)\xa4\xfe\x00\x00\x00\xfe\x00\x00\x00\x0f\x00\x1c\x00Africa/Sao_TomeUT\t\x00\x03nӧ^n" + + "ӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00" + + "\x00\f\x80\x00\x00\x00\x92掀ZI\x88\x10\\*\xbb\x90\x01\x02\x03\x04\x00\x00\x06P\x00\x00\xff\xff\xf7c\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x00\b\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00" + + "WAT\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\f\xff\xff" + + "\xff\xff^<\xfd0\xff\xff\xff\xff\x92掀\x00\x00\x00\x00ZI\x88\x10\x00\x00\x00\x00\\*\xbb\x90\x01\x02\x03\x04\x00\x00\x06P\x00\x00\xff\xff\xf7c\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x00\b\x00\x00" + + "\x00\x00\x00\x04LMT\x00GMT\x00WAT\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xae\x18\x88\x94\x00\x00\x00\x94\x00\x00\x00\x0e\x00" + + "\x1c\x00Africa/ConakryUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00TZif2\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LM" + + "T\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xae\x18\x88\x94\x00\x00\x00\x94\x00\x00\x00\f\x00\x1c\x00Africa/DakarUT\t\x00\x03n" + + "ӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" + + "\x00\x02\x00\x00\x00\b\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00" + + "\xf5F\x9cP\xa3\x12>\xaa\xc7\x00\x00\x00\xc7\x00\x00\x00\x0f\x00\x1c\x00Africa/NdjamenaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14" + + "\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\r\x92\xe6\x80d\x12fqp\x13&\xde`\x01" + + "\x02\x01\x00\x00\x0e\x1c\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLMT\x00WAT\x00WAST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff\x92\xe6\x80d\x00\x00\x00\x00\x12fqp\x00\x00\x00\x00\x13&\xde`\x01\x02\x01\x00\x00\x0e\x1c\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c " + + "\x01\bLMT\x00WAT\x00WAST\x00\nWAT-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xd4K-\x14}\t\x00\x00}\t\x00\x00\x11\x00\x1c\x00Africa/C" + + "asablancaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00_\x00\x00\x00\x05\x00\x00\x00\f\x96Q\xf9\x9c\xc6\xff\x14\x80\xc7X\xacp\xc7\xd9\xed\x80ҡ2\xf0\xdb5\xa4\x00\xdb\xee'\xf0\xfb%r@\xfb\xc2\xefp\bk\x84" + + "\x80\b\xc6m\xf0\v\xe8\f\x00\faG\xf0\r\xc9?\x80\x0e\x8e\xf2p\x0f\xd3Q\x80\x10'\xa3p\x1a\xb7\xa6\x00\x1e\x18o\xf0HA\xe6\x80H\xbb\"pJ#\x1a\x00J\x8d\xd5pK\xdc\xc0\x80L]\xe5" + + "pM\x97\xb8\x80N4\x8c\xf0O\x9c\xa0\xa0P\b\xbb\xa0P1\x9a Pg\xa7\xa0Q|\x82\xa0Q\xd8ˠR\x05\x9e\xa0Rls\xa0S7z\xa0S\xae!\xa0S\xdcF TLU\xa0U\x17\\" + + "\xa0U|\xe0 U\xab\x04\xa0V,7\xa0V\xf7>\xa0WS\x87\xa0W\x81\xac X\x15T X\xd7 \xa0Y \xf4\xa0YXS\xa0Y\xf56 Z\xb7\x02\xa0Z\xf7\x9c [%\xc0\xa0[\xd5\x18" + + " \\\xceC\xa0\\\xfch ^\x9b\xb0\xa0^\xd3\x0f\xa0`rX `\xa0|\xa0b?\xc5 bw$ d\x16l\xa0dD\x91 e\xed\x14 f\x1b8\xa0g\xba\x81 g\xf1\xe0 i\x91(" + + "\xa0i\xbfM kg\xd0 k\x95\xf4\xa0m5= ml\x9c o\v\xe4\xa0o:\t p\xd9Q\xa0q\x10\xb0\xa0r\xaf\xf9 r\xde\x1d\xa0t\x86\xa0\xa0t\xb4\xc5 vT\r\xa0v\x8bl" + + "\xa0x*\xb5 xX٠y\xf8\" z/\x81 {\xceɠ|\x06(\xa0}\xa5q }ӕ\xa0\u007fr\xde \u007f\xaa= \x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\xff\xff\xf8\xe4\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x0e\x10\x00\x04\x00\x00\x00\x00\x01\bLMT\x00+01\x00+00\x00TZ" + + "if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\x00\x00\x00\x05\x00\x00\x00\f\xff\xff\xff\xff\x96Q\xf9\x9c\xff\xff\xff\xff\xc6\xff\x14\x80\xff\xff" + + "\xff\xff\xc7X\xacp\xff\xff\xff\xff\xc7\xd9\xed\x80\xff\xff\xff\xffҡ2\xf0\xff\xff\xff\xff\xdb5\xa4\x00\xff\xff\xff\xff\xdb\xee'\xf0\xff\xff\xff\xff\xfb%r@\xff\xff\xff\xff\xfb\xc2\xefp\x00\x00\x00\x00\bk" + + "\x84\x80\x00\x00\x00\x00\b\xc6m\xf0\x00\x00\x00\x00\v\xe8\f\x00\x00\x00\x00\x00\faG\xf0\x00\x00\x00\x00\r\xc9?\x80\x00\x00\x00\x00\x0e\x8e\xf2p\x00\x00\x00\x00\x0f\xd3Q\x80\x00\x00\x00\x00\x10'\xa3p\x00\x00" + + "\x00\x00\x1a\xb7\xa6\x00\x00\x00\x00\x00\x1e\x18o\xf0\x00\x00\x00\x00HA\xe6\x80\x00\x00\x00\x00H\xbb\"p\x00\x00\x00\x00J#\x1a\x00\x00\x00\x00\x00J\x8d\xd5p\x00\x00\x00\x00K\xdc\xc0\x80\x00\x00\x00\x00L]" + + "\xe5p\x00\x00\x00\x00M\x97\xb8\x80\x00\x00\x00\x00N4\x8c\xf0\x00\x00\x00\x00O\x9c\xa0\xa0\x00\x00\x00\x00P\b\xbb\xa0\x00\x00\x00\x00P1\x9a \x00\x00\x00\x00Pg\xa7\xa0\x00\x00\x00\x00Q|\x82\xa0\x00\x00" + + "\x00\x00Q\xd8ˠ\x00\x00\x00\x00R\x05\x9e\xa0\x00\x00\x00\x00Rls\xa0\x00\x00\x00\x00S7z\xa0\x00\x00\x00\x00S\xae!\xa0\x00\x00\x00\x00S\xdcF \x00\x00\x00\x00TLU\xa0\x00\x00\x00\x00U\x17" + + "\\\xa0\x00\x00\x00\x00U|\xe0 \x00\x00\x00\x00U\xab\x04\xa0\x00\x00\x00\x00V,7\xa0\x00\x00\x00\x00V\xf7>\xa0\x00\x00\x00\x00WS\x87\xa0\x00\x00\x00\x00W\x81\xac \x00\x00\x00\x00X\x15T \x00\x00" + + "\x00\x00X\xd7 \xa0\x00\x00\x00\x00Y \xf4\xa0\x00\x00\x00\x00YXS\xa0\x00\x00\x00\x00Y\xf56 \x00\x00\x00\x00Z\xb7\x02\xa0\x00\x00\x00\x00Z\xf7\x9c \x00\x00\x00\x00[%\xc0\xa0\x00\x00\x00\x00[\xd5" + + "\x18 \x00\x00\x00\x00\\\xceC\xa0\x00\x00\x00\x00\\\xfch \x00\x00\x00\x00^\x9b\xb0\xa0\x00\x00\x00\x00^\xd3\x0f\xa0\x00\x00\x00\x00`rX \x00\x00\x00\x00`\xa0|\xa0\x00\x00\x00\x00b?\xc5 \x00\x00" + + "\x00\x00bw$ \x00\x00\x00\x00d\x16l\xa0\x00\x00\x00\x00dD\x91 \x00\x00\x00\x00e\xed\x14 \x00\x00\x00\x00f\x1b8\xa0\x00\x00\x00\x00g\xba\x81 \x00\x00\x00\x00g\xf1\xe0 \x00\x00\x00\x00i\x91" + + "(\xa0\x00\x00\x00\x00i\xbfM \x00\x00\x00\x00kg\xd0 \x00\x00\x00\x00k\x95\xf4\xa0\x00\x00\x00\x00m5= \x00\x00\x00\x00ml\x9c \x00\x00\x00\x00o\v\xe4\xa0\x00\x00\x00\x00o:\t \x00\x00" + + "\x00\x00p\xd9Q\xa0\x00\x00\x00\x00q\x10\xb0\xa0\x00\x00\x00\x00r\xaf\xf9 \x00\x00\x00\x00r\xde\x1d\xa0\x00\x00\x00\x00t\x86\xa0\xa0\x00\x00\x00\x00t\xb4\xc5 \x00\x00\x00\x00vT\r\xa0\x00\x00\x00\x00v\x8b" + + "l\xa0\x00\x00\x00\x00x*\xb5 \x00\x00\x00\x00xX٠\x00\x00\x00\x00y\xf8\" \x00\x00\x00\x00z/\x81 \x00\x00\x00\x00{\xceɠ\x00\x00\x00\x00|\x06(\xa0\x00\x00\x00\x00}\xa5q \x00\x00" + + "\x00\x00}ӕ\xa0\x00\x00\x00\x00\u007fr\xde \x00\x00\x00\x00\u007f\xaa= \x00\x00\x00\x00\x81I\x85\xa0\x00\x00\x00\x00\x81w\xaa \x00\x00\x00\x00\x83 - \x00\x00\x00\x00\x83NQ\xa0\x00\x00\x00\x00\x84\xed" + + "\x9a \x00\x00\x00\x00\x85$\xf9 \x00\x00\x00\x00\x86\xc4A\xa0\x00\x00\x00\x00\x86\xf2f \x00\x00\x00\x00\x88\x91\xae\xa0\x00\x00\x00\x00\x88\xc9\r\xa0\x00\x00\x00\x00\x8ahV \x00\x00\x00\x00\x8a\x9f\xb5 \x00\x00" + + "\x00\x00\x8c>\xfd\xa0\x00\x00\x00\x00\x8cm\" \x00\x00\x00\x00\x8e\fj\xa0\x00\x00\x00\x00\x8eCɠ\x00\x00\x00\x00\x8f\xe3\x12 \x00\x00\x00\x00\x90\x116\xa0\x00\x00\x00\x00\x91\xb9\xb9\xa0\x00\x00\x00\x00\x91\xe7" + + "\xde \x00\x00\x00\x00\x93\x87&\xa0\x00\x00\x00\x00\x93\xbe\x85\xa0\x00\x00\x00\x00\x95]\xce \x00\x00\x00\x00\x95\x8b\xf2\xa0\x00\x00\x00\x00\x97+; \x00\x00\x00\x00\x97b\x9a \x00\x00\x00\x00\x99\x01\xe2\xa0\x00\x00" + + "\x00\x00\x999A\xa0\x00\x00\x00\x00\x9a؊ \x00\x00\x00\x00\x9b\x06\xae\xa0\x00\x00\x00\x00\x9c\xa5\xf7 \x00\x00\x00\x00\x9c\xddV \x00\x00\x00\x00\x9e|\x9e\xa0\x00\x00\x00\x00\x9e\xaa\xc3 \x00\x00\x00\x00\xa0S" + + "F \x00\x00\x00\x00\xa0\x81j\xa0\x00\x00\x00\x00\xa2 \xb3 \x00\x00\x00\x00\xa2X\x12 \x00\x00\x00\x00\xa3\xf7Z\xa0\x00\x00\x00\x00\xa4%\u007f \x00\x00\x00\x00\xa5\xc4Ǡ\x00\x00\x00\x00\xa5\xfc&\xa0\x00\x00" + + "\x00\x00\xa7\x9bo \x00\x00\x00\x00\xa7\xd2\xce \x00\x00\x00\x00\xa9r\x16\xa0\x00\x00\x00\x00\xa9\xa0; \x00\x00\x00\x00\xab?\x83\xa0\x00\x00\x00\x00\xabv\xe2\xa0\x00\x00\x00\x00\xad\x16+ \x00\x00\x00\x00\xadD" + + "O\xa0\x00\x00\x00\x00\xae\xecҠ\x00\x00\x00\x00\xaf\x1a\xf7 \x00\x00\x00\x00\xb0\xba?\xa0\x00\x00\x00\x00\xb0\xf1\x9e\xa0\x00\x00\x00\x00\xb2\x90\xe7 \x00\x00\x00\x00\xb2\xbf\v\xa0\x00\x00\x00\x00\xb4^T \x00\x00" + + "\x00\x00\xb4\x95\xb3 \x00\x00\x00\x00\xb64\xfb\xa0\x00\x00\x00\x00\xb6lZ\xa0\x00\x00\x00\x00\xb8\v\xa3 \x00\x00\x00\x00\xb89Ǡ\x00\x00\x00\x00\xb9\xd9\x10 \x00\x00\x00\x00\xba\x10o \x00\x00\x00\x00\xbb\xaf" + + "\xb7\xa0\x00\x00\x00\x00\xbb\xdd\xdc \x00\x00\x00\x00\xbd\x86_ \x00\x00\x00\x00\xbd\xb4\x83\xa0\x00\x00\x00\x00\xbfS\xcc \x00\x00\x00\x00\xbf\x8b+ \x00\x00\x00\x00\xc1*s\xa0\x00\x00\x00\x00\xc1X\x98 \x00\x00" + + "\x00\x00\xc2\xf7\xe0\xa0\x00\x00\x00\x00\xc3/?\xa0\x00\x00\x00\x00\xc4Έ \x00\x00\x00\x00\xc5\x05\xe7 \x00\x00\x00\x00ƥ/\xa0\x00\x00\x00\x00\xc6\xd3T \x00\x00\x00\x00\xc8r\x9c\xa0\x00\x00\x00\x00ȩ" + + "\xfb\xa0\x00\x00\x00\x00\xcaID \x00\x00\x00\x00\xcawh\xa0\x00\x00\x00\x00\xcc\x1f\xeb\xa0\x00\x00\x00\x00\xccN\x10 \x00\x00\x00\x00\xcd\xedX\xa0\x00\x00\x00\x00\xce$\xb7\xa0\x00\x00\x00\x00\xcf\xc4\x00 \x00\x00" + + "\x00\x00\xcf\xf2$\xa0\x00\x00\x00\x00ёm \x00\x00\x00\x00\xd1\xc8\xcc \x00\x00\x00\x00\xd3h\x14\xa0\x00\x00\x00\x00Ӗ9 \x00\x00\x00\x00\xd5>\xbc \x00\x00\x00\x00\xd5l\xe0\xa0\x00\x00\x00\x00\xd7\f" + + ") \x00\x00\x00\x00\xd7C\x88 \x00\x00\x00\x00\xd8\xe2Р\x00\x00\x00\x00\xd9\x10\xf5 \x00\x00\x00\x00ڹx \x00\x00\x00\x00\xda眠\x00\x00\x00\x00܆\xe5 \x00\x00\x00\x00ܾD \x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\xff\xff\xf8\xe4\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x0e\x10\x00\x04\x00\x00\x00\x00\x01\bLMT\x00+01\x00+00\x00\n<+" + + "01>-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xae\x18\x88\x94\x00\x00\x00\x94\x00\x00\x00\v\x00\x1c\x00Africa/LomeUT\t\x00\x03nӧ^nӧ^" + + "ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\x92" + + "\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" + + "\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x8d>\xe1" + + "4\xdf\x02\x00\x00\xdf\x02\x00\x00\x0e\x00\x1c\x00Africa/AlgiersUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\b\x00\x00\x00\x1a\x80\x00\x00\x00\x91`PO\x9bGx\xf0\x9b\xd7,p\x9c\xbc\x91p\x9d" + + "\xc0H\xf0\x9e\x89\xfep\x9f\xa0*\xf0\xa0`\xa5\xf0\xa1\x80\f\xf0\xa2.\x12\xf0\xa3zL\xf0\xa45\x81\xf0\xa4\xb8\x06p\xc6\xff\x06p\xc7X\xba\x80\xc7\xda\t\xa0ϒ4\x10Њ\x00\x00\xd1r\x16\x10\xd2" + + "N$p\xd4K\ap\xe5\xce\xd3\x00\xf3\\\xb0\xf0\x02x\xc1\xf0\x03C\xc8\xf0\r\xcf\xd7\x00\x0e\xadD\xf0\x0fxZ\x00\x10hY\x10\x12vCp\x13fB\x80\x14_|\x10\x15O_\x00\x01\x04\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x06\x05\x06\x05\x06\x04\x06\x04\x02\x03\a\x06\x05\x06\x04\a\x04\x06\x00\x00\x02\xdc\x00\x00\x00\x00\x021\x00\x04\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\r\x00\x00\x00\x00\x00\r\x00" + + "\x00\x1c \x01\x11\x00\x00\x0e\x10\x00\x16\x00\x00\x0e\x10\x01\bLMT\x00PMT\x00WEST\x00WET\x00CEST\x00CET\x00\x00\x00\x01\x01\x00\x00\x00\x00TZif2\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\b\x00\x00\x00\x1a\xff\xff\xff\xffk\xc8I\xe0\xff\xff\xff\xff\x91`PO\xff\xff\xff\xff\x9bGx\xf0\xff" + + "\xff\xff\xff\x9b\xd7,p\xff\xff\xff\xff\x9c\xbc\x91p\xff\xff\xff\xff\x9d\xc0H\xf0\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0*\xf0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1\x80\f\xf0\xff\xff\xff\xff\xa2" + + ".\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45\x81\xf0\xff\xff\xff\xff\xa4\xb8\x06p\xff\xff\xff\xff\xc6\xff\x06p\xff\xff\xff\xff\xc7X\xba\x80\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xffϒ4\x10\xff" + + "\xff\xff\xffЊ\x00\x00\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N$p\xff\xff\xff\xff\xd4K\ap\xff\xff\xff\xff\xe5\xce\xd3\x00\xff\xff\xff\xff\xf3\\\xb0\xf0\x00\x00\x00\x00\x02x\xc1\xf0\x00\x00\x00\x00\x03" + + "C\xc8\xf0\x00\x00\x00\x00\r\xcf\xd7\x00\x00\x00\x00\x00\x0e\xadD\xf0\x00\x00\x00\x00\x0fxZ\x00\x00\x00\x00\x00\x10hY\x10\x00\x00\x00\x00\x12vCp\x00\x00\x00\x00\x13fB\x80\x00\x00\x00\x00\x14_|\x10\x00" + + "\x00\x00\x00\x15O_\x00\x01\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x06\x05\x06\x05\x06\x04\x06\x04\x02\x03\a\x06\x05\x06\x04\a\x04\x06\x00\x00\x02\xdc\x00\x00\x00\x00\x021\x00\x04\x00\x00\x0e\x10\x01\b\x00" + + "\x00\x00\x00\x00\r\x00\x00\x00\x00\x00\r\x00\x00\x1c \x01\x11\x00\x00\x0e\x10\x00\x16\x00\x00\x0e\x10\x01\bLMT\x00PMT\x00WEST\x00WET\x00CEST\x00CET\x00\x00\x00\x01\x01\x00" + + "\x00\x00\x00\nCET-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPx=\xfb\xae\xfb\x00\x00\x00\xfb\x00\x00\x00\x10\x00\x1c\x00Africa/MogadishuUT\t\x00" + + "\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04" + + "\x00\x00\x00\x05\x00\x00\x00\x14\xb1\xee\xda\xfc\xb4\u009a\xd0ǑG\xd8\xed/\xe1\xd4\x01\x02\x03\x01\x00\x00\"\x84\x00\x00\x00\x00*0\x00\x04\x00\x00#(\x00\b\x00\x00&\xac\x00\x0e\x00\x00*0\x00\x04LM" + + "T\x00EAT\x00+0230\x00+0245\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00" + + "\x00\x14\xff\xff\xff\xff\xb1\xee\xda\xfc\xff\xff\xff\xff\xb4\u009a\xd0\xff\xff\xff\xffǑG\xd8\xff\xff\xff\xff\xed/\xe1\xd4\x01\x02\x03\x01\x00\x00\"\x84\x00\x00\x00\x00*0\x00\x04\x00\x00#(\x00\b\x00\x00&\xac" + + "\x00\x0e\x00\x00*0\x00\x04LMT\x00EAT\x00+0230\x00+0245\x00\nEAT-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP.\x85\x1f\xf0\x95\x00\x00\x00\x95\x00\x00" + + "\x00\f\x00\x1c\x00Africa/LagosUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xa1Q\xf3P\x01\x00\x00\x030\x00\x00\x00\x00\x0e\x10\x00\x04LMT\x00WAT\x00TZif2\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xa1Q\xf3P\x01\x00\x00\x030\x00\x00\x00\x00\x0e\x10\x00\x04L" + + "MT\x00WAT\x00\nWAT-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP.\x85\x1f\xf0\x95\x00\x00\x00\x95\x00\x00\x00\x12\x00\x1c\x00Africa/Brazzavil" + + "leUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xa1Q\xf3P\x01\x00\x00\x030\x00\x00\x00\x00\x0e\x10\x00\x04LMT\x00WAT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xa1Q\xf3P\x01\x00\x00\x030\x00\x00\x00\x00\x0e\x10\x00\x04LMT\x00WAT\x00\nWAT-1\nP" + + "K\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xae\x18\x88\x94\x00\x00\x00\x94\x00\x00\x00\x0f\x00\x1c\x00Africa/TimbuktuUT\t\x00\x03nӧ^nӧ^ux\v" + + "\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\x92\xe6\x92H" + + "\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" + + "\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xae\x18\x88\x94\x00" + + "\x00\x00\x94\x00\x00\x00\x11\x00\x1c\x00Africa/NouakchottUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00" + + "GMT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc" + + "8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb1\x980\xb2\xf6\x00\x00\x00\xf6\x00\x00\x00\r\x00\x1c\x00Africa/" + + "MaseruUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\t\x80\x00\x00\x00\x82F\xcfḫ\x8c\x80͞opΎn\x80\xcf~Qp\x01\x03\x02\x03\x02\x03\x00\x00\x1a@\x00\x00\x00\x00\x15\x18\x00\x04" + + "\x00\x00*0\x01\x04\x00\x00\x1c \x00\x04LMT\x00SAST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00" + + "\x04\x00\x00\x00\t\xff\xff\xff\xffm{A@\xff\xff\xff\xff\x82F\xcfh\xff\xff\xff\xff̮\x8c\x80\xff\xff\xff\xff͞op\xff\xff\xff\xffΎn\x80\xff\xff\xff\xff\xcf~Qp\x01\x03\x02\x03\x02\x03\x00" + + "\x00\x1a@\x00\x00\x00\x00\x15\x18\x00\x04\x00\x00*0\x01\x04\x00\x00\x1c \x00\x04LMT\x00SAST\x00\nSAST-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP.\x85\x1f\xf0\x95\x00" + + "\x00\x00\x95\x00\x00\x00\x11\x00\x1c\x00Africa/LibrevilleUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xa1Q\xf3P\x01\x00\x00\x030\x00\x00\x00\x00\x0e\x10\x00\x04LMT\x00" + + "WAT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xa1Q\xf3P\x01\x00\x00\x03" + + "0\x00\x00\x00\x00\x0e\x10\x00\x04LMT\x00WAT\x00\nWAT-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP4\x8b\xa4 \x95\x00\x00\x00\x95\x00\x00\x00\r\x00\x1c\x00Africa" + + "/HarareUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCA" + + "T-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP.\x85\x1f\xf0\x95\x00\x00\x00\x95\x00\x00\x00\r\x00\x1c\x00Africa/MalaboUT\t\x00\x03nӧ^nӧ^" + + "ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xa1" + + "Q\xf3P\x01\x00\x00\x030\x00\x00\x00\x00\x0e\x10\x00\x04LMT\x00WAT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" + + "\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xa1Q\xf3P\x01\x00\x00\x030\x00\x00\x00\x00\x0e\x10\x00\x04LMT\x00WAT\x00\nWAT-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP.\x85" + + "\x1f\xf0\x95\x00\x00\x00\x95\x00\x00\x00\r\x00\x1c\x00Africa/BanguiUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xa1Q\xf3P\x01\x00\x00\x030\x00\x00\x00\x00\x0e\x10\x00\x04LMT\x00" + + "WAT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xa1Q\xf3P\x01\x00\x00\x03" + + "0\x00\x00\x00\x00\x0e\x10\x00\x04LMT\x00WAT\x00\nWAT-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPx=\xfb\xae\xfb\x00\x00\x00\xfb\x00\x00\x00\x0e\x00\x1c\x00Africa" + + "/NairobiUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x14\xb1\xee\xda\xfc\xb4\u009a\xd0ǑG\xd8\xed/\xe1\xd4\x01\x02\x03\x01\x00\x00\"\x84\x00\x00\x00\x00*0\x00\x04\x00\x00#(\x00\b\x00\x00" + + "&\xac\x00\x0e\x00\x00*0\x00\x04LMT\x00EAT\x00+0230\x00+0245\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xb1\xee\xda\xfc\xff\xff\xff\xff\xb4\u009a\xd0\xff\xff\xff\xffǑG\xd8\xff\xff\xff\xff\xed/\xe1\xd4\x01\x02\x03\x01\x00\x00\"\x84\x00\x00\x00\x00*0" + + "\x00\x04\x00\x00#(\x00\b\x00\x00&\xac\x00\x0e\x00\x00*0\x00\x04LMT\x00EAT\x00+0230\x00+0245\x00\nEAT-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9c" + + "P.\x85\x1f\xf0\x95\x00\x00\x00\x95\x00\x00\x00\x0f\x00\x1c\x00Africa/KinshasaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00" + + "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xa1Q\xf3P\x01\x00\x00\x030\x00\x00\x00\x00\x0e\x10\x00" + + "\x04LMT\x00WAT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xa1Q\xf3" + + "P\x01\x00\x00\x030\x00\x00\x00\x00\x0e\x10\x00\x04LMT\x00WAT\x00\nWAT-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP.\x85\x1f\xf0\x95\x00\x00\x00\x95\x00\x00\x00\x11\x00\x1c\x00A" + + "frica/Porto-NovoUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xa1Q\xf3P\x01\x00\x00\x030\x00\x00\x00\x00\x0e\x10\x00\x04LMT\x00WAT\x00TZif2\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xa1Q\xf3P\x01\x00\x00\x030\x00\x00\x00\x00\x0e\x10\x00\x04LM" + + "T\x00WAT\x00\nWAT-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPtg&ף\a\x00\x00\xa3\a\x00\x00\f\x00\x1c\x00Africa/CairoUT\t\x00\x03" + + "nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\u007f\x00" + + "\x00\x00\x04\x00\x00\x00\r\x80\x00\x00\x00ȓ\xb4\xe0\xc8\xfa{\xd0\xc9\xfc\xef\xe0\xca\xc7\xe8\xd0\xcbˮ`\xcc\xdf)\xd0ͬ\xe1\xe0\xce\xc6\xf4\xd0Ϗf\xe0Щy\xd0ф`\xe0Ҋ\xadP\xe8" + + "6c`\xe8\xf4-P\xea\v\xb9`\xea\xd5`\xd0\xeb\xec\xfa\xf0\xec\xb5m\x00\xed\xcf\u007f\xf0\xee\x97\xf2\x00ﰳp\xf0y%\x80\xf1\x91\xe6\xf0\xf2ZY\x00\xf3s\x1ap\xf4;\x8c\x80\xf5U\x9fp\xf6" + + "\x1e\x11\x80\xf76\xd2\xf0\xf7\xffE\x00\xf9\x18\x06p\xf9\xe1\xca\x00\xfa\xf99\xf0\xfb\xc2\xfd\x80\xfc۾\xf0\xfd\xa5\x82\x80\xfe\xbc\xf2p\xff\x86\xb6\x00\x00\x9e%\xf0\x01g\xe9\x80\x02\u007fYp\x03I\x1d\x00\x04" + + "a\xdep\x05+\xa2\x00\x06C\x11\xf0\a\fՀ\b$Ep\b\xee\t\x00\n\x05x\xf0\n\xcf<\x80\v\xe7\xfd\xf0\f\xb1\xc1\x80\r\xc91p\x0e\x92\xf5\x00\x0f\xaad\xf0\x10t(\x80\x11\x8b\x98p\x12" + + "U\\\x00\x13n\x1dp\x147\xe1\x00\x15OP\xf0\x16\x19\x14\x80\x17\xa0\x93\xf0\x17\xfaH\x00\x19p\xa3\xf0\x19\xdb{\x80\x1a\xf4<\xf0\x1b\xbe\x00\x80\x1c\xd5pp\x1d\x9f4\x00\x1e\xb6\xa3\xf0\x1f\x80g\x80 " + + "\x97\xd7p!a\x9b\x00\"z\\p#D \x00$b'p%%S\x80&<\xc3p'\x06\x87\x00(\x1d\xf6\xf0(纀*\x00{\xf0*\xca?\x80+\xe1\xafp,\xabs\x00-\xc2\xe2\xf0." + + "\x8c\xa6\x80/\xa0\x13\xe00k\f\xd01\u007f\xf5\xe02J\xee\xd03_\xd7\xe04*\xd0\xd05?\xb9\xe06\n\xb2\xd07(\xd6`7\xf3\xcfP9\b\xb8`9ӱP:\xe8\x9a`;\xb3\x93P<" + + "\xc8|`=\x93uP>\xa8^`?sWP@\x91z\xe0A\\s\xd0Bq\\\xe0C\xe0E\x12\xfdPF1 \xe0F\xe0jPH\x11\x02\xe0H\xb7\x11\xd0I\xf0\xe4\xe0J" + + "\x8d\xb9PK\xda\x01`La\xbd\xd0L\x89X\xe0L\xa4\xfaPSu8\xe0S\xac\x89\xd0Sڼ`T$\x82P\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x01\x02\x01\x02\x01\x02\x00\x00\x1dU\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t" + + "\x00\x00*0\x01\x04LMT\x00EEST\x00EET\x00\x00\x00\x00\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\u007f\x00" + + "\x00\x00\x04\x00\x00\x00\r\xff\xff\xff\xff}\xbdM\xab\xff\xff\xff\xffȓ\xb4\xe0\xff\xff\xff\xff\xc8\xfa{\xd0\xff\xff\xff\xff\xc9\xfc\xef\xe0\xff\xff\xff\xff\xca\xc7\xe8\xd0\xff\xff\xff\xff\xcbˮ`\xff\xff\xff\xff\xcc" + + "\xdf)\xd0\xff\xff\xff\xffͬ\xe1\xe0\xff\xff\xff\xff\xce\xc6\xf4\xd0\xff\xff\xff\xffϏf\xe0\xff\xff\xff\xffЩy\xd0\xff\xff\xff\xffф`\xe0\xff\xff\xff\xffҊ\xadP\xff\xff\xff\xff\xe86c`\xff" + + "\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea\v\xb9`\xff\xff\xff\xff\xea\xd5`\xd0\xff\xff\xff\xff\xeb\xec\xfa\xf0\xff\xff\xff\xff\xec\xb5m\x00\xff\xff\xff\xff\xed\xcf\u007f\xf0\xff\xff\xff\xff\xee\x97\xf2\x00\xff\xff\xff\xff\xef" + + "\xb0\xb3p\xff\xff\xff\xff\xf0y%\x80\xff\xff\xff\xff\xf1\x91\xe6\xf0\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3s\x1ap\xff\xff\xff\xff\xf4;\x8c\x80\xff\xff\xff\xff\xf5U\x9fp\xff\xff\xff\xff\xf6\x1e\x11\x80\xff" + + "\xff\xff\xff\xf76\xd2\xf0\xff\xff\xff\xff\xf7\xffE\x00\xff\xff\xff\xff\xf9\x18\x06p\xff\xff\xff\xff\xf9\xe1\xca\x00\xff\xff\xff\xff\xfa\xf99\xf0\xff\xff\xff\xff\xfb\xc2\xfd\x80\xff\xff\xff\xff\xfc۾\xf0\xff\xff\xff\xff\xfd" + + "\xa5\x82\x80\xff\xff\xff\xff\xfe\xbc\xf2p\xff\xff\xff\xff\xff\x86\xb6\x00\x00\x00\x00\x00\x00\x9e%\xf0\x00\x00\x00\x00\x01g\xe9\x80\x00\x00\x00\x00\x02\u007fYp\x00\x00\x00\x00\x03I\x1d\x00\x00\x00\x00\x00\x04a\xdep\x00" + + "\x00\x00\x00\x05+\xa2\x00\x00\x00\x00\x00\x06C\x11\xf0\x00\x00\x00\x00\a\fՀ\x00\x00\x00\x00\b$Ep\x00\x00\x00\x00\b\xee\t\x00\x00\x00\x00\x00\n\x05x\xf0\x00\x00\x00\x00\n\xcf<\x80\x00\x00\x00\x00\v" + + "\xe7\xfd\xf0\x00\x00\x00\x00\f\xb1\xc1\x80\x00\x00\x00\x00\r\xc91p\x00\x00\x00\x00\x0e\x92\xf5\x00\x00\x00\x00\x00\x0f\xaad\xf0\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11\x8b\x98p\x00\x00\x00\x00\x12U\\\x00\x00" + + "\x00\x00\x00\x13n\x1dp\x00\x00\x00\x00\x147\xe1\x00\x00\x00\x00\x00\x15OP\xf0\x00\x00\x00\x00\x16\x19\x14\x80\x00\x00\x00\x00\x17\xa0\x93\xf0\x00\x00\x00\x00\x17\xfaH\x00\x00\x00\x00\x00\x19p\xa3\xf0\x00\x00\x00\x00\x19" + + "\xdb{\x80\x00\x00\x00\x00\x1a\xf4<\xf0\x00\x00\x00\x00\x1b\xbe\x00\x80\x00\x00\x00\x00\x1c\xd5pp\x00\x00\x00\x00\x1d\x9f4\x00\x00\x00\x00\x00\x1e\xb6\xa3\xf0\x00\x00\x00\x00\x1f\x80g\x80\x00\x00\x00\x00 \x97\xd7p\x00" + + "\x00\x00\x00!a\x9b\x00\x00\x00\x00\x00\"z\\p\x00\x00\x00\x00#D \x00\x00\x00\x00\x00$b'p\x00\x00\x00\x00%%S\x80\x00\x00\x00\x00&<\xc3p\x00\x00\x00\x00'\x06\x87\x00\x00\x00\x00\x00(" + + "\x1d\xf6\xf0\x00\x00\x00\x00(纀\x00\x00\x00\x00*\x00{\xf0\x00\x00\x00\x00*\xca?\x80\x00\x00\x00\x00+\xe1\xafp\x00\x00\x00\x00,\xabs\x00\x00\x00\x00\x00-\xc2\xe2\xf0\x00\x00\x00\x00.\x8c\xa6\x80\x00" + + "\x00\x00\x00/\xa0\x13\xe0\x00\x00\x00\x000k\f\xd0\x00\x00\x00\x001\u007f\xf5\xe0\x00\x00\x00\x002J\xee\xd0\x00\x00\x00\x003_\xd7\xe0\x00\x00\x00\x004*\xd0\xd0\x00\x00\x00\x005?\xb9\xe0\x00\x00\x00\x006" + + "\n\xb2\xd0\x00\x00\x00\x007(\xd6`\x00\x00\x00\x007\xf3\xcfP\x00\x00\x00\x009\b\xb8`\x00\x00\x00\x009ӱP\x00\x00\x00\x00:\xe8\x9a`\x00\x00\x00\x00;\xb3\x93P\x00\x00\x00\x00<\xc8|`\x00" + + "\x00\x00\x00=\x93uP\x00\x00\x00\x00>\xa8^`\x00\x00\x00\x00?sWP\x00\x00\x00\x00@\x91z\xe0\x00\x00\x00\x00A\\s\xd0\x00\x00\x00\x00Bq\\\xe0\x00\x00\x00\x00C\xe0\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00F1 \xe0\x00\x00\x00\x00F\xe0jP\x00\x00\x00\x00H\x11\x02\xe0\x00\x00\x00\x00H\xb7\x11\xd0\x00\x00\x00\x00I\xf0\xe4\xe0\x00\x00\x00\x00J\x8d\xb9P\x00" + + "\x00\x00\x00K\xda\x01`\x00\x00\x00\x00La\xbd\xd0\x00\x00\x00\x00L\x89X\xe0\x00\x00\x00\x00L\xa4\xfaP\x00\x00\x00\x00Su8\xe0\x00\x00\x00\x00S\xac\x89\xd0\x00\x00\x00\x00Sڼ`\x00\x00\x00\x00T" + + "$\x82P\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x01\x02\x01\x02\x01\x02\x00\x00\x1dU\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x01\x04LMT\x00EEST\x00EET\x00\x00\x00\x00\x01\nEET-2\nPK" + + "\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP.\x85\x1f\xf0\x95\x00\x00\x00\x95\x00\x00\x00\r\x00\x1c\x00Africa/DoualaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04" + + "\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xa1Q\xf3P\x01\x00\x00" + + "\x030\x00\x00\x00\x00\x0e\x10\x00\x04LMT\x00WAT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00" + + "\x00\b\xff\xff\xff\xff\xa1Q\xf3P\x01\x00\x00\x030\x00\x00\x00\x00\x0e\x10\x00\x04LMT\x00WAT\x00\nWAT-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP4#\xa3\xe0\x8d\x02\x00\x00" + + "\x8d\x02\x00\x00\v\x00\x1c\x00Africa/JubaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\x04\x00\x00\x00\x11\xb6\xa3\xda\xdc\x00\x9e\x17\xe0\x01z4P\x02}\xf9\xe0\x03[g\xd0\x04`~\xe0\x05=\xec\xd0\x06" + + "@`\xe0\a\x1f P\b B\xe0\t\x00S\xd0\n\x00$\xe0\n\xe1\x87P\v\xe0\x06\xe0\f\xc4\fP\r\xbf\xe8\xe0\x0e\xa5?\xd0\x0f\xa9\x05`\x10\x86sP\x11\x88\xe7`\x12g\xa6\xd0\x13h\xc9`\x14" + + "J+\xd0\x15H\xab`\x16+_P\x17(\x8d`\x18\f\x92\xd0\x19\bo`\x19\xed\xc6P\x1a\xf1\x8b\xe0\x1b\xd0KP\x1c\xd1m\xe0\x1d\xb1~\xd08\x80E \x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x00\x00\x1d\xa4\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x00\rLMT\x00CAST\x00CAT\x00EA" + + "T\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff\xb6\xa3\xda\xdc\x00\x00\x00\x00\x00\x9e" + + "\x17\xe0\x00\x00\x00\x00\x01z4P\x00\x00\x00\x00\x02}\xf9\xe0\x00\x00\x00\x00\x03[g\xd0\x00\x00\x00\x00\x04`~\xe0\x00\x00\x00\x00\x05=\xec\xd0\x00\x00\x00\x00\x06@`\xe0\x00\x00\x00\x00\a\x1f P\x00\x00" + + "\x00\x00\b B\xe0\x00\x00\x00\x00\t\x00S\xd0\x00\x00\x00\x00\n\x00$\xe0\x00\x00\x00\x00\n\xe1\x87P\x00\x00\x00\x00\v\xe0\x06\xe0\x00\x00\x00\x00\f\xc4\fP\x00\x00\x00\x00\r\xbf\xe8\xe0\x00\x00\x00\x00\x0e\xa5" + + "?\xd0\x00\x00\x00\x00\x0f\xa9\x05`\x00\x00\x00\x00\x10\x86sP\x00\x00\x00\x00\x11\x88\xe7`\x00\x00\x00\x00\x12g\xa6\xd0\x00\x00\x00\x00\x13h\xc9`\x00\x00\x00\x00\x14J+\xd0\x00\x00\x00\x00\x15H\xab`\x00\x00" + + "\x00\x00\x16+_P\x00\x00\x00\x00\x17(\x8d`\x00\x00\x00\x00\x18\f\x92\xd0\x00\x00\x00\x00\x19\bo`\x00\x00\x00\x00\x19\xed\xc6P\x00\x00\x00\x00\x1a\xf1\x8b\xe0\x00\x00\x00\x00\x1b\xd0KP\x00\x00\x00\x00\x1c\xd1" + + "m\xe0\x00\x00\x00\x00\x1d\xb1~\xd0\x00\x00\x00\x008\x80E \x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x00\x00\x1d\xa4\x00\x00\x00\x00" + + "*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x00\rLMT\x00CAST\x00CAT\x00EAT\x00\nEAT-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP4\x8b\xa4 \x95\x00" + + "\x00\x00\x95\x00\x00\x00\x0f\x00\x1c\x00Africa/GaboroneUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CA" + + "T\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00" + + "\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x94\xbdb?\xb1\x02\x00\x00\xb1\x02\x00\x00\f\x00\x1c\x00Africa/T" + + "unisUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06" + + "\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\x06\x00\x00\x00\x11\x80\x00\x00\x00\x91`PO\xc6:\x88\xe0\xc7X\x9e`\xc7\xdb\"\xe0\xca\xe2T\xe0˭i\xf0\xcc\xe7K\x10ͩ\x17\x90\xcd\xc2\x16\x00\xcd̰\x10" + + "\u03a25\x00ϒ4\x10Љ\xe3\xe0\xd1r\x16\x10\xd2N\x16`\r\xc7\xdf\xf0\x0e\x89\xacp\x0f\xaad\xf0\x10t\x1ap\"\xa3:\xf0#<(\xf0$,\x19\xf0%\x1c\n\xf0&<\xc3p'\x05'p" + + "Bt\r\xf0C<\x80\x00D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10\x01\x04\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x00\x00\t\x8c\x00\x00\x00\x00\x021\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x01\bLMT\x00PMT\x00CEST\x00CET\x00\x00" + + "\x00\x01\x01\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\x06\x00\x00\x00\x11\xff\xff\xff\xffYF\x13\xf4\xff\xff\xff" + + "\xff\x91`PO\xff\xff\xff\xff\xc6:\x88\xe0\xff\xff\xff\xff\xc7X\x9e`\xff\xff\xff\xff\xc7\xdb\"\xe0\xff\xff\xff\xff\xca\xe2T\xe0\xff\xff\xff\xff˭i\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17" + + "\x90\xff\xff\xff\xff\xcd\xc2\x16\x00\xff\xff\xff\xff\xcd̰\x10\xff\xff\xff\xff\u03a25\x00\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЉ\xe3\xe0\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N\x16`\x00\x00\x00" + + "\x00\r\xc7\xdf\xf0\x00\x00\x00\x00\x0e\x89\xacp\x00\x00\x00\x00\x0f\xaad\xf0\x00\x00\x00\x00\x10t\x1ap\x00\x00\x00\x00\"\xa3:\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n" + + "\xf0\x00\x00\x00\x00&<\xc3p\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00Bt\r\xf0\x00\x00\x00\x00C<\x80\x00\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00" + + "\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x01\x04\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\t\x8c\x00" + + "\x00\x00\x00\x021\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x01\bLMT\x00PMT\x00CEST\x00CET\x00\x00\x00\x01\x01\x00\x00\nCET-1" + + "\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPx=\xfb\xae\xfb\x00\x00\x00\xfb\x00\x00\x00\x0e\x00\x1c\x00Africa/KampalaUT\t\x00\x03nӧ^nӧ^ux" + + "\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x14\xb1\xee\xda" + + "\xfc\xb4\u009a\xd0ǑG\xd8\xed/\xe1\xd4\x01\x02\x03\x01\x00\x00\"\x84\x00\x00\x00\x00*0\x00\x04\x00\x00#(\x00\b\x00\x00&\xac\x00\x0e\x00\x00*0\x00\x04LMT\x00EAT\x00+0230" + + "\x00+0245\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xb1\xee\xda\xfc\xff" + + "\xff\xff\xff\xb4\u009a\xd0\xff\xff\xff\xffǑG\xd8\xff\xff\xff\xff\xed/\xe1\xd4\x01\x02\x03\x01\x00\x00\"\x84\x00\x00\x00\x00*0\x00\x04\x00\x00#(\x00\b\x00\x00&\xac\x00\x0e\x00\x00*0\x00\x04LMT" + + "\x00EAT\x00+0230\x00+0245\x00\nEAT-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb1\x980\xb2\xf6\x00\x00\x00\xf6\x00\x00\x00\x0e\x00\x1c\x00Africa" + + "/MbabaneUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\t\x80\x00\x00\x00\x82F\xcfḫ\x8c\x80͞opΎn\x80\xcf~Qp\x01\x03\x02\x03\x02\x03\x00\x00\x1a@\x00\x00\x00\x00\x15\x18" + + "\x00\x04\x00\x00*0\x01\x04\x00\x00\x1c \x00\x04LMT\x00SAST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00" + + "\x00\x00\x04\x00\x00\x00\t\xff\xff\xff\xffm{A@\xff\xff\xff\xff\x82F\xcfh\xff\xff\xff\xff̮\x8c\x80\xff\xff\xff\xff͞op\xff\xff\xff\xffΎn\x80\xff\xff\xff\xff\xcf~Qp\x01\x03\x02\x03\x02" + + "\x03\x00\x00\x1a@\x00\x00\x00\x00\x15\x18\x00\x04\x00\x00*0\x01\x04\x00\x00\x1c \x00\x04LMT\x00SAST\x00\nSAST-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPx=\xfb\xae" + + "\xfb\x00\x00\x00\xfb\x00\x00\x00\x12\x00\x1c\x00Africa/Addis_AbabaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZ" + + "if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x14\xb1\xee\xda\xfc\xb4\u009a\xd0ǑG\xd8\xed/\xe1\xd4\x01\x02" + + "\x03\x01\x00\x00\"\x84\x00\x00\x00\x00*0\x00\x04\x00\x00#(\x00\b\x00\x00&\xac\x00\x0e\x00\x00*0\x00\x04LMT\x00EAT\x00+0230\x00+0245\x00TZif2\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xb1\xee\xda\xfc\xff\xff\xff\xff\xb4\u009a\xd0\xff\xff\xff\xffǑG\xd8" + + "\xff\xff\xff\xff\xed/\xe1\xd4\x01\x02\x03\x01\x00\x00\"\x84\x00\x00\x00\x00*0\x00\x04\x00\x00#(\x00\b\x00\x00&\xac\x00\x0e\x00\x00*0\x00\x04LMT\x00EAT\x00+0230\x00+024" + + "5\x00\nEAT-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP4\x8b\xa4 \x95\x00\x00\x00\x95\x00\x00\x00\r\x00\x1c\x00Africa/MaputoUT\t\x00\x03nӧ" + + "^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02" + + "\x00\x00\x00\b\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5" + + "F\x9cP\xd6UH\xae\xc2\x00\x00\x00\xc2\x00\x00\x00\r\x00\x1c\x00Africa/BissauUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00" + + "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\x92朐\tga\x10\x01\x02\xff\xff\xf1d\x00\x00" + + "\xff\xff\xf1\xf0\x00\x04\x00\x00\x00\x00\x00\bLMT\x00-01\x00GMT\x00\x00\x01\x00\x00\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00" + + "\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x92朐\x00\x00\x00\x00\tga\x10\x01\x02\xff\xff\xf1d\x00\x00\xff\xff\xf1\xf0\x00\x04\x00\x00\x00\x00\x00\bLMT\x00-01\x00GM" + + "T\x00\x00\x01\x00\x00\x01\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP4\x8b\xa4 \x95\x00\x00\x00\x95\x00\x00\x00\x0f\x00\x1c\x00Africa/BlantyreU" + + "T\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nPK\x03\x04" + + "\n\x00\x00\x00\x00\x00\xf5F\x9cP.\x85\x1f\xf0\x95\x00\x00\x00\x95\x00\x00\x00\r\x00\x1c\x00Africa/NiameyUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01" + + "\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xa1Q\xf3P\x01\x00\x00\x030" + + "\x00\x00\x00\x00\x0e\x10\x00\x04LMT\x00WAT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b" + + "\xff\xff\xff\xff\xa1Q\xf3P\x01\x00\x00\x030\x00\x00\x00\x00\x0e\x10\x00\x04LMT\x00WAT\x00\nWAT-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xae\x18\x88\x94\x00\x00\x00\x94\x00" + + "\x00\x00\r\x00\x1c\x00Africa/BanjulUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00TZif" + + "2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00" + + "\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xae\x18\x88\x94\x00\x00\x00\x94\x00\x00\x00\x0e\x00\x1c\x00Africa/AbidjanU" + + "T\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\n" + + "\x00\x00\x00\x00\x00\xf5F\x9cPx=\xfb\xae\xfb\x00\x00\x00\xfb\x00\x00\x00\r\x00\x1c\x00Africa/AsmaraUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00" + + "\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x14\xb1\xee\xda\xfc\xb4\u009a\xd0Ǒ" + + "G\xd8\xed/\xe1\xd4\x01\x02\x03\x01\x00\x00\"\x84\x00\x00\x00\x00*0\x00\x04\x00\x00#(\x00\b\x00\x00&\xac\x00\x0e\x00\x00*0\x00\x04LMT\x00EAT\x00+0230\x00+0245\x00" + + "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xb1\xee\xda\xfc\xff\xff\xff\xff\xb4\u009a\xd0" + + "\xff\xff\xff\xffǑG\xd8\xff\xff\xff\xff\xed/\xe1\xd4\x01\x02\x03\x01\x00\x00\"\x84\x00\x00\x00\x00*0\x00\x04\x00\x00#(\x00\b\x00\x00&\xac\x00\x0e\x00\x00*0\x00\x04LMT\x00EAT\x00+0" + + "230\x00+0245\x00\nEAT-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xae\x18\x88\x94\x00\x00\x00\x94\x00\x00\x00\r\x00\x1c\x00Africa/Bamako" + + "UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04" + + "\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xae\x18\x88\x94\x00\x00\x00\x94\x00\x00\x00\x12\x00\x1c\x00Africa/OuagadougouUT\t\x00\x03nӧ^nӧ^ux\v" + + "\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\x92\xe6\x92H" + + "\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" + + "\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP4\x8b\xa4 \x95\x00" + + "\x00\x00\x95\x00\x00\x00\r\x00\x1c\x00Africa/LusakaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00" + + "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00" + + "\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP.\x85\x1f\xf0\x95\x00\x00\x00\x95\x00\x00\x00\r\x00\x1c\x00Africa/Lua" + + "ndaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xa1Q\xf3P\x01\x00\x00\x030\x00\x00\x00\x00\x0e\x10\x00\x04LMT\x00WAT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xa1Q\xf3P\x01\x00\x00\x030\x00\x00\x00\x00\x0e\x10\x00\x04LMT\x00WAT\x00\nWAT-1\n" + + "PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPx=\xfb\xae\xfb\x00\x00\x00\xfb\x00\x00\x00\r\x00\x1c\x00Africa/AsmeraUT\t\x00\x03nӧ^nӧ^ux\v\x00" + + "\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x14\xb1\xee\xda\xfc\xb4" + + "\u009a\xd0ǑG\xd8\xed/\xe1\xd4\x01\x02\x03\x01\x00\x00\"\x84\x00\x00\x00\x00*0\x00\x04\x00\x00#(\x00\b\x00\x00&\xac\x00\x0e\x00\x00*0\x00\x04LMT\x00EAT\x00+0230\x00+" + + "0245\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xb1\xee\xda\xfc\xff\xff\xff" + + "\xff\xb4\u009a\xd0\xff\xff\xff\xffǑG\xd8\xff\xff\xff\xff\xed/\xe1\xd4\x01\x02\x03\x01\x00\x00\"\x84\x00\x00\x00\x00*0\x00\x04\x00\x00#(\x00\b\x00\x00&\xac\x00\x0e\x00\x00*0\x00\x04LMT\x00E" + + "AT\x00+0230\x00+0245\x00\nEAT-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP4\x8b\xa4 \x95\x00\x00\x00\x95\x00\x00\x00\x11\x00\x1c\x00Africa/L" + + "ubumbashiUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\n" + + "CAT-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPҫd\x850\x03\x00\x000\x03\x00\x00\f\x00\x1c\x00Africa/AccraUT\t\x00\x03nӧ^nӧ" + + "^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00/\x00\x00\x00\x03\x00\x00\x00\x0e" + + "\x9e0f\xb4\xa34{\x80\xa3\xd3\xfcP\xa5\x15\xaf\x00\xa5\xb5/Ц\xf6‧\x96cP\xa8\xd8\x16\x00\xa9w\x96Ъ\xba\x9b\x00\xabZ\x1bЬ\x9b\u0380\xad;OP\xae}\x02\x00\xaf\x1c\x82\xd0" + + "\xb0^5\x80\xb0\xfd\xb6P\xb2@\xba\x80\xb2\xe0;P\xb4!\xee\x00\xb4\xc1nж\x03!\x80\xb6\xa2\xa2P\xb7\xe4U\x00\xb8\x83\xd5й\xc6\xda\x00\xbafZл\xa8\r\x80\xbcG\x8eP\xbd\x89A\x00" + + "\xbe(\xc1пjt\x80\xc0\t\xf5P\xc1L\xf9\x80\xc1\xeczP\xc3.-\x00\xc3ͭ\xd0\xc5\x0f`\x80Ů\xe1P\xc6\xf0\x94\x00ǐ\x14\xd0\xc8\xd3\x19\x00\xc9r\x99\xd0ʴL\x80\xcbS\xcdP" + + "̕\x80\x00\xcd5\x00\xd0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xff\xcc\x00" + + "\x00\x00\x00\x04\xb0\x01\x04\x00\x00\x00\x00\x00\nLMT\x00+0020\x00GMT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00/\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xff\x9e0f\xb4\xff\xff\xff\xff\xa34{\x80\xff\xff\xff\xff\xa3\xd3\xfcP\xff\xff\xff\xff\xa5\x15\xaf\x00\xff\xff\xff\xff\xa5\xb5/\xd0\xff\xff\xff\xff\xa6\xf6\xe2\x80\xff" + + "\xff\xff\xff\xa7\x96cP\xff\xff\xff\xff\xa8\xd8\x16\x00\xff\xff\xff\xff\xa9w\x96\xd0\xff\xff\xff\xff\xaa\xba\x9b\x00\xff\xff\xff\xff\xabZ\x1b\xd0\xff\xff\xff\xff\xac\x9b\u0380\xff\xff\xff\xff\xad;OP\xff\xff\xff\xff\xae" + + "}\x02\x00\xff\xff\xff\xff\xaf\x1c\x82\xd0\xff\xff\xff\xff\xb0^5\x80\xff\xff\xff\xff\xb0\xfd\xb6P\xff\xff\xff\xff\xb2@\xba\x80\xff\xff\xff\xff\xb2\xe0;P\xff\xff\xff\xff\xb4!\xee\x00\xff\xff\xff\xff\xb4\xc1n\xd0\xff" + + "\xff\xff\xff\xb6\x03!\x80\xff\xff\xff\xff\xb6\xa2\xa2P\xff\xff\xff\xff\xb7\xe4U\x00\xff\xff\xff\xff\xb8\x83\xd5\xd0\xff\xff\xff\xff\xb9\xc6\xda\x00\xff\xff\xff\xff\xbafZ\xd0\xff\xff\xff\xff\xbb\xa8\r\x80\xff\xff\xff\xff\xbc" + + "G\x8eP\xff\xff\xff\xff\xbd\x89A\x00\xff\xff\xff\xff\xbe(\xc1\xd0\xff\xff\xff\xff\xbfjt\x80\xff\xff\xff\xff\xc0\t\xf5P\xff\xff\xff\xff\xc1L\xf9\x80\xff\xff\xff\xff\xc1\xeczP\xff\xff\xff\xff\xc3.-\x00\xff" + + "\xff\xff\xff\xc3ͭ\xd0\xff\xff\xff\xff\xc5\x0f`\x80\xff\xff\xff\xffŮ\xe1P\xff\xff\xff\xff\xc6\xf0\x94\x00\xff\xff\xff\xffǐ\x14\xd0\xff\xff\xff\xff\xc8\xd3\x19\x00\xff\xff\xff\xff\xc9r\x99\xd0\xff\xff\xff\xff\xca" + + "\xb4L\x80\xff\xff\xff\xff\xcbS\xcdP\xff\xff\xff\xff̕\x80\x00\xff\xff\xff\xff\xcd5\x00\xd0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xff\xcc\x00\x00\x00\x00\x04\xb0\x01\x04\x00\x00\x00\x00\x00\nLMT\x00+0020\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00" + + "\x00\x00\xf5F\x9cP\u007f\xccV\xb2\xa7\x02\x00\x00\xa7\x02\x00\x00\x0f\x00\x1c\x00Africa/KhartoumUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00" + + "\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#\x00\x00\x00\x05\x00\x00\x00\x11\xb6\xa3\xda\x00\x00\x9e\x17\xe0\x01z4" + + "P\x02}\xf9\xe0\x03[g\xd0\x04`~\xe0\x05=\xec\xd0\x06@`\xe0\a\x1f P\b B\xe0\t\x00S\xd0\n\x00$\xe0\n\xe1\x87P\v\xe0\x06\xe0\f\xc4\fP\r\xbf\xe8\xe0\x0e\xa5?\xd0\x0f\xa9\x05" + + "`\x10\x86sP\x11\x88\xe7`\x12g\xa6\xd0\x13h\xc9`\x14J+\xd0\x15H\xab`\x16+_P\x17(\x8d`\x18\f\x92\xd0\x19\bo`\x19\xed\xc6P\x1a\xf1\x8b\xe0\x1b\xd0KP\x1c\xd1m\xe0\x1d\xb1~" + + "\xd08\x80E Y\xf8\xe4P\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x00\x00\x1e\x80\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c " + + "\x00\t\x00\x00*0\x00\r\x00\x00\x1c \x00\tLMT\x00CAST\x00CAT\x00EAT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00#\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\xb6\xa3\xda\x00\x00\x00\x00\x00\x00\x9e\x17\xe0\x00\x00\x00\x00\x01z4P\x00\x00\x00\x00\x02}\xf9\xe0\x00\x00\x00\x00\x03[g\xd0\x00\x00\x00\x00\x04" + + "`~\xe0\x00\x00\x00\x00\x05=\xec\xd0\x00\x00\x00\x00\x06@`\xe0\x00\x00\x00\x00\a\x1f P\x00\x00\x00\x00\b B\xe0\x00\x00\x00\x00\t\x00S\xd0\x00\x00\x00\x00\n\x00$\xe0\x00\x00\x00\x00\n\xe1\x87P\x00" + + "\x00\x00\x00\v\xe0\x06\xe0\x00\x00\x00\x00\f\xc4\fP\x00\x00\x00\x00\r\xbf\xe8\xe0\x00\x00\x00\x00\x0e\xa5?\xd0\x00\x00\x00\x00\x0f\xa9\x05`\x00\x00\x00\x00\x10\x86sP\x00\x00\x00\x00\x11\x88\xe7`\x00\x00\x00\x00\x12" + + "g\xa6\xd0\x00\x00\x00\x00\x13h\xc9`\x00\x00\x00\x00\x14J+\xd0\x00\x00\x00\x00\x15H\xab`\x00\x00\x00\x00\x16+_P\x00\x00\x00\x00\x17(\x8d`\x00\x00\x00\x00\x18\f\x92\xd0\x00\x00\x00\x00\x19\bo`\x00" + + "\x00\x00\x00\x19\xed\xc6P\x00\x00\x00\x00\x1a\xf1\x8b\xe0\x00\x00\x00\x00\x1b\xd0KP\x00\x00\x00\x00\x1c\xd1m\xe0\x00\x00\x00\x00\x1d\xb1~\xd0\x00\x00\x00\x008\x80E \x00\x00\x00\x00Y\xf8\xe4P\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x00\x00\x1e\x80\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x00\r\x00\x00\x1c \x00\t" + + "LMT\x00CAST\x00CAT\x00EAT\x00\nCAT-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x97\x17\x1ai\xf4\a\x00\x00\xf4\a\x00\x00\f\x00\x1c\x00Africa" + + "/CeutaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00" + + "\x00\a\x00\x00\x00\x00\x00\x00\x00~\x00\x00\x00\a\x00\x00\x00\x16\x80\x00\x00\x00\x9e\xd6up\x9f\xa1n`\xaa\x05\xefp\xaa\xe7n\x00\xadɧ\xf0\xae\xa72\x00\xaf\xa0Op\xb0\x87\x14\x00\xb1\x89z\x00\xb2p" + + "0\x80\xfb%r@\xfb\xc2\xefp\bk\x84\x80\b\xc6m\xf0\v\xe8\f\x00\faG\xf0\r\xc9?\x80\x0e\x8e\xf2p\x0f\xd3Q\x80\x10'\xa3p\x1a\xb7\xa6\x00\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\" + + "c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae" + + "\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5" + + "(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g\xe8" + + "\x97\x90h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/" + + "\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x04\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xfb\x04\x00\x00\x00\x00\x00\x00\x00\x04" + + "\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x01\x11\x00\x00\x0e\x10\x00\rLMT\x00WET\x00WEST\x00CET\x00CEST\x00\x00\x00\x00\x01\x00\x01\x01\x00" + + "\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00~\x00\x00\x00\a\x00\x00\x00\x16\xff\xff\xff\xff~6\xb5\x00\xff\xff" + + "\xff\xff\x9e\xd6up\xff\xff\xff\xff\x9f\xa1n`\xff\xff\xff\xff\xaa\x05\xefp\xff\xff\xff\xff\xaa\xe7n\x00\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa72\x00\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87" + + "\x14\x00\xff\xff\xff\xff\xb1\x89z\x00\xff\xff\xff\xff\xb2p0\x80\xff\xff\xff\xff\xfb%r@\xff\xff\xff\xff\xfb\xc2\xefp\x00\x00\x00\x00\bk\x84\x80\x00\x00\x00\x00\b\xc6m\xf0\x00\x00\x00\x00\v\xe8\f\x00\x00\x00" + + "\x00\x00\faG\xf0\x00\x00\x00\x00\r\xc9?\x80\x00\x00\x00\x00\x0e\x8e\xf2p\x00\x00\x00\x00\x0f\xd3Q\x80\x00\x00\x00\x00\x10'\xa3p\x00\x00\x00\x00\x1a\xb7\xa6\x00\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|" + + "\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00" + + "\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce" + + "\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00" + + "\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15" + + "F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00" + + "\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b" + + "\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00" + + "\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE" + + "\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00" + + "\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xfb\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10" + + "\x01\b\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x01\x11\x00\x00\x0e\x10\x00\rLMT\x00WET\x00WEST\x00CET\x00CEST\x00\x00\x00\x00\x01\x00\x01\x01\x00\x00\x00\x00\x00" + + "\x01\x01\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP4\x8b\xa4 \x95\x00\x00\x00\x95\x00\x00\x00\x10\x00\x1c\x00" + + "Africa/BujumburaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00TZif2\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LM" + + "T\x00CAT\x00\nCAT-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe1X(\b\xbb\x03\x00\x00\xbb\x03\x00\x00\x0f\x00\x1c\x00Africa/WindhoekUT" + + "\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x005\x00\x00\x00\x06\x00\x00\x00\x17\x80\x00\x00\x00\x82F\xcfḫ\x8c\x80͞op&\x06\xa7\xe0-\x8c\xc7`.i\x1c\x10/}\xe9\x000H\xfe\x101g\x05\x802(\xe0\x103F\xe7\x804\x11" + + "\xfc\x905&ɀ5\xf1ސ7\x06\xab\x807\xd1\xc0\x908捀9\xb1\xa2\x90:\xc6o\x80;\x91\x84\x90<\xaf\x8c\x00=qf\x90>\x8fn\x00?Z\x83\x10@oP\x00A:e\x10BO" + + "2\x00C\x1aG\x10D/\x14\x00D\xfa)\x10F\x0e\xf6\x00F\xda\v\x10G\xf8\x12\x80H\xc3'\x90I\xd7\xf4\x80J\xa3\t\x90K\xb7րL\x82\xeb\x90M\x97\xb8\x80Nb͐Ow\x9a\x80PB" + + "\xaf\x90Q`\xb7\x00R\"\x91\x90S@\x99\x00T\v\xae\x10U {\x00U\xeb\x90\x10W\x00]\x00W\xcbr\x10X\xe0?\x00Y\xabT\x10\x01\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x00\x00\x10\b\x00\x00\x00\x00\x15\x18\x00\x04\x00\x00\x1c \x00\n\x00\x00*0\x01\n\x00" + + "\x00\x0e\x10\x01\x0f\x00\x00\x1c \x00\x13LMT\x00+0130\x00SAST\x00WAT\x00CAT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00\x06\x00\x00\x00\x17\xff\xff\xff\xffm{Kx\xff\xff\xff\xff\x82F\xcfh\xff\xff\xff\xff̮\x8c\x80\xff\xff\xff\xff͞op\x00\x00\x00\x00&\x06\xa7\xe0\x00\x00" + + "\x00\x00-\x8c\xc7`\x00\x00\x00\x00.i\x1c\x10\x00\x00\x00\x00/}\xe9\x00\x00\x00\x00\x000H\xfe\x10\x00\x00\x00\x001g\x05\x80\x00\x00\x00\x002(\xe0\x10\x00\x00\x00\x003F\xe7\x80\x00\x00\x00\x004\x11" + + "\xfc\x90\x00\x00\x00\x005&ɀ\x00\x00\x00\x005\xf1ސ\x00\x00\x00\x007\x06\xab\x80\x00\x00\x00\x007\xd1\xc0\x90\x00\x00\x00\x008捀\x00\x00\x00\x009\xb1\xa2\x90\x00\x00\x00\x00:\xc6o\x80\x00\x00" + + "\x00\x00;\x91\x84\x90\x00\x00\x00\x00<\xaf\x8c\x00\x00\x00\x00\x00=qf\x90\x00\x00\x00\x00>\x8fn\x00\x00\x00\x00\x00?Z\x83\x10\x00\x00\x00\x00@oP\x00\x00\x00\x00\x00A:e\x10\x00\x00\x00\x00BO" + + "2\x00\x00\x00\x00\x00C\x1aG\x10\x00\x00\x00\x00D/\x14\x00\x00\x00\x00\x00D\xfa)\x10\x00\x00\x00\x00F\x0e\xf6\x00\x00\x00\x00\x00F\xda\v\x10\x00\x00\x00\x00G\xf8\x12\x80\x00\x00\x00\x00H\xc3'\x90\x00\x00" + + "\x00\x00I\xd7\xf4\x80\x00\x00\x00\x00J\xa3\t\x90\x00\x00\x00\x00K\xb7ր\x00\x00\x00\x00L\x82\xeb\x90\x00\x00\x00\x00M\x97\xb8\x80\x00\x00\x00\x00Nb͐\x00\x00\x00\x00Ow\x9a\x80\x00\x00\x00\x00PB" + + "\xaf\x90\x00\x00\x00\x00Q`\xb7\x00\x00\x00\x00\x00R\"\x91\x90\x00\x00\x00\x00S@\x99\x00\x00\x00\x00\x00T\v\xae\x10\x00\x00\x00\x00U {\x00\x00\x00\x00\x00U\xeb\x90\x10\x00\x00\x00\x00W\x00]\x00\x00\x00" + + "\x00\x00W\xcbr\x10\x00\x00\x00\x00X\xe0?\x00\x00\x00\x00\x00Y\xabT\x10\x01\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x00\x00\x10\b\x00\x00\x00\x00\x15\x18\x00\x04\x00\x00\x1c \x00\n\x00\x00*0\x01\n\x00\x00\x0e\x10\x01\x0f\x00\x00\x1c \x00\x13LMT\x00+0130" + + "\x00SAST\x00WAT\x00CAT\x00\nCAT-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x0f%\b\xcc\xf7\b\x00\x00\xf7\b\x00\x00\x0f\x00\x1c\x00Africa/El" + + "_AaiunUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00\x06\x00\x00\x00\x10\xbcH\xf0\xe0\vѰ\x90\v\xe8\f\x00\faG\xf0\r\xc9?\x80\x0e\x8e\xf2p\x0f\xd3Q\x80\x10'\xa3pHA\xe6\x80H\xbb\"pJ#" + + "\x1a\x00J\x8d\xd5pK\xdc\xc0\x80L]\xe5pM\x97\xb8\x80N4\x8c\xf0O\x9c\xa0\xa0P\b\xbb\xa0P1\x9a Pg\xa7\xa0Q|\x82\xa0Q\xd8ˠR\x05\x9e\xa0Rls\xa0S7z\xa0S\xae" + + "!\xa0S\xdcF TLU\xa0U\x17\\\xa0U|\xe0 U\xab\x04\xa0V,7\xa0V\xf7>\xa0WS\x87\xa0W\x81\xac X\x15T X\xd7 \xa0Y \xf4\xa0YXS\xa0Y\xf56 Z\xb7" + + "\x02\xa0Z\xf7\x9c [%\xc0\xa0[\xd5\x18 \\\xceC\xa0\\\xfch ^\x9b\xb0\xa0^\xd3\x0f\xa0`rX `\xa0|\xa0b?\xc5 bw$ d\x16l\xa0dD\x91 e\xed\x14 f\x1b" + + "8\xa0g\xba\x81 g\xf1\xe0 i\x91(\xa0i\xbfM kg\xd0 k\x95\xf4\xa0m5= ml\x9c o\v\xe4\xa0o:\t p\xd9Q\xa0q\x10\xb0\xa0r\xaf\xf9 r\xde\x1d\xa0t\x86" + + "\xa0\xa0t\xb4\xc5 vT\r\xa0v\x8bl\xa0x*\xb5 xX٠y\xf8\" z/\x81 {\xceɠ|\x06(\xa0}\xa5q }ӕ\xa0\u007fr\xde \u007f\xaa= \x01\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\xff\xff\xf3\xa0\x00\x00\xff\xff\xf1\xf0\x00\x04\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x01\f\x00\x00\x0e\x10\x00\bLMT\x00-0" + + "1\x00+01\x00+00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xba\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xbcH" + + "\xf0\xe0\x00\x00\x00\x00\vѰ\x90\x00\x00\x00\x00\v\xe8\f\x00\x00\x00\x00\x00\faG\xf0\x00\x00\x00\x00\r\xc9?\x80\x00\x00\x00\x00\x0e\x8e\xf2p\x00\x00\x00\x00\x0f\xd3Q\x80\x00\x00\x00\x00\x10'\xa3p\x00\x00" + + "\x00\x00HA\xe6\x80\x00\x00\x00\x00H\xbb\"p\x00\x00\x00\x00J#\x1a\x00\x00\x00\x00\x00J\x8d\xd5p\x00\x00\x00\x00K\xdc\xc0\x80\x00\x00\x00\x00L]\xe5p\x00\x00\x00\x00M\x97\xb8\x80\x00\x00\x00\x00N4" + + "\x8c\xf0\x00\x00\x00\x00O\x9c\xa0\xa0\x00\x00\x00\x00P\b\xbb\xa0\x00\x00\x00\x00P1\x9a \x00\x00\x00\x00Pg\xa7\xa0\x00\x00\x00\x00Q|\x82\xa0\x00\x00\x00\x00Q\xd8ˠ\x00\x00\x00\x00R\x05\x9e\xa0\x00\x00" + + "\x00\x00Rls\xa0\x00\x00\x00\x00S7z\xa0\x00\x00\x00\x00S\xae!\xa0\x00\x00\x00\x00S\xdcF \x00\x00\x00\x00TLU\xa0\x00\x00\x00\x00U\x17\\\xa0\x00\x00\x00\x00U|\xe0 \x00\x00\x00\x00U\xab" + + "\x04\xa0\x00\x00\x00\x00V,7\xa0\x00\x00\x00\x00V\xf7>\xa0\x00\x00\x00\x00WS\x87\xa0\x00\x00\x00\x00W\x81\xac \x00\x00\x00\x00X\x15T \x00\x00\x00\x00X\xd7 \xa0\x00\x00\x00\x00Y \xf4\xa0\x00\x00" + + "\x00\x00YXS\xa0\x00\x00\x00\x00Y\xf56 \x00\x00\x00\x00Z\xb7\x02\xa0\x00\x00\x00\x00Z\xf7\x9c \x00\x00\x00\x00[%\xc0\xa0\x00\x00\x00\x00[\xd5\x18 \x00\x00\x00\x00\\\xceC\xa0\x00\x00\x00\x00\\\xfc" + + "h \x00\x00\x00\x00^\x9b\xb0\xa0\x00\x00\x00\x00^\xd3\x0f\xa0\x00\x00\x00\x00`rX \x00\x00\x00\x00`\xa0|\xa0\x00\x00\x00\x00b?\xc5 \x00\x00\x00\x00bw$ \x00\x00\x00\x00d\x16l\xa0\x00\x00" + + "\x00\x00dD\x91 \x00\x00\x00\x00e\xed\x14 \x00\x00\x00\x00f\x1b8\xa0\x00\x00\x00\x00g\xba\x81 \x00\x00\x00\x00g\xf1\xe0 \x00\x00\x00\x00i\x91(\xa0\x00\x00\x00\x00i\xbfM \x00\x00\x00\x00kg" + + "\xd0 \x00\x00\x00\x00k\x95\xf4\xa0\x00\x00\x00\x00m5= \x00\x00\x00\x00ml\x9c \x00\x00\x00\x00o\v\xe4\xa0\x00\x00\x00\x00o:\t \x00\x00\x00\x00p\xd9Q\xa0\x00\x00\x00\x00q\x10\xb0\xa0\x00\x00" + + "\x00\x00r\xaf\xf9 \x00\x00\x00\x00r\xde\x1d\xa0\x00\x00\x00\x00t\x86\xa0\xa0\x00\x00\x00\x00t\xb4\xc5 \x00\x00\x00\x00vT\r\xa0\x00\x00\x00\x00v\x8bl\xa0\x00\x00\x00\x00x*\xb5 \x00\x00\x00\x00xX" + + "٠\x00\x00\x00\x00y\xf8\" \x00\x00\x00\x00z/\x81 \x00\x00\x00\x00{\xceɠ\x00\x00\x00\x00|\x06(\xa0\x00\x00\x00\x00}\xa5q \x00\x00\x00\x00}ӕ\xa0\x00\x00\x00\x00\u007fr\xde \x00\x00" + + "\x00\x00\u007f\xaa= \x00\x00\x00\x00\x81I\x85\xa0\x00\x00\x00\x00\x81w\xaa \x00\x00\x00\x00\x83 - \x00\x00\x00\x00\x83NQ\xa0\x00\x00\x00\x00\x84\xed\x9a \x00\x00\x00\x00\x85$\xf9 \x00\x00\x00\x00\x86\xc4" + + "A\xa0\x00\x00\x00\x00\x86\xf2f \x00\x00\x00\x00\x88\x91\xae\xa0\x00\x00\x00\x00\x88\xc9\r\xa0\x00\x00\x00\x00\x8ahV \x00\x00\x00\x00\x8a\x9f\xb5 \x00\x00\x00\x00\x8c>\xfd\xa0\x00\x00\x00\x00\x8cm\" \x00\x00" + + "\x00\x00\x8e\fj\xa0\x00\x00\x00\x00\x8eCɠ\x00\x00\x00\x00\x8f\xe3\x12 \x00\x00\x00\x00\x90\x116\xa0\x00\x00\x00\x00\x91\xb9\xb9\xa0\x00\x00\x00\x00\x91\xe7\xde \x00\x00\x00\x00\x93\x87&\xa0\x00\x00\x00\x00\x93\xbe" + + "\x85\xa0\x00\x00\x00\x00\x95]\xce \x00\x00\x00\x00\x95\x8b\xf2\xa0\x00\x00\x00\x00\x97+; \x00\x00\x00\x00\x97b\x9a \x00\x00\x00\x00\x99\x01\xe2\xa0\x00\x00\x00\x00\x999A\xa0\x00\x00\x00\x00\x9a؊ \x00\x00" + + "\x00\x00\x9b\x06\xae\xa0\x00\x00\x00\x00\x9c\xa5\xf7 \x00\x00\x00\x00\x9c\xddV \x00\x00\x00\x00\x9e|\x9e\xa0\x00\x00\x00\x00\x9e\xaa\xc3 \x00\x00\x00\x00\xa0SF \x00\x00\x00\x00\xa0\x81j\xa0\x00\x00\x00\x00\xa2 " + + "\xb3 \x00\x00\x00\x00\xa2X\x12 \x00\x00\x00\x00\xa3\xf7Z\xa0\x00\x00\x00\x00\xa4%\u007f \x00\x00\x00\x00\xa5\xc4Ǡ\x00\x00\x00\x00\xa5\xfc&\xa0\x00\x00\x00\x00\xa7\x9bo \x00\x00\x00\x00\xa7\xd2\xce \x00\x00" + + "\x00\x00\xa9r\x16\xa0\x00\x00\x00\x00\xa9\xa0; \x00\x00\x00\x00\xab?\x83\xa0\x00\x00\x00\x00\xabv\xe2\xa0\x00\x00\x00\x00\xad\x16+ \x00\x00\x00\x00\xadDO\xa0\x00\x00\x00\x00\xae\xecҠ\x00\x00\x00\x00\xaf\x1a" + + "\xf7 \x00\x00\x00\x00\xb0\xba?\xa0\x00\x00\x00\x00\xb0\xf1\x9e\xa0\x00\x00\x00\x00\xb2\x90\xe7 \x00\x00\x00\x00\xb2\xbf\v\xa0\x00\x00\x00\x00\xb4^T \x00\x00\x00\x00\xb4\x95\xb3 \x00\x00\x00\x00\xb64\xfb\xa0\x00\x00" + + "\x00\x00\xb6lZ\xa0\x00\x00\x00\x00\xb8\v\xa3 \x00\x00\x00\x00\xb89Ǡ\x00\x00\x00\x00\xb9\xd9\x10 \x00\x00\x00\x00\xba\x10o \x00\x00\x00\x00\xbb\xaf\xb7\xa0\x00\x00\x00\x00\xbb\xdd\xdc \x00\x00\x00\x00\xbd\x86" + + "_ \x00\x00\x00\x00\xbd\xb4\x83\xa0\x00\x00\x00\x00\xbfS\xcc \x00\x00\x00\x00\xbf\x8b+ \x00\x00\x00\x00\xc1*s\xa0\x00\x00\x00\x00\xc1X\x98 \x00\x00\x00\x00\xc2\xf7\xe0\xa0\x00\x00\x00\x00\xc3/?\xa0\x00\x00" + + "\x00\x00\xc4Έ \x00\x00\x00\x00\xc5\x05\xe7 \x00\x00\x00\x00ƥ/\xa0\x00\x00\x00\x00\xc6\xd3T \x00\x00\x00\x00\xc8r\x9c\xa0\x00\x00\x00\x00ȩ\xfb\xa0\x00\x00\x00\x00\xcaID \x00\x00\x00\x00\xcaw" + + "h\xa0\x00\x00\x00\x00\xcc\x1f\xeb\xa0\x00\x00\x00\x00\xccN\x10 \x00\x00\x00\x00\xcd\xedX\xa0\x00\x00\x00\x00\xce$\xb7\xa0\x00\x00\x00\x00\xcf\xc4\x00 \x00\x00\x00\x00\xcf\xf2$\xa0\x00\x00\x00\x00ёm \x00\x00" + + "\x00\x00\xd1\xc8\xcc \x00\x00\x00\x00\xd3h\x14\xa0\x00\x00\x00\x00Ӗ9 \x00\x00\x00\x00\xd5>\xbc \x00\x00\x00\x00\xd5l\xe0\xa0\x00\x00\x00\x00\xd7\f) \x00\x00\x00\x00\xd7C\x88 \x00\x00\x00\x00\xd8\xe2" + + "Р\x00\x00\x00\x00\xd9\x10\xf5 \x00\x00\x00\x00ڹx \x00\x00\x00\x00\xda眠\x00\x00\x00\x00܆\xe5 \x00\x00\x00\x00ܾD \x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\xff\xff\xf3\xa0\x00\x00\xff\xff\xf1\xf0\x00\x04" + + "\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x01\f\x00\x00\x0e\x10\x00\bLMT\x00-01\x00+01\x00+00\x00\n<+01>-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5" + + "F\x9cP\xc2ɵ,q\x02\x00\x00q\x02\x00\x00\x0e\x00\x1c\x00Africa/TripoliUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00" + + "\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x04\x00\x00\x00\x11\xa1\xf2\xc1$ݻ\xb1\x10\xde#\xad`\xe1x\xd2" + + "\x10\xe1\xe7e\xe0\xe5/?p\xe5\xa9\xcc\xe0\xebN\xc6\xf0\x16\x92B`\x17\b\xf7p\x17\xfa+\xe0\x18\xea*\xf0\x19\xdb_`\x1a̯\xf0\x1b\xbd\xe4`\x1c\xb4z\xf0\x1d\x9f\x17\xe0\x1e\x93\vp\x1f\x82\xee" + + "` pJp!a~\xe0\"R\xcfp#D\x03\xe0$4\x02\xf0%%7`&@\xb7\xf02N\xf1`3D6p45j\xe0P\x9d\x99\x00QTـRi\xb4\x80\x02\x01\x02\x01\x02\x01\x02" + + "\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x03\x02\x01\x03\x00\x00\f\\\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x00\rLMT\x00CEST\x00CE" + + "T\x00EET\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff\xa1\xf2\xc1$\xff\xff" + + "\xff\xffݻ\xb1\x10\xff\xff\xff\xff\xde#\xad`\xff\xff\xff\xff\xe1x\xd2\x10\xff\xff\xff\xff\xe1\xe7e\xe0\xff\xff\xff\xff\xe5/?p\xff\xff\xff\xff\xe5\xa9\xcc\xe0\xff\xff\xff\xff\xebN\xc6\xf0\x00\x00\x00\x00\x16\x92" + + "B`\x00\x00\x00\x00\x17\b\xf7p\x00\x00\x00\x00\x17\xfa+\xe0\x00\x00\x00\x00\x18\xea*\xf0\x00\x00\x00\x00\x19\xdb_`\x00\x00\x00\x00\x1a̯\xf0\x00\x00\x00\x00\x1b\xbd\xe4`\x00\x00\x00\x00\x1c\xb4z\xf0\x00\x00" + + "\x00\x00\x1d\x9f\x17\xe0\x00\x00\x00\x00\x1e\x93\vp\x00\x00\x00\x00\x1f\x82\xee`\x00\x00\x00\x00 pJp\x00\x00\x00\x00!a~\xe0\x00\x00\x00\x00\"R\xcfp\x00\x00\x00\x00#D\x03\xe0\x00\x00\x00\x00$4" + + "\x02\xf0\x00\x00\x00\x00%%7`\x00\x00\x00\x00&@\xb7\xf0\x00\x00\x00\x002N\xf1`\x00\x00\x00\x003D6p\x00\x00\x00\x0045j\xe0\x00\x00\x00\x00P\x9d\x99\x00\x00\x00\x00\x00QTـ\x00\x00" + + "\x00\x00Ri\xb4\x80\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x03\x02\x01\x03\x00\x00\f\\\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x1c " + + "\x00\rLMT\x00CEST\x00CET\x00EET\x00\nEET-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP|\xe5C0\xd0\x00\x00\x00\xd0\x00\x00\x00\x0f\x00\x1c\x00Afri" + + "ca/MonroviaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\f\x80\x00\x00\x00\xa0_l\x9c\x03\xcaZn\x01\x02\x03\xff\xff\xf5\xe4\x00\x00\xff\xff\xf5\xe4\x00\x04\xff\xff\xf5\x92\x00\x04\x00\x00\x00\x00" + + "\x00\bLMT\x00MMT\x00GMT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\f\xff\xff" + + "\xff\xffZz\xa6\x9c\xff\xff\xff\xff\xa0_l\x9c\x00\x00\x00\x00\x03\xcaZn\x01\x02\x03\xff\xff\xf5\xe4\x00\x00\xff\xff\xf5\xe4\x00\x04\xff\xff\xf5\x92\x00\x04\x00\x00\x00\x00\x00\bLMT\x00MMT\x00GMT" + + "\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPx=\xfb\xae\xfb\x00\x00\x00\xfb\x00\x00\x00\x14\x00\x1c\x00Africa/Dar_es_SalaamUT\t" + + "\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x04\x00\x00\x00\x05\x00\x00\x00\x14\xb1\xee\xda\xfc\xb4\u009a\xd0ǑG\xd8\xed/\xe1\xd4\x01\x02\x03\x01\x00\x00\"\x84\x00\x00\x00\x00*0\x00\x04\x00\x00#(\x00\b\x00\x00&\xac\x00\x0e\x00\x00*0\x00\x04L" + + "MT\x00EAT\x00+0230\x00+0245\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00" + + "\x00\x00\x14\xff\xff\xff\xff\xb1\xee\xda\xfc\xff\xff\xff\xff\xb4\u009a\xd0\xff\xff\xff\xffǑG\xd8\xff\xff\xff\xff\xed/\xe1\xd4\x01\x02\x03\x01\x00\x00\"\x84\x00\x00\x00\x00*0\x00\x04\x00\x00#(\x00\b\x00\x00&" + + "\xac\x00\x0e\x00\x00*0\x00\x04LMT\x00EAT\x00+0230\x00+0245\x00\nEAT-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb1\x980\xb2\xf6\x00\x00\x00\xf6\x00" + + "\x00\x00\x13\x00\x1c\x00Africa/JohannesburgUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\t\x80\x00\x00\x00\x82F\xcfḫ\x8c\x80͞opΎn\x80\xcf~Q" + + "p\x01\x03\x02\x03\x02\x03\x00\x00\x1a@\x00\x00\x00\x00\x15\x18\x00\x04\x00\x00*0\x01\x04\x00\x00\x1c \x00\x04LMT\x00SAST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\t\xff\xff\xff\xffm{A@\xff\xff\xff\xff\x82F\xcfh\xff\xff\xff\xff̮\x8c\x80\xff\xff\xff\xff͞op\xff\xff\xff\xff" + + "Ύn\x80\xff\xff\xff\xff\xcf~Qp\x01\x03\x02\x03\x02\x03\x00\x00\x1a@\x00\x00\x00\x00\x15\x18\x00\x04\x00\x00*0\x01\x04\x00\x00\x1c \x00\x04LMT\x00SAST\x00\nSAST-2\nP" + + "K\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP4\x8b\xa4 \x95\x00\x00\x00\x95\x00\x00\x00\r\x00\x1c\x00Africa/KigaliUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01" + + "\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\x82F\xc5\xf4\x01\x00" + + "\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00" + + "\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPx=\xfb\xae\xfb\x00\x00" + + "\x00\xfb\x00\x00\x00\x0f\x00\x1c\x00Africa/DjiboutiUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x14\xb1\xee\xda\xfc\xb4\u009a\xd0ǑG\xd8\xed/\xe1\xd4\x01\x02\x03\x01\x00\x00\"\x84" + + "\x00\x00\x00\x00*0\x00\x04\x00\x00#(\x00\b\x00\x00&\xac\x00\x0e\x00\x00*0\x00\x04LMT\x00EAT\x00+0230\x00+0245\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xb1\xee\xda\xfc\xff\xff\xff\xff\xb4\u009a\xd0\xff\xff\xff\xffǑG\xd8\xff\xff\xff\xff\xed/" + + "\xe1\xd4\x01\x02\x03\x01\x00\x00\"\x84\x00\x00\x00\x00*0\x00\x04\x00\x00#(\x00\b\x00\x00&\xac\x00\x0e\x00\x00*0\x00\x04LMT\x00EAT\x00+0230\x00+0245\x00\nEAT" + + "-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xae\x18\x88\x94\x00\x00\x00\x94\x00\x00\x00\x0f\x00\x1c\x00Africa/FreetownUT\t\x00\x03nӧ^nӧ" + + "^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b" + + "\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x1c\x00America/UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x03\x04\n\x00\x00\x00\x00\x00" + + "\xf5F\x9cP(*3\xf3\xf6\x00\x00\x00\xf6\x00\x00\x00\x13\x00\x1c\x00America/Puerto_RicoUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01" + + "\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\x80\x00\x00\x00\xcb\xf62\xc0\xd2" + + "#\xf4p\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\x00\x00\x01\x00\x00\x00\x01\x00T" + + "Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff" + + "\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\x00" + + "\x00\x01\x00\x00\x00\x01\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x03\xcdU\x02\xcc\x02\x00\x00\xcc\x02\x00\x00\x0e\x00\x1c\x00America/RecifeUT\t" + + "\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "(\x00\x00\x00\x03\x00\x00\x00\f\x96\xaag\xb8\xb8\x0fI\xe0\xb8\xfd@\xa0\xb9\xf140\xba\xdet \xda8\xae0\xda\xeb\xfa0\xdc\x19\xe1\xb0ܹY \xdd\xfb\x150ޛ\xde \xdfݚ0\xe0T3" + + " \xf4\x97\xff\xb0\xf5\x05^ \xf6\xc0d0\xf7\x0e\x1e\xa0\xf8Q,0\xf8\xc7\xc5 \xfa\nҰ\xfa\xa8\xf8\xa0\xfb\xec\x060\xfc\x8b}\xa0\x1dɎ0\x1exנ\x1f\xa05\xb0 3Ϡ!\x81i" + + "0\"\vȠ#X\x10\xb0#\xe2p %7\xf2\xb0%\xd4\xc7 7\xf6ư8\xb8\x85 9\xdf\xe309\xe9\x0f\xa0;\xc8\xff\xb03\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x10\x91Wpd\a\x00\x00d\a\x00\x00\x10\x00\x1c\x00America/R" + + "esoluteUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00w\x00\x00\x00\x06\x00\x00\x00\x15\xd5\xfb\x81\x80\xf7/L`\xf8(w\xe0\x13iV\x00\x14Y8\xf0\x15I8\x00\x169\x1a\xf0\x17)\x1a\x00\x18\"7p\x19\b\xfc\x00\x1a" + + "\x02\x19p\x1a\xf2\x18\x80\x1b\xe1\xfbp\x1c\xd1\xfa\x80\x1d\xc1\xddp\x1e\xb1܀\x1f\xa1\xbfp v\x0f\x00!\x81\xa1p\"U\xf1\x00#j\xbd\xf0$5\xd3\x00%J\x9f\xf0&\x15\xb5\x00'*\x81\xf0'" + + "\xfeр)\nc\xf0)\u07b3\x80*\xeaE\xf0+\xbe\x95\x80,\xd3bp-\x9ew\x80.\xb3Dp/~Y\x800\x93&p1gv\x002s\bp3GX\x004R\xeap5':\x006" + + "2\xccp7\a\x1c\x008\x1b\xe8\xf08\xe6\xfe\x009\xfb\xca\xf0:\xc6\xe0\x00;۬\xf0<\xaf\xfc\x80=\xbb\x8e\xf0>\x8fހ?\x9bp\xf0@o\xc0\x80A\x84\x8dpBO\xa2\x80CdopD" + + "/\x84\x80EDQpE\xf3\xb7\x00G-m\xf0Gә\x00I\rO\xf0I\xb3{\x00J\xed1\xf0K\x9c\x97\x80L\xd6NpM|y\x80N\xb60pO\\[\x80P\x96\x12pQ<=\x80R" + + "u\xf4pS\x1c\x1f\x80TU\xd6pT\xfc\x01\x80V5\xb8pV\xe5\x1e\x00X\x1e\xd4\xf0X\xc5\x00\x00Y\xfe\xb6\xf0Z\xa4\xe2\x00[ޘ\xf0\\\x84\xc4\x00]\xbez\xf0^d\xa6\x00_\x9e\\\xf0`" + + "M\u0080a\x87ypb-\xa4\x80cg[pd\r\x86\x80eG=pe\xedh\x80g'\x1fpg\xcdJ\x80i\a\x01pi\xad,\x80j\xe6\xe3pk\x96I\x00l\xcf\xff\xf0mv+\x00n" + + "\xaf\xe1\xf0oV\r\x00p\x8f\xc3\xf0q5\xef\x00ro\xa5\xf0s\x15\xd1\x00tO\x87\xf0t\xfe\xed\x80v8\xa4pv\xdeπx\x18\x86px\xbe\xb1\x80y\xf8hpz\x9e\x93\x80{\xd8Jp|" + + "~u\x80}\xb8,p~^W\x80\u007f\x98\x0ep\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x00\x00\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xab\xa0\x00\t\xff\xff\xb9\xb0\x01\r\xff\xff\xb9\xb0\x00\x11\xff\xff\xab\xa0\x00\t-00\x00CDDT\x00C" + + "ST\x00CDT\x00EST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00w\x00\x00\x00\x06\x00\x00\x00\x15\xff\xff\xff\xff\xd5" + + "\xfb\x81\x80\xff\xff\xff\xff\xf7/L`\xff\xff\xff\xff\xf8(w\xe0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00" + + "\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e" + + "\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00" + + "\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00," + + "\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00" + + "\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:" + + "\xc6\xe0\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00" + + "\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G-m\xf0\x00\x00\x00\x00Gә\x00\x00\x00\x00\x00I" + + "\rO\xf0\x00\x00\x00\x00I\xb3{\x00\x00\x00\x00\x00J\xed1\xf0\x00\x00\x00\x00K\x9c\x97\x80\x00\x00\x00\x00L\xd6Np\x00\x00\x00\x00M|y\x80\x00\x00\x00\x00N\xb60p\x00\x00\x00\x00O\\[\x80\x00" + + "\x00\x00\x00P\x96\x12p\x00\x00\x00\x00Q<=\x80\x00\x00\x00\x00Ru\xf4p\x00\x00\x00\x00S\x1c\x1f\x80\x00\x00\x00\x00TU\xd6p\x00\x00\x00\x00T\xfc\x01\x80\x00\x00\x00\x00V5\xb8p\x00\x00\x00\x00V" + + "\xe5\x1e\x00\x00\x00\x00\x00X\x1e\xd4\xf0\x00\x00\x00\x00X\xc5\x00\x00\x00\x00\x00\x00Y\xfe\xb6\xf0\x00\x00\x00\x00Z\xa4\xe2\x00\x00\x00\x00\x00[ޘ\xf0\x00\x00\x00\x00\\\x84\xc4\x00\x00\x00\x00\x00]\xbez\xf0\x00" + + "\x00\x00\x00^d\xa6\x00\x00\x00\x00\x00_\x9e\\\xf0\x00\x00\x00\x00`M\u0080\x00\x00\x00\x00a\x87yp\x00\x00\x00\x00b-\xa4\x80\x00\x00\x00\x00cg[p\x00\x00\x00\x00d\r\x86\x80\x00\x00\x00\x00e" + + "G=p\x00\x00\x00\x00e\xedh\x80\x00\x00\x00\x00g'\x1fp\x00\x00\x00\x00g\xcdJ\x80\x00\x00\x00\x00i\a\x01p\x00\x00\x00\x00i\xad,\x80\x00\x00\x00\x00j\xe6\xe3p\x00\x00\x00\x00k\x96I\x00\x00" + + "\x00\x00\x00l\xcf\xff\xf0\x00\x00\x00\x00mv+\x00\x00\x00\x00\x00n\xaf\xe1\xf0\x00\x00\x00\x00oV\r\x00\x00\x00\x00\x00p\x8f\xc3\xf0\x00\x00\x00\x00q5\xef\x00\x00\x00\x00\x00ro\xa5\xf0\x00\x00\x00\x00s" + + "\x15\xd1\x00\x00\x00\x00\x00tO\x87\xf0\x00\x00\x00\x00t\xfe\xed\x80\x00\x00\x00\x00v8\xa4p\x00\x00\x00\x00v\xdeπ\x00\x00\x00\x00x\x18\x86p\x00\x00\x00\x00x\xbe\xb1\x80\x00\x00\x00\x00y\xf8hp\x00" + + "\x00\x00\x00z\x9e\x93\x80\x00\x00\x00\x00{\xd8Jp\x00\x00\x00\x00|~u\x80\x00\x00\x00\x00}\xb8,p\x00\x00\x00\x00~^W\x80\x00\x00\x00\x00\u007f\x98\x0ep\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x00\x00\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff" + + "\xab\xa0\x00\t\xff\xff\xb9\xb0\x01\r\xff\xff\xb9\xb0\x00\x11\xff\xff\xab\xa0\x00\t-00\x00CDDT\x00CST\x00CDT\x00EST\x00\nCST6CDT,M3.2.0,M" + + "11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP*\x95<\xda\\\x02\x00\x00\\\x02\x00\x00\x0e\x00\x1c\x00America/ManausUT\t\x00\x03nӧ^" + + "nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x03\x00" + + "\x00\x00\f\x96\xaa\u007fD\xb8\x0fW\xf0\xb8\xfdN\xb0\xb9\xf1B@\xbaނ0\xda8\xbc@\xda\xec\b@\xdc\x19\xef\xc0ܹg0\xdd\xfb#@ޛ\xec0\xdfݨ@\xe0TA0\xf4\x98\r\xc0\xf5" + + "\x05l0\xf6\xc0r@\xf7\x0e,\xb0\xf8Q:@\xf8\xc7\xd30\xfa\n\xe0\xc0\xfa\xa9\x06\xb0\xfb\xec\x14@\xfc\x8b\x8b\xb0\x1dɜ@\x1ex\xe5\xb0\x1f\xa0C\xc0 3ݰ!\x81w@\"\vְ," + + "\xc0\xc3@-f\xd20\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\xff\xffǼ\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00" + + "\bLMT\x00-03\x00-04\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff" + + "\xff\x96\xaa\u007fD\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xbaނ0\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef" + + "\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xffޛ\xec0\xff\xff\xff\xff\xdfݨ@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff" + + "\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b" + + "\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3ݰ\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"\vְ\x00\x00\x00\x00,\xc0\xc3@\x00\x00\x00" + + "\x00-f\xd20\x00\x00\x00\x00\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\xff\xffǼ\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7" + + "\xc0\x00\bLMT\x00-03\x00-04\x00\n<-04>4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x96-\xbf\x9f\xd0\r\x00\x00\xd0\r\x00\x00\x10\x00\x1c\x00America" + + "/New_YorkUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\xec\x00\x00\x00\x05\x00\x00\x00\x14\x80\x00\x00\x00\x9e\xa6\x1ep\x9f\xba\xeb`\xa0\x86\x00p\xa1\x9a\xcd`\xa2e\xe2p\xa3\x83\xe9\xe0\xa4j\xaep\xa55\xa7`\xa6S\xca" + + "\xf0\xa7\x15\x89`\xa83\xac\xf0\xa8\xfe\xa5\xe0\xaa\x13\x8e\xf0\xaaއ\xe0\xab\xf3p\xf0\xac\xbei\xe0\xad\xd3R\xf0\xae\x9eK௳4\xf0\xb0~-\u0c5cQp\xb2gJ`\xb3|3p\xb4G," + + "`\xb5\\\x15p\xb6'\x0e`\xb7;\xf7p\xb8\x06\xf0`\xb9\x1b\xd9p\xb9\xe6\xd2`\xbb\x04\xf5\xf0\xbbƴ`\xbc\xe4\xd7\xf0\xbd\xaf\xd0\xe0\xbeĹ\U0003f3f2\xe0\xc0\xa4\x9b\xf0\xc1o\x94\xe0\u0084}" + + "\xf0\xc3Ov\xe0\xc4d_\xf0\xc5/X\xe0\xc6M|p\xc7\x0f:\xe0\xc8-^p\xc8\xf8W`\xca\r@p\xca\xd89`ˈ\xf0p\xd2#\xf4p\xd2`\xfb\xe0\xd3u\xe4\xf0\xd4@\xdd\xe0\xd5U\xc6" + + "\xf0\xd6 \xbf\xe0\xd75\xa8\xf0\xd8\x00\xa1\xe0\xd9\x15\x8a\xf0\xd9\xe0\x83\xe0\xda\xfe\xa7p\xdb\xc0e\xe0\xdcމpݩ\x82`\u07bekp߉d`\xe0\x9eMp\xe1iF`\xe2~/p\xe3I(" + + "`\xe4^\x11p\xe5W.\xe0\xe6G-\xf0\xe77\x10\xe0\xe8'\x0f\xf0\xe9\x16\xf2\xe0\xea\x06\xf1\xf0\xea\xf6\xd4\xe0\xeb\xe6\xd3\xf0\xecֶ\xe0\xedƵ\xf0\xee\xbf\xd3`\xef\xaf\xd2p\xf0\x9f\xb5`\xf1\x8f\xb4" + + "p\xf2\u007f\x97`\xf3o\x96p\xf4_y`\xf5Oxp\xf6?[`\xf7/Zp\xf8(w\xe0\xf9\x0f\x8f\xd0p?\x9bb\xe0@o\xb2pA\x84\u007f`BO\x94pCda`D/vpEDC`E\xf3\xa8" + + "\xf0G-_\xe0Gӊ\xf0I\rA\xe0I\xb3l\xf0J\xed#\xe0K\x9c\x89pL\xd6@`M|kpN\xb6\"`O\\MpP\x96\x04`Q\x8f\xd0" + + "p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\u007f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00" + + "\x00E\xf3\xa8\xf0\x00\x00\x00\x00G-_\xe0\x00\x00\x00\x00Gӊ\xf0\x00\x00\x00\x00I\rA\xe0\x00\x00\x00\x00I\xb3l\xf0\x00\x00\x00\x00J\xed#\xe0\x00\x00\x00\x00K\x9c\x89p\x00\x00\x00\x00L\xd6@" + + "`\x00\x00\x00\x00M|kp\x00\x00\x00\x00N\xb6\"`\x00\x00\x00\x00O\\Mp\x00\x00\x00\x00P\x96\x04`\x00\x00\x00\x00Q\x8fހ?\x9bp\xf0@" + + "o\xc0\x80A\x84\x8dpBO\xa2\x80CdopD/\x84\x80EDQpE\xf3\xb7\x00G-m\xf0Gә\x00I\rO\xf0I\xb3{\x00J\xed1\xf0K\x9c\x97\x80L\xd6NpM|y\x80N" + + "\xb60pO\\[\x80P\x96\x12pQ<=\x80Ru\xf4pS\x1c\x1f\x80TU\xd6pT\xfc\x01\x80V5\xb8pV\xe5\x1e\x00X\x1e\xd4\xf0X\xc5\x00\x00Y\xfe\xb6\xf0Z\xa4\xe2\x00[ޘ\xf0\\" + + "\x84\xc4\x00]\xbez\xf0^d\xa6\x00_\x9e\\\xf0`M\u0080a\x87ypb-\xa4\x80cg[pd\r\x86\x80eG=pe\xedh\x80g'\x1fpg\xcdJ\x80i\a\x01pi\xad,\x80j" + + "\xe6\xe3pk\x96I\x00l\xcf\xff\xf0mv+\x00n\xaf\xe1\xf0oV\r\x00p\x8f\xc3\xf0q5\xef\x00ro\xa5\xf0s\x15\xd1\x00tO\x87\xf0t\xfe\xed\x80v8\xa4pv\xdeπx\x18\x86px" + + "\xbe\xb1\x80y\xf8hpz\x9e\x93\x80{\xd8Jp|~u\x80}\xb8,p~^W\x80\u007f\x98\x0ep\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x00\x00\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xab\xa0\x00\t\xff\xff\xb9\xb0\x01\r\xff\xff\xb9\xb0\x00\x11" + + "\xff\xff\xab\xa0\x00\t-00\x00CDDT\x00CST\x00CDT\x00EST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00w\x00\x00\x00\x06\x00\x00\x00\x15\xff\xff\xff\xff\xe7\x8cn\x00\xff\xff\xff\xff\xf7/L`\xff\xff\xff\xff\xf8(w\xe0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00" + + "\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c" + + "\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00" + + "\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*" + + "\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00" + + "\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008" + + "\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00" + + "\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G" + + "-m\xf0\x00\x00\x00\x00Gә\x00\x00\x00\x00\x00I\rO\xf0\x00\x00\x00\x00I\xb3{\x00\x00\x00\x00\x00J\xed1\xf0\x00\x00\x00\x00K\x9c\x97\x80\x00\x00\x00\x00L\xd6Np\x00\x00\x00\x00M|y\x80\x00" + + "\x00\x00\x00N\xb60p\x00\x00\x00\x00O\\[\x80\x00\x00\x00\x00P\x96\x12p\x00\x00\x00\x00Q<=\x80\x00\x00\x00\x00Ru\xf4p\x00\x00\x00\x00S\x1c\x1f\x80\x00\x00\x00\x00TU\xd6p\x00\x00\x00\x00T" + + "\xfc\x01\x80\x00\x00\x00\x00V5\xb8p\x00\x00\x00\x00V\xe5\x1e\x00\x00\x00\x00\x00X\x1e\xd4\xf0\x00\x00\x00\x00X\xc5\x00\x00\x00\x00\x00\x00Y\xfe\xb6\xf0\x00\x00\x00\x00Z\xa4\xe2\x00\x00\x00\x00\x00[ޘ\xf0\x00" + + "\x00\x00\x00\\\x84\xc4\x00\x00\x00\x00\x00]\xbez\xf0\x00\x00\x00\x00^d\xa6\x00\x00\x00\x00\x00_\x9e\\\xf0\x00\x00\x00\x00`M\u0080\x00\x00\x00\x00a\x87yp\x00\x00\x00\x00b-\xa4\x80\x00\x00\x00\x00c" + + "g[p\x00\x00\x00\x00d\r\x86\x80\x00\x00\x00\x00eG=p\x00\x00\x00\x00e\xedh\x80\x00\x00\x00\x00g'\x1fp\x00\x00\x00\x00g\xcdJ\x80\x00\x00\x00\x00i\a\x01p\x00\x00\x00\x00i\xad,\x80\x00" + + "\x00\x00\x00j\xe6\xe3p\x00\x00\x00\x00k\x96I\x00\x00\x00\x00\x00l\xcf\xff\xf0\x00\x00\x00\x00mv+\x00\x00\x00\x00\x00n\xaf\xe1\xf0\x00\x00\x00\x00oV\r\x00\x00\x00\x00\x00p\x8f\xc3\xf0\x00\x00\x00\x00q" + + "5\xef\x00\x00\x00\x00\x00ro\xa5\xf0\x00\x00\x00\x00s\x15\xd1\x00\x00\x00\x00\x00tO\x87\xf0\x00\x00\x00\x00t\xfe\xed\x80\x00\x00\x00\x00v8\xa4p\x00\x00\x00\x00v\xdeπ\x00\x00\x00\x00x\x18\x86p\x00" + + "\x00\x00\x00x\xbe\xb1\x80\x00\x00\x00\x00y\xf8hp\x00\x00\x00\x00z\x9e\x93\x80\x00\x00\x00\x00{\xd8Jp\x00\x00\x00\x00|~u\x80\x00\x00\x00\x00}\xb8,p\x00\x00\x00\x00~^W\x80\x00\x00\x00\x00\u007f" + + "\x98\x0ep\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x00\x00\x00\x00\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xab\xa0\x00\t\xff\xff\xb9\xb0\x01\r\xff\xff\xb9\xb0\x00\x11\xff\xff\xab\xa0\x00\t-00\x00CDDT\x00CST\x00CDT\x00EST\x00\n" + + "CST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPiyᨖ\x01\x00\x00\x96\x01\x00\x00\f\x00\x1c\x00America" + + "/LimaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x04\x00\x00\x00\f\x80\x00\x00\x00\x8ct@\xd4\xc3\xcfJP\xc4E\xe3@\xc5/J\xd0\xc6\x1f-\xc0\xc7\x0f,\xd0\xc7\xff\x0f\xc0\x1e\x18\xc4P\x1e\x8f]@\x1f\xf9\xf7" + + "\xd0 p\x90\xc0%\x9e\xe3\xd0&\x15|\xc0-%\x03P-\x9b\x9c@\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x03\xff\xff\xb7\xc4\x00\x00\xff\xff\xb7\xac\x00\x00\xff\xff\xc7\xc0\x01\x04" + + "\xff\xff\xb9\xb0\x00\bLMT\x00-04\x00-05\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x04\x00\x00" + + "\x00\f\xff\xff\xff\xffi\x87#\xbc\xff\xff\xff\xff\x8ct@\xd4\xff\xff\xff\xff\xc3\xcfJP\xff\xff\xff\xff\xc4E\xe3@\xff\xff\xff\xff\xc5/J\xd0\xff\xff\xff\xff\xc6\x1f-\xc0\xff\xff\xff\xff\xc7\x0f,\xd0\xff\xff" + + "\xff\xff\xc7\xff\x0f\xc0\x00\x00\x00\x00\x1e\x18\xc4P\x00\x00\x00\x00\x1e\x8f]@\x00\x00\x00\x00\x1f\xf9\xf7\xd0\x00\x00\x00\x00 p\x90\xc0\x00\x00\x00\x00%\x9e\xe3\xd0\x00\x00\x00\x00&\x15|\xc0\x00\x00\x00\x00-%" + + "\x03P\x00\x00\x00\x00-\x9b\x9c@\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x03\xff\xff\xb7\xc4\x00\x00\xff\xff\xb7\xac\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\bL" + + "MT\x00-04\x00-05\x00\n<-05>5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xcf|3(\x94\x00\x00\x00\x94\x00\x00\x00\x15\x00\x1c\x00America/St_" + + "BarthelemyUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\x9373\xac\x01\xff\xff\xc6T\x00\x00\xff\xff\xc7\xc0\x00\x04LMT\x00AST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x9373\xac\x01\xff\xff\xc6T\x00\x00\xff\xff\xc7\xc0\x00\x04LMT\x00AST\x00" + + "\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPr\xcb;\xb3\xca\x01\x00\x00\xca\x01\x00\x00\x15\x00\x1c\x00America/Santo_DomingoUT\t" + + "\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x11\x00\x00\x00\x06\x00\x00\x00\x1b\x80\x00\x00\x00\xba\xdfB`\xfa\bK\xd0\xfa\xa7\xc3@\xff\xa7\xf1\xd0\x00C{\xc8\x01\x87\xd3\xd0\x01\xfa\u007fH\x03p\xf0P\x03\xdd\x04H\x05P\xd2P\x05\xbf\x89H\a0\xb4" + + "P\a\xa0\xbc\xc8\t\x10\x96P9\xfb\xbc\xe0:)\xe1`\x01\x03\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x03\x05\xff\xff\xbex\x00\x00\xff\xff\xbe`\x00\x04\xff\xff\xc7\xc0\x01\t\xff\xff\xb9\xb0\x00\r\xff\xff" + + "\xc0\xb8\x01\x11\xff\xff\xc7\xc0\x00\x17LMT\x00SDMT\x00EDT\x00EST\x00-0430\x00AST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x06\x00\x00\x00\x1b\xff\xff\xff\xffi\x87\x1d\b\xff\xff\xff\xff\xba\xdfB`\xff\xff\xff\xff\xfa\bK\xd0\xff\xff\xff\xff\xfa\xa7\xc3@\xff\xff\xff\xff\xff\xa7\xf1" + + "\xd0\x00\x00\x00\x00\x00C{\xc8\x00\x00\x00\x00\x01\x87\xd3\xd0\x00\x00\x00\x00\x01\xfa\u007fH\x00\x00\x00\x00\x03p\xf0P\x00\x00\x00\x00\x03\xdd\x04H\x00\x00\x00\x00\x05P\xd2P\x00\x00\x00\x00\x05\xbf\x89H\x00\x00\x00" + + "\x00\a0\xb4P\x00\x00\x00\x00\a\xa0\xbc\xc8\x00\x00\x00\x00\t\x10\x96P\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:)\xe1`\x01\x03\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x03\x05\xff\xff\xbex\x00\x00" + + "\xff\xff\xbe`\x00\x04\xff\xff\xc7\xc0\x01\t\xff\xff\xb9\xb0\x00\r\xff\xff\xc0\xb8\x01\x11\xff\xff\xc7\xc0\x00\x17LMT\x00SDMT\x00EDT\x00EST\x00-0430\x00AST\x00\nAS" + + "T4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x03:\x80]\xb6\b\x00\x00\xb6\b\x00\x00\x0f\x00\x1c\x00America/DetroitUT\t\x00\x03nӧ^nӧ" + + "^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x8d\x00\x00\x00\x06\x00\x00\x00\x18" + + "\x85\xbd\"[\x99<\x94\x00ˈ\xf0p\xd2#\xf4p\xd2`\xfb\xe0\xd75\xa8\xf0\xd8\x00\xa1\xe0\xfb3\x90\x8c\xfb\xe8;\xe0\xfc\xd8:\xf0\xfd\xc8\x1d\xe0\x06@\xdfp\a0\xc2`\a\x8d\x19p\t\x10\xa4`" + + "\n\x00\xa3p\n\xf0\x86`\v\xe0\x85p\f٢\xe0\r\xc0gp\x0e\xb9\x84\xe0\x0f\xa9\x83\xf0\x10\x99f\xe0\x11\x89e\xf0\x12yH\xe0\x13iG\xf0\x14Y*\xe0\x15I)\xf0\x169\f\xe0\x17)\v\xf0" + + "\x18\")`\x19\b\xed\xf0\x1a\x02\v`\x1a\xf2\np\x1b\xe1\xed`\x1c\xd1\xecp\x1d\xc1\xcf`\x1e\xb1\xcep\x1f\xa1\xb1` v\x00\xf0!\x81\x93`\"U\xe2\xf0#j\xaf\xe0$5\xc4\xf0%J\x91\xe0" + + "&\x15\xa6\xf0'*s\xe0'\xfe\xc3p)\nU\xe0)ޥp*\xea7\xe0+\xbe\x87p,\xd3T`-\x9eip.\xb36`/~Kp0\x93\x18`1gg\xf02r\xfa`3GI\xf0" + + "4R\xdc`5'+\xf062\xbe`7\a\r\xf08\x1b\xda\xe08\xe6\xef\xf09\xfb\xbc\xe0:\xc6\xd1\xf0;۞\xe0<\xaf\xeep=\xbb\x80\xe0>\x8f\xd0p?\x9bb\xe0@o\xb2pA\x84\u007f`" + + "BO\x94pCda`D/vpEDC`E\xf3\xa8\xf0G-_\xe0Gӊ\xf0I\rA\xe0I\xb3l\xf0J\xed#\xe0K\x9c\x89pL\xd6@`M|kpN\xb6\"`O\\Mp" + + "P\x96\x04`Q\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\u007f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00" + + "\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x00\x00\x00\x00G-_\xe0\x00\x00\x00\x00Gӊ\xf0\x00\x00\x00\x00I\rA\xe0\x00\x00\x00\x00I\xb3l\xf0\x00\x00\x00\x00J\xed#" + + "\xe0\x00\x00\x00\x00K\x9c\x89p\x00\x00\x00\x00L\xd6@`\x00\x00\x00\x00M|kp\x00\x00\x00\x00N\xb6\"`\x00\x00\x00\x00O\\Mp\x00\x00\x00\x00P\x96\x04`\x00\x00\x00\x00Q3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x14_\t\xbd\x01\t\x00\x00\x01\t\x00\x00\x0f\x00\x1c\x00America/YakutatUT\t\x00\x03nӧ^n\xd3" + + "\xa7^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x8f\x00\x00\x00\a\x00\x00\x00" + + "\x1e\x80\x00\x00\x00ˉ(\xb0\xd2#\xf4p\xd2a4 \xfe\xb8U0\xff\xa88 \x00\x9870\x01\x88\x1a \x02x\x190\x03q6\xa0\x04a5\xb0\x05Q\x18\xa0\x06A\x17\xb0\a0\xfa\xa0\a\x8dQ" + + "\xb0\t\x10ܠ\t\xad\xcd0\n\xf0\xbe\xa0\v\u0f70\f\xd9\xdb \r\xc0\x9f\xb0\x0e\xb9\xbd \x0f\xa9\xbc0\x10\x99\x9f \x11\x89\x9e0\x12y\x81 \x13i\x800\x14Yc \x15Ib0\x169E" + + " \x17)D0\x18\"a\xa0\x19\t&0\x1a\x02C\xa0\x1a+\x14\x10\x1a\xf2B\xb0\x1b\xe2%\xa0\x1c\xd2$\xb0\x1d\xc2\a\xa0\x1e\xb2\x06\xb0\x1f\xa1\xe9\xa0 v90!\x81ˠ\"V\x1b0#j\xe8" + + " $5\xfd0%J\xca &\x15\xdf0'*\xac '\xfe\xfb\xb0)\n\x8e )\xdeݰ*\xeap +\xbe\xbf\xb0,ӌ\xa0-\x9e\xa1\xb0.\xb3n\xa0/~\x83\xb00\x93P\xa01g\xa0" + + "02s2\xa03G\x8204S\x14\xa05'd062\xf6\xa07\aF08\x1c\x13 8\xe7(09\xfb\xf5 :\xc7\n0;\xdb\xd7 <\xb0&\xb0=\xbb\xb9 >\x90\b\xb0?\x9b\x9b" + + " @o\xea\xb0A\x84\xb7\xa0BO̰Cd\x99\xa0D/\xae\xb0ED{\xa0E\xf3\xe10G-\x98 G\xd3\xc30I\rz I\xb3\xa50J\xed\\ K\x9c\xc1\xb0L\xd6x\xa0M|\xa3" + + "\xb0N\xb6Z\xa0O\\\x85\xb0P\x96<\xa0Q\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO̰\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED" + + "{\xa0\x00\x00\x00\x00E\xf3\xe10\x00\x00\x00\x00G-\x98 \x00\x00\x00\x00G\xd3\xc30\x00\x00\x00\x00I\rz \x00\x00\x00\x00I\xb3\xa50\x00\x00\x00\x00J\xed\\ \x00\x00\x00\x00K\x9c\xc1\xb0\x00\x00" + + "\x00\x00L\xd6x\xa0\x00\x00\x00\x00M|\xa3\xb0\x00\x00\x00\x00N\xb6Z\xa0\x00\x00\x00\x00O\\\x85\xb0\x00\x00\x00\x00P\x96<\xa0\x00\x00\x00\x00Q3\nPK" + + "\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x89S\xb8\xd5n\a\x00\x00n\a\x00\x00\x14\x00\x1c\x00America/Punta_ArenasUT\t\x00\x03nӧ^nӧ" + + "^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00u\x00\x00\x00\b\x00\x00\x00\x14" + + "\x80\x00\x00\x00\x8f0GF\x9b\\\xe5P\x9f|\xe2ơ\x00q\xc0\xb0^wƱw=@\xb2A\x00гXp\xc0\xb4\"4P\xb59\xa4@\xb6\x03gз\x1a\xd7\xc0\xb7\xe4\x9bP\xb8\xfd\\\xc0" + + "\xb9\xc7 P\xcc\x1cn@\xccl\xe7\xd0\xd53U\xc0\xd5v\x92@\xfd\xd1<@\xfe\x92\xfa\xb0\xff\xcc\xcd\xc0\x00rܰ\x01uP\xc0\x02@I\xb0\x03U2\xc0\x04 +\xb0\x05>O@\x06\x00\r\xb0" + + "\a\v\xbc@\a\xdf\xef\xb0\b\xfe\x13@\t\xbfѰ\n\xdd\xf5@\v\xa8\xee0\f\xbd\xd7@\r\x88\xd00\x0e\x9d\xb9@\x0fh\xb20\x10\x86\xd5\xc0\x11H\x940\x12f\xb7\xc0\x13(v0\x14F\x99\xc0" + + "\x15\x11\x92\xb0\x16&{\xc0\x16\xf1t\xb0\x18\x06]\xc0\x18\xd1V\xb0\x19\xe6?\xc0\x1a\xb18\xb0\x1b\xcf\\@\x1c\x91\x1a\xb0\x1d\xaf>@\x1ep\xfc\xb0\x1f\x8f @ \u007f\x030!o\x02@\"9\xfb0" + + "#N\xe4@$\x19\xdd0%8\x00\xc0%\xf9\xbf0&\xf2\xf8\xc0'١0(\xf7\xc4\xc0)½\xb0*צ\xc0+\xa2\x9f\xb0,\xb7\x88\xc0-\x82\x81\xb0.\x97j\xc0/bc\xb00\x80\x87@" + + "1BE\xb02`i@3=\xd704@K@5\vD06\r\xb8@7\x06հ8\x00\x0f@8\xcb\b09\xe9+\xc0:\xaa\xea0;\xc9\r\xc0<\x8a\xcc0=\xa8\xef\xc0>j\xae0" + + "?\x88\xd1\xc0@SʰAh\xb3\xc0B3\xac\xb0CH\x95\xc0D\x13\x8e\xb0E1\xb2@E\xf3p\xb0G\x11\x94@G\xef\x020H\xf1v@I\xbco0J\xd1X@K\xb8\x00\xb0L\xb1:@" + + "M\xc6\a0NP\x82\xc0O\x9c\xae\xb0PB\xd9\xc0Q|\x90\xb0R+\xf6@S\\r\xb0T\v\xd8@W7\xe60W\xaf\xec\xc0XC\x86\xb0\u007f\xff\xff\xff\x01\x02\x01\x03\x01\x04\x02\x04\x02\x04\x02\x04" + + "\x02\x04\x02\x03\x02\x03\x02\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\a\xff\xff\xbd\x84\x00\x00\xff\xff\xbd\xba\x00\x04\xff\xff\xb9" + + "\xb0\x00\b\xff\xff\xc7\xc0\x00\f\xff\xff\xc7\xc0\x01\f\xff\xff\xd5\xd0\x01\x10\xff\xff\xc7\xc0\x00\f\xff\xff\xd5\xd0\x00\x10LMT\x00SMT\x00-05\x00-04\x00-03\x00\x00\x00\x00\x00\x00\x01\x01" + + "\x00\x00\x00\x00\x00\x00\x01\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00u\x00\x00\x00\b\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x1d" + + "\xfc\xff\xff\xff\xff\x8f0GF\xff\xff\xff\xff\x9b\\\xe5P\xff\xff\xff\xff\x9f|\xe2\xc6\xff\xff\xff\xff\xa1\x00q\xc0\xff\xff\xff\xff\xb0^w\xc6\xff\xff\xff\xff\xb1w=@\xff\xff\xff\xff\xb2A\x00\xd0\xff\xff\xff" + + "\xff\xb3Xp\xc0\xff\xff\xff\xff\xb4\"4P\xff\xff\xff\xff\xb59\xa4@\xff\xff\xff\xff\xb6\x03g\xd0\xff\xff\xff\xff\xb7\x1a\xd7\xc0\xff\xff\xff\xff\xb7\xe4\x9bP\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xc7 " + + "P\xff\xff\xff\xff\xcc\x1cn@\xff\xff\xff\xff\xccl\xe7\xd0\xff\xff\xff\xff\xd53U\xc0\xff\xff\xff\xff\xd5v\x92@\xff\xff\xff\xff\xfd\xd1<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00\x00" + + "\x00\x00rܰ\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00\x02@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +\xb0\x00\x00\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\r\xb0\x00\x00\x00\x00\a\v\xbc" + + "@\x00\x00\x00\x00\a\xdf\xef\xb0\x00\x00\x00\x00\b\xfe\x13@\x00\x00\x00\x00\t\xbfѰ\x00\x00\x00\x00\n\xdd\xf5@\x00\x00\x00\x00\v\xa8\xee0\x00\x00\x00\x00\f\xbd\xd7@\x00\x00\x00\x00\r\x88\xd00\x00\x00\x00" + + "\x00\x0e\x9d\xb9@\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00\x10\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11\x92" + + "\xb0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00" + + "\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \u007f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"9\xfb0\x00\x00\x00\x00#N\xe4" + + "@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'١0\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)½\xb0\x00\x00\x00" + + "\x00*צ\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE" + + "\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\vD0\x00\x00\x00\x006\r\xb8@\x00\x00\x00\x007\x06հ\x00\x00\x00\x008\x00\x0f@\x00\x00\x00" + + "\x008\xcb\b0\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1" + + "\xc0\x00\x00\x00\x00@Sʰ\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00" + + "\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\a" + + "0\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T\v\xd8@\x00\x00\x00" + + "\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00XC\x86\xb0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x01\x03\x01\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x03\x02\x03\x02\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\a\xff\xff\xbd\x84\x00\x00\xff\xff\xbd\xba\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\f\xff\xff\xc7\xc0\x01\f\xff\xff\xd5\xd0" + + "\x01\x10\xff\xff\xc7\xc0\x00\f\xff\xff\xd5\xd0\x00\x10LMT\x00SMT\x00-05\x00-04\x00-03\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x01\x01\x00\n<-03>3\nPK" + + "\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xcfV%\x9e|\a\x00\x00|\a\x00\x00\x14\x00\x1c\x00America/ScoresbysundUT\t\x00\x03nӧ^nӧ" + + "^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00v\x00\x00\x00\a\x00\x00\x00\x10" + + "\x9b\x80L\x18\x13Mn@\x144$\xc0\x15#\xf9\xa0\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10" + + " lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10" + + "J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10" + + "X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90" + + "g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10" + + "u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\u007f\xff\xff\xff\x01\x02\x03\x06\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x04\xff\xff\xebh\x00\x00\xff\xff\xe3\xe0" + + "\x00\x04\xff\xff\xf1\xf0\x01\b\xff\xff\xe3\xe0\x00\x04\xff\xff\xf1\xf0\x00\b\x00\x00\x00\x00\x01\f\x00\x00\x00\x00\x01\fLMT\x00-02\x00-01\x00+00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x01" + + "\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00v\x00\x00\x00\a\x00\x00\x00\x10\xff\xff\xff\xff\x9b\x80L\x18\x00\x00\x00\x00\x13M" + + "n@\x00\x00\x00\x00\x144$\xc0\x00\x00\x00\x00\x15#\xf9\xa0\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00" + + "\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\" + + "c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00" + + "\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae" + + "\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00" + + "\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5" + + "(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00" + + "\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g\xe8" + + "\x97\x90\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00" + + "\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/" + + "\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00" + + "\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x06\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x04\xff\xff\xebh\x00\x00\xff\xff\xe3\xe0\x00\x04\xff\xff\xf1\xf0\x01\b\xff\xff\xe3\xe0\x00\x04\xff\xff\xf1\xf0\x00\b\x00\x00" + + "\x00\x00\x01\f\x00\x00\x00\x00\x01\fLMT\x00-02\x00-01\x00+00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x01\x01\x00\n<-01>1<+00>,M3.5.0/" + + "0,M10.5.0/1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP|p&\x14\xe1\t\x00\x00\xe1\t\x00\x00\x10\x00\x1c\x00America/SantiagoUT" + + "\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\b\x00\x00\x00\x00\x00\x00" + + "\x00\xa0\x00\x00\x00\b\x00\x00\x00\x14\x80\x00\x00\x00\x8f0GF\x9b\\\xe5P\x9f|\xe2ơ\x00q\xc0\xb0^wƱw=@\xb2A\x00гXp\xc0\xb4\"4P\xb59\xa4@\xb6\x03gз\x1a" + + "\xd7\xc0\xb7\xe4\x9bP\xb8\xfd\\\xc0\xb9\xc7 P\xcc\x1cn@\xccl\xe7\xd0\xd3\u070f\xc0\xd4\x1bɰ\xd53U\xc0\xd5v\x92@\xfd\xd1<@\xfe\x92\xfa\xb0\xff\xcc\xcd\xc0\x00rܰ\x01uP\xc0\x02@" + + "I\xb0\x03U2\xc0\x04 +\xb0\x05>O@\x06\x00\r\xb0\a\v\xbc@\a\xdf\xef\xb0\b\xfe\x13@\t\xbfѰ\n\xdd\xf5@\v\xa8\xee0\f\xbd\xd7@\r\x88\xd00\x0e\x9d\xb9@\x0fh\xb20\x10\x86" + + "\xd5\xc0\x11H\x940\x12f\xb7\xc0\x13(v0\x14F\x99\xc0\x15\x11\x92\xb0\x16&{\xc0\x16\xf1t\xb0\x18\x06]\xc0\x18\xd1V\xb0\x19\xe6?\xc0\x1a\xb18\xb0\x1b\xcf\\@\x1c\x91\x1a\xb0\x1d\xaf>@\x1ep" + + "\xfc\xb0\x1f\x8f @ \u007f\x030!o\x02@\"9\xfb0#N\xe4@$\x19\xdd0%8\x00\xc0%\xf9\xbf0&\xf2\xf8\xc0'١0(\xf7\xc4\xc0)½\xb0*צ\xc0+\xa2\x9f\xb0,\xb7" + + "\x88\xc0-\x82\x81\xb0.\x97j\xc0/bc\xb00\x80\x87@1BE\xb02`i@3=\xd704@K@5\vD06\r\xb8@7\x06հ8\x00\x0f@8\xcb\b09\xe9+\xc0:\xaa" + + "\xea0;\xc9\r\xc0<\x8a\xcc0=\xa8\xef\xc0>j\xae0?\x88\xd1\xc0@SʰAh\xb3\xc0B3\xac\xb0CH\x95\xc0D\x13\x8e\xb0E1\xb2@E\xf3p\xb0G\x11\x94@G\xef\x020H\xf1" + + "v@I\xbco0J\xd1X@K\xb8\x00\xb0L\xb1:@M\xc6\a0NP\x82\xc0O\x9c\xae\xb0PB\xd9\xc0Q|\x90\xb0R+\xf6@S\\r\xb0T\v\xd8@W7\xe60W\xaf\xec\xc0Y\x17" + + "\xc80Y\x8f\xce\xc0Z\xf7\xaa0[o\xb0\xc0\\\xa9g\xb0]t|\xc0^\x89I\xb0_T^\xc0`i+\xb0a4@\xc0bI\r\xb0c\x14\"\xc0d(\xef\xb0d\xf4\x04\xc0f\x12\f0f\xdd" + + "!@g\xf1\xee0h\xbd\x03@i\xd1\xd00j\x9c\xe5@k\xb1\xb20l|\xc7@m\x91\x940n\\\xa9@oz\xb0\xb0p<\x8b@qZ\x92\xb0r%\xa7\xc0s:t\xb0t\x05\x89\xc0u\x1a" + + "V\xb0u\xe5k\xc0v\xfa8\xb0w\xc5M\xc0x\xda\x1a\xb0y\xa5/\xc0z\xc370{\x85\x11\xc0|\xa3\x190}n.@~\x82\xfb0\u007fN\x10@\u007f\xff\xff\xff\x01\x02\x01\x03\x01\x04\x02\x04\x02\x04" + + "\x02\x04\x02\x04\x02\x03\x02\x03\x05\x03\x02\x03\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\x06\xff\xff\xbd\xba\x00\x00\xff\xff\xbd\xba\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\f\xff\xff\xc7\xc0\x01\f" + + "\xff\xff\xd5\xd0\x01\x10\xff\xff\xd5\xd0\x01\x10\xff\xff\xc7\xc0\x00\fLMT\x00SMT\x00-05\x00-04\x00-03\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x01\x01TZif3\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\xa0\x00\x00\x00\b\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x1d\xc6\xff\xff\xff\xff\x8f0GF\xff\xff\xff\xff\x9b\\" + + "\xe5P\xff\xff\xff\xff\x9f|\xe2\xc6\xff\xff\xff\xff\xa1\x00q\xc0\xff\xff\xff\xff\xb0^w\xc6\xff\xff\xff\xff\xb1w=@\xff\xff\xff\xff\xb2A\x00\xd0\xff\xff\xff\xff\xb3Xp\xc0\xff\xff\xff\xff\xb4\"4P\xff\xff" + + "\xff\xff\xb59\xa4@\xff\xff\xff\xff\xb6\x03g\xd0\xff\xff\xff\xff\xb7\x1a\xd7\xc0\xff\xff\xff\xff\xb7\xe4\x9bP\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xc7 P\xff\xff\xff\xff\xcc\x1cn@\xff\xff\xff\xff\xccl" + + "\xe7\xd0\xff\xff\xff\xff\xd3\u070f\xc0\xff\xff\xff\xff\xd4\x1bɰ\xff\xff\xff\xff\xd53U\xc0\xff\xff\xff\xff\xd5v\x92@\xff\xff\xff\xff\xfd\xd1<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00" + + "\x00\x00\x00rܰ\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00\x02@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +\xb0\x00\x00\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\r\xb0\x00\x00\x00\x00\a\v" + + "\xbc@\x00\x00\x00\x00\a\xdf\xef\xb0\x00\x00\x00\x00\b\xfe\x13@\x00\x00\x00\x00\t\xbfѰ\x00\x00\x00\x00\n\xdd\xf5@\x00\x00\x00\x00\v\xa8\xee0\x00\x00\x00\x00\f\xbd\xd7@\x00\x00\x00\x00\r\x88\xd00\x00\x00" + + "\x00\x00\x0e\x9d\xb9@\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00\x10\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11" + + "\x92\xb0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00" + + "\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \u007f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"9\xfb0\x00\x00\x00\x00#N" + + "\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'١0\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)½\xb0\x00\x00" + + "\x00\x00*צ\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001B" + + "E\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\vD0\x00\x00\x00\x006\r\xb8@\x00\x00\x00\x007\x06հ\x00\x00\x00\x008\x00\x0f@\x00\x00" + + "\x00\x008\xcb\b0\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88" + + "\xd1\xc0\x00\x00\x00\x00@Sʰ\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00" + + "\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6" + + "\a0\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T\v\xd8@\x00\x00" + + "\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00Y\x17\xc80\x00\x00\x00\x00Y\x8f\xce\xc0\x00\x00\x00\x00Z\xf7\xaa0\x00\x00\x00\x00[o\xb0\xc0\x00\x00\x00\x00\\\xa9g\xb0\x00\x00\x00\x00]t" + + "|\xc0\x00\x00\x00\x00^\x89I\xb0\x00\x00\x00\x00_T^\xc0\x00\x00\x00\x00`i+\xb0\x00\x00\x00\x00a4@\xc0\x00\x00\x00\x00bI\r\xb0\x00\x00\x00\x00c\x14\"\xc0\x00\x00\x00\x00d(\xef\xb0\x00\x00" + + "\x00\x00d\xf4\x04\xc0\x00\x00\x00\x00f\x12\f0\x00\x00\x00\x00f\xdd!@\x00\x00\x00\x00g\xf1\xee0\x00\x00\x00\x00h\xbd\x03@\x00\x00\x00\x00i\xd1\xd00\x00\x00\x00\x00j\x9c\xe5@\x00\x00\x00\x00k\xb1" + + "\xb20\x00\x00\x00\x00l|\xc7@\x00\x00\x00\x00m\x91\x940\x00\x00\x00\x00n\\\xa9@\x00\x00\x00\x00oz\xb0\xb0\x00\x00\x00\x00p<\x8b@\x00\x00\x00\x00qZ\x92\xb0\x00\x00\x00\x00r%\xa7\xc0\x00\x00" + + "\x00\x00s:t\xb0\x00\x00\x00\x00t\x05\x89\xc0\x00\x00\x00\x00u\x1aV\xb0\x00\x00\x00\x00u\xe5k\xc0\x00\x00\x00\x00v\xfa8\xb0\x00\x00\x00\x00w\xc5M\xc0\x00\x00\x00\x00x\xda\x1a\xb0\x00\x00\x00\x00y\xa5" + + "/\xc0\x00\x00\x00\x00z\xc370\x00\x00\x00\x00{\x85\x11\xc0\x00\x00\x00\x00|\xa3\x190\x00\x00\x00\x00}n.@\x00\x00\x00\x00~\x82\xfb0\x00\x00\x00\x00\u007fN\x10@\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02" + + "\x01\x03\x01\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x03\x02\x03\x05\x03\x02\x03\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\x06\xff\xff\xbd\xba\x00\x00\xff\xff\xbd\xba\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0" + + "\x00\f\xff\xff\xc7\xc0\x01\f\xff\xff\xd5\xd0\x01\x10\xff\xff\xd5\xd0\x01\x10\xff\xff\xc7\xc0\x00\fLMT\x00SMT\x00-05\x00-04\x00-03\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00" + + "\x01\x01\n<-04>4<-03>,M9.1.6/24,M4.1.6/24\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfe\xd6y\x85\xec\x00\x00\x00\xec\x00\x00" + + "\x00\x0e\x00\x1c\x00America/GuyanaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\x98\xd9y\x88\n}\xb4<'\u007f\xfb0\u007f\xff\xff\xff\x01\x02\x03\x03\xff\xff\xc9x\x00\x00\xff\xff\xcb" + + "D\x00\x04\xff\xff\xd5\xd0\x00\n\xff\xff\xc7\xc0\x00\x0eLMT\x00-0345\x00-03\x00-04\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x98\xd9y\x88\x00\x00\x00\x00\n}\xb4<\x00\x00\x00\x00'\u007f\xfb0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x03\xff\xff\xc9x\x00\x00\xff" + + "\xff\xcbD\x00\x04\xff\xff\xd5\xd0\x00\n\xff\xff\xc7\xc0\x00\x0eLMT\x00-0345\x00-03\x00-04\x00\n<-04>4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPENO" + + "\xd9P\x01\x00\x00P\x01\x00\x00\x15\x00\x1c\x00America/Coral_HarbourUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00" + + "\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x06\x00\x00\x00\x18\x80\x00\x00\x00\x9e\xb8\xa1\x80\x9f\xba\xf9p\xc8\xf8" + + "W`ˈ\xfe\x80\xd2#\xf4p\xd2a\t\xf0\x02\x01\x02\x01\x03\x04\x05\xff\xff\xaa\x1c\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14LMT" + + "\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00" + + "\x06\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xffr\xee\x84d\xff\xff\xff\xff\x9e\xb8\xa1\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xc8\xf8W`\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff" + + "\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\x02\x01\x02\x01\x03\x04\x05\xff\xff\xaa\x1c\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14LMT\x00" + + "CDT\x00CST\x00CWT\x00CPT\x00EST\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00\nEST5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe6\xee\xf1\xbft\x02\x00\x00" + + "t\x02\x00\x00\x12\x00\x1c\x00America/Rio_BrancoUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x05\x00\x00\x00\f\x96\xaa\x86\x90\xb8\x0ff\x00\xb8\xfd\\\xc0\xb9\xf1PP\xbaސ@\xda8" + + "\xcaP\xda\xec\x16P\xdc\x19\xfd\xd0ܹu@\xdd\xfb1Pޛ\xfa@\xdfݶP\xe0TO@\xf4\x98\x1b\xd0\xf5\x05z@\xf6\xc0\x80P\xf7\x0e:\xc0\xf8QHP\xf8\xc7\xe1@\xfa\n\xee\xd0\xfa\xa9" + + "\x14\xc0\xfb\xec\"P\xfc\x8b\x99\xc0\x1dɪP\x1ex\xf3\xc0\x1f\xa0Q\xd0 3\xeb\xc0!\x81\x85P\"\v\xe4\xc0H`\u007fPR\u007f\x04\xc0\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x02\xff\xff\xc0p\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\x04\xff\xff\xb9\xb0\x00\bLMT\x00-04\x00-05\x00" + + "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x05\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x86\x90\xff\xff\xff\xff\xb8\x0ff\x00" + + "\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xf1PP\xff\xff\xff\xff\xbaސ@\xff\xff\xff\xff\xda8\xcaP\xff\xff\xff\xff\xda\xec\x16P\xff\xff\xff\xff\xdc\x19\xfd\xd0\xff\xff\xff\xffܹu@\xff\xff\xff\xff" + + "\xdd\xfb1P\xff\xff\xff\xffޛ\xfa@\xff\xff\xff\xff\xdfݶP\xff\xff\xff\xff\xe0TO@\xff\xff\xff\xff\xf4\x98\x1b\xd0\xff\xff\xff\xff\xf5\x05z@\xff\xff\xff\xff\xf6\xc0\x80P\xff\xff\xff\xff\xf7\x0e:\xc0" + + "\xff\xff\xff\xff\xf8QHP\xff\xff\xff\xff\xf8\xc7\xe1@\xff\xff\xff\xff\xfa\n\xee\xd0\xff\xff\xff\xff\xfa\xa9\x14\xc0\xff\xff\xff\xff\xfb\xec\"P\xff\xff\xff\xff\xfc\x8b\x99\xc0\x00\x00\x00\x00\x1dɪP\x00\x00\x00\x00" + + "\x1ex\xf3\xc0\x00\x00\x00\x00\x1f\xa0Q\xd0\x00\x00\x00\x00 3\xeb\xc0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"\v\xe4\xc0\x00\x00\x00\x00H`\u007fP\x00\x00\x00\x00R\u007f\x04\xc0\x00\x00\x00\x00\u007f\xff\xff\xff" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x02\xff\xff\xc0p\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\x04\xff\xff\xb9\xb0" + + "\x00\bLMT\x00-04\x00-05\x00\n<-05>5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe6\xee\xf1\xbft\x02\x00\x00t\x02\x00\x00\x12\x00\x1c\x00America/" + + "Porto_AcreUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x05\x00\x00\x00\f\x96\xaa\x86\x90\xb8\x0ff\x00\xb8\xfd\\\xc0\xb9\xf1PP\xbaސ@\xda8\xcaP\xda\xec\x16P\xdc\x19\xfd\xd0ܹu@\xdd\xfb" + + "1Pޛ\xfa@\xdfݶP\xe0TO@\xf4\x98\x1b\xd0\xf5\x05z@\xf6\xc0\x80P\xf7\x0e:\xc0\xf8QHP\xf8\xc7\xe1@\xfa\n\xee\xd0\xfa\xa9\x14\xc0\xfb\xec\"P\xfc\x8b\x99\xc0\x1dɪP\x1ex" + + "\xf3\xc0\x1f\xa0Q\xd0 3\xeb\xc0!\x81\x85P\"\v\xe4\xc0H`\u007fPR\u007f\x04\xc0\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03" + + "\x02\x02\xff\xff\xc0p\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\x04\xff\xff\xb9\xb0\x00\bLMT\x00-04\x00-05\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x05\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x86\x90\xff\xff\xff\xff\xb8\x0ff\x00\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xf1PP" + + "\xff\xff\xff\xff\xbaސ@\xff\xff\xff\xff\xda8\xcaP\xff\xff\xff\xff\xda\xec\x16P\xff\xff\xff\xff\xdc\x19\xfd\xd0\xff\xff\xff\xffܹu@\xff\xff\xff\xff\xdd\xfb1P\xff\xff\xff\xffޛ\xfa@\xff\xff\xff\xff" + + "\xdfݶP\xff\xff\xff\xff\xe0TO@\xff\xff\xff\xff\xf4\x98\x1b\xd0\xff\xff\xff\xff\xf5\x05z@\xff\xff\xff\xff\xf6\xc0\x80P\xff\xff\xff\xff\xf7\x0e:\xc0\xff\xff\xff\xff\xf8QHP\xff\xff\xff\xff\xf8\xc7\xe1@" + + "\xff\xff\xff\xff\xfa\n\xee\xd0\xff\xff\xff\xff\xfa\xa9\x14\xc0\xff\xff\xff\xff\xfb\xec\"P\xff\xff\xff\xff\xfc\x8b\x99\xc0\x00\x00\x00\x00\x1dɪP\x00\x00\x00\x00\x1ex\xf3\xc0\x00\x00\x00\x00\x1f\xa0Q\xd0\x00\x00\x00\x00" + + " 3\xeb\xc0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"\v\xe4\xc0\x00\x00\x00\x00H`\u007fP\x00\x00\x00\x00R\u007f\x04\xc0\x00\x00\x00\x00\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x02\xff\xff\xc0p\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\x04\xff\xff\xb9\xb0\x00\bLMT\x00-04\x00-05\x00\n<" + + "-05>5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x01\x84\xd10J\b\x00\x00J\b\x00\x00\x0f\x00\x1c\x00America/NipigonUT\t\x00\x03nӧ^" + + "nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x87\x00\x00\x00\x05\x00" + + "\x00\x00\x14\x80\x00\x00\x00\x9e\xb8\x93p\x9f\xba\xeb`\xc8\xf8IPˈ\xf0p\xd2#\xf4p\xd2`\xfb\xe0\b \xc1p\t\x10\xa4`\n\x00\xa3p\n\xf0\x86`\v\xe0\x85p\f٢\xe0\r\xc0gp\x0e" + + "\xb9\x84\xe0\x0f\xa9\x83\xf0\x10\x99f\xe0\x11\x89e\xf0\x12yH\xe0\x13iG\xf0\x14Y*\xe0\x15I)\xf0\x169\f\xe0\x17)\v\xf0\x18\")`\x19\b\xed\xf0\x1a\x02\v`\x1a\xf2\np\x1b\xe1\xed`\x1c" + + "\xd1\xecp\x1d\xc1\xcf`\x1e\xb1\xcep\x1f\xa1\xb1` v\x00\xf0!\x81\x93`\"U\xe2\xf0#j\xaf\xe0$5\xc4\xf0%J\x91\xe0&\x15\xa6\xf0'*s\xe0'\xfe\xc3p)\nU\xe0)ޥp*" + + "\xea7\xe0+\xbe\x87p,\xd3T`-\x9eip.\xb36`/~Kp0\x93\x18`1gg\xf02r\xfa`3GI\xf04R\xdc`5'+\xf062\xbe`7\a\r\xf08\x1b\xda\xe08" + + "\xe6\xef\xf09\xfb\xbc\xe0:\xc6\xd1\xf0;۞\xe0<\xaf\xeep=\xbb\x80\xe0>\x8f\xd0p?\x9bb\xe0@o\xb2pA\x84\u007f`BO\x94pCda`D/vpEDC`E\xf3\xa8\xf0G" + + "-_\xe0Gӊ\xf0I\rA\xe0I\xb3l\xf0J\xed#\xe0K\x9c\x89pL\xd6@`M|kpN\xb6\"`O\\MpP\x96\x04`Q\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00" + + "\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\u007f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x00\x00\x00\x00G-" + + "_\xe0\x00\x00\x00\x00Gӊ\xf0\x00\x00\x00\x00I\rA\xe0\x00\x00\x00\x00I\xb3l\xf0\x00\x00\x00\x00J\xed#\xe0\x00\x00\x00\x00K\x9c\x89p\x00\x00\x00\x00L\xd6@`\x00\x00\x00\x00M|kp\x00\x00" + + "\x00\x00N\xb6\"`\x00\x00\x00\x00O\\Mp\x00\x00\x00\x00P\x96\x04`\x00\x00\x00\x00Q" + + "\x8f\xec\x90?\x9b\u007f\x00@oΐA\x84\x9b\x80BO\xb0\x90Cd}\x80D/\x92\x90ED_\x80E\xf3\xc5\x10G-|\x00Gӧ\x10I\r^\x00I\xb3\x89\x10J\xed@\x00K\x9c\xa5\x90L" + + "\xd6\\\x80M|\x87\x90N\xb6>\x80O\\i\x90P\x96 \x80Q\x8f\xec\x90\x00\x00\x00\x00?\x9b\u007f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00" + + "\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x00\x00\x00\x00G-|\x00\x00\x00\x00\x00Gӧ" + + "\x10\x00\x00\x00\x00I\r^\x00\x00\x00\x00\x00I\xb3\x89\x10\x00\x00\x00\x00J\xed@\x00\x00\x00\x00\x00K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\\\x80\x00\x00\x00\x00M|\x87\x90\x00\x00\x00\x00N\xb6>\x80\x00\x00\x00" + + "\x00O\\i\x90\x00\x00\x00\x00P\x96 \x80\x00\x00\x00\x00Q\x00\x00\x00\x06\x00\x00\x00\x14\x80\x00\x00\x00\xa2\x92\x8f0\xb6{R@\xb7\x1aɰ\xb8\x1e\x8f@\xb8\xd4p0" + + "\xba\x17}\xc0\xba\xb5\xa3\xb0\xbb\xf8\xb1@\xbc\x96\xd70\xbd\xd9\xe4\xc0\xbex\n\xb0\xbf\xbb\x18@\xc0Z\x8f\xb0\xc1\x9d\x9d@\xc2;\xc30\xc3~\xd0\xc0\xc4\x1c\xf6\xb0\xc5`\x04@\xc5\xfe*0\xc7A7\xc0" + + "\xc7\xe0\xaf0ȁ\x94@\xcaM\xa1\xb0\xca\xee\x86\xc0\xceM\xff0ΰ\xed\xc0\xd3)5\xb0\xd4Cd\xc0\xf4=\b0\xf4\x9f\xf6\xc0\xf5\x05l0\xf62\x10@\xf6柰\xf8\x13C\xc0\xf8\xc7\xd30" + + "\xf9\xf4w@\xfa\xd36\xb0\xfb\xc35\xc0\xfc\xbcS0\xfd\xacR@\xfe\x9c50\xff\x8c4@\a\xa3J\xb0\b$o\xa0#\x94\xb5\xb0$\x10\x94\xa0%7\xf2\xb0%\xf0v\xa0'!\x0f0'\xd0X\xa0" + + ")\x00\xff@)\xb0:\xa0*\xe0\xd30+\x99W 7\xf6ư8\xbf*\xb0@\xbb\xf10@\xd5\v\xc0Gw\t\xb0G\xdc\u007f \u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\x05\xff\xff\xc2T\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff" + + "\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xaf,\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff" + + "\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex" + + "\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff" + + "\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ" + + "\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff" + + "\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c" + + "50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00" + + "\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf" + + "*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\v\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\u007f \x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\x05\xff\xff\xc2T\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0" + + "\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F" + + "\x9cP\xcf|3(\x94\x00\x00\x00\x94\x00\x00\x00\x0f\x00\x1c\x00America/AntiguaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00" + + "\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\x9373\xac\x01\xff\xff\xc6T\x00\x00\xff\xff\xc7\xc0" + + "\x00\x04LMT\x00AST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x937" + + "3\xac\x01\xff\xff\xc6T\x00\x00\xff\xff\xc7\xc0\x00\x04LMT\x00AST\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP+!\xd6\n@\x02\x00\x00@\x02\x00\x00\x13\x00\x1c\x00A" + + "merica/Porto_VelhoUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x03\x00\x00\x00\f\x96\xaa\x82\xe8\xb8\x0fW\xf0\xb8\xfdN\xb0\xb9\xf1B@\xbaނ0\xda8\xbc@\xda\xec\b@\xdc\x19" + + "\xef\xc0ܹg0\xdd\xfb#@ޛ\xec0\xdfݨ@\xe0TA0\xf4\x98\r\xc0\xf5\x05l0\xf6\xc0r@\xf7\x0e,\xb0\xf8Q:@\xf8\xc7\xd30\xfa\n\xe0\xc0\xfa\xa9\x06\xb0\xfb\xec\x14@\xfc\x8b" + + "\x8b\xb0\x1dɜ@\x1ex\xe5\xb0\x1f\xa0C\xc0 3ݰ!\x81w@\"\vְ\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02" + + "\xff\xff\xc4\x18\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03\x00-04\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x82\xe8\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xbaނ0\xff\xff\xff\xff\xda8" + + "\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xffޛ\xec0\xff\xff\xff\xff\xdfݨ@\xff\xff\xff\xff\xe0TA0\xff\xff" + + "\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9" + + "\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3ݰ\x00\x00\x00\x00!\x81w@\x00\x00" + + "\x00\x00\"\vְ\x00\x00\x00\x00\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\xff\xff\xc4\x18\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0" + + "\x00\bLMT\x00-03\x00-04\x00\n<-04>4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb6\xb1\xfb\x104\x04\x00\x004\x04\x00\x00\x0f\x00\x1c\x00America/" + + "RosarioUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06\x00\x00\x00\x14\x80\x00\x00\x00\xa2\x92\x8f0\xb6{R@\xb7\x1aɰ\xb8\x1e\x8f@\xb8\xd4p0\xba\x17}\xc0\xba\xb5\xa3\xb0\xbb\xf8\xb1@\xbc\x96\xd70\xbd" + + "\xd9\xe4\xc0\xbex\n\xb0\xbf\xbb\x18@\xc0Z\x8f\xb0\xc1\x9d\x9d@\xc2;\xc30\xc3~\xd0\xc0\xc4\x1c\xf6\xb0\xc5`\x04@\xc5\xfe*0\xc7A7\xc0\xc7\xe0\xaf0ȁ\x94@\xcaM\xa1\xb0\xca\xee\x86\xc0\xce" + + "M\xff0ΰ\xed\xc0\xd3)5\xb0\xd4Cd\xc0\xf4=\b0\xf4\x9f\xf6\xc0\xf5\x05l0\xf62\x10@\xf6柰\xf8\x13C\xc0\xf8\xc7\xd30\xf9\xf4w@\xfa\xd36\xb0\xfb\xc35\xc0\xfc\xbcS0\xfd" + + "\xacR@\xfe\x9c50\xff\x8c4@\a\xa3J\xb0\b$o\xa0#\x94\xb5\xb0$\x10\x94\xa0%7\xf2\xb0%\xf0v\xa0'!\x0f0'\xd0X\xa0)\x00\xff@)\xb0:\xa0*\xe0\xd30+\x99W 7" + + "\xf6ư8\xbf*\xb0Gw\t\xb0G\xdc\u007f H\xfa\xa2\xb0I\xbca \u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\x05\xff\xff\xc3\xd0\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff" + + "\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + ">\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xad\xb0\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff" + + "\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f" + + "\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff" + + "\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd" + + "\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff" + + "\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J" + + "\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00" + + "\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\u007f" + + " \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\x05\xff\xff\xc3\xd0\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5" + + "\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf8=\xf2\x1a\xf8\r\x00\x00\xf8\r\x00\x00\x0f\x00\x1c" + + "\x00America/ChicagoUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xec\x00\x00\x00\a\x00\x00\x00\x18\x80\x00\x00\x00\x9e\xa6,\x80\x9f\xba\xf9p\xa0\x86\x0e\x80\xa1\x9a\xdbp\xa2\xcbt\x00\xa3\x83\xf7\xf0\xa4EҀ" + + "\xa5c\xd9\xf0\xa6S\xd9\x00\xa7\x15\x97p\xa83\xbb\x00\xa8\xfe\xb3\xf0\xaa\x13\x9d\x00\xaaޕ\xf0\xab\xf3\u007f\x00\xac\xbew\xf0\xad\xd3a\x00\xae\x9eY\xf0\xaf\xb3C\x00\xb0~;\xf0\xb1\x9c_\x80\xb2gXp" + + "\xb3|A\x80\xb4G:p\xb5\\#\x80\xb6'\x1cp\xb7<\x05\x80\xb8\x06\xfep\xb9\x1b瀹\xe6\xe0p\xbb\x05\x04\x00\xbb\xc6\xc2p\xbc\xe4\xe6\x00\xbd\xaf\xde\xf0\xbe\xc4\xc8\x00\xbf\x8f\xc0\xf0\xc0Z\xd6\x00" + + "\xc1\xb0\x8fހ?\x9bp\xf0@o\xc0\x80A\x84\x8dpBO\xa2\x80CdopD/\x84\x80" + + "EDQpE\xf3\xb7\x00G-m\xf0Gә\x00I\rO\xf0I\xb3{\x00J\xed1\xf0K\x9c\x97\x80L\xd6NpM|y\x80N\xb60pO\\[\x80P\x96\x12pQ<=\x80Ru\xf4p" + + "S\x1c\x1f\x80TU\xd6pT\xfc\x01\x80V5\xb8pV\xe5\x1e\x00X\x1e\xd4\xf0X\xc5\x00\x00Y\xfe\xb6\xf0Z\xa4\xe2\x00[ޘ\xf0\\\x84\xc4\x00]\xbez\xf0^d\xa6\x00_\x9e\\\xf0`M\u0080" + + "a\x87ypb-\xa4\x80cg[pd\r\x86\x80eG=pe\xedh\x80g'\x1fpg\xcdJ\x80i\a\x01pi\xad,\x80j\xe6\xe3pk\x96I\x00l\xcf\xff\xf0mv+\x00n\xaf\xe1\xf0" + + "oV\r\x00p\x8f\xc3\xf0q5\xef\x00ro\xa5\xf0s\x15\xd1\x00tO\x87\xf0t\xfe\xed\x80v8\xa4pv\xdeπx\x18\x86px\xbe\xb1\x80y\xf8hpz\x9e\x93\x80{\xd8Jp|~u\x80" + + "}\xb8,p~^W\x80\u007f\x98\x0ep\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x04\x05\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xad\xd4\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x00\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x01\x14\xff\xff\xab\xa0\x00\bLMT\x00CDT\x00CS" + + "T\x00EST\x00CWT\x00CPT\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00" + + "\x00\x00\x00\xec\x00\x00\x00\a\x00\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xa2\xcbt\x00" + + "\xff\xff\xff\xff\xa3\x83\xf7\xf0\xff\xff\xff\xff\xa4EҀ\xff\xff\xff\xff\xa5c\xd9\xf0\xff\xff\xff\xff\xa6S\xd9\x00\xff\xff\xff\xff\xa7\x15\x97p\xff\xff\xff\xff\xa83\xbb\x00\xff\xff\xff\xff\xa8\xfe\xb3\xf0\xff\xff\xff\xff" + + "\xaa\x13\x9d\x00\xff\xff\xff\xff\xaaޕ\xf0\xff\xff\xff\xff\xab\xf3\u007f\x00\xff\xff\xff\xff\xac\xbew\xf0\xff\xff\xff\xff\xad\xd3a\x00\xff\xff\xff\xff\xae\x9eY\xf0\xff\xff\xff\xff\xaf\xb3C\x00\xff\xff\xff\xff\xb0~;\xf0" + + "\xff\xff\xff\xff\xb1\x9c_\x80\xff\xff\xff\xff\xb2gXp\xff\xff\xff\xff\xb3|A\x80\xff\xff\xff\xff\xb4G:p\xff\xff\xff\xff\xb5\\#\x80\xff\xff\xff\xff\xb6'\x1cp\xff\xff\xff\xff\xb7<\x05\x80\xff\xff\xff\xff" + + "\xb8\x06\xfep\xff\xff\xff\xff\xb9\x1b\xe7\x80\xff\xff\xff\xff\xb9\xe6\xe0p\xff\xff\xff\xff\xbb\x05\x04\x00\xff\xff\xff\xff\xbb\xc6\xc2p\xff\xff\xff\xff\xbc\xe4\xe6\x00\xff\xff\xff\xff\xbd\xaf\xde\xf0\xff\xff\xff\xff\xbe\xc4\xc8\x00" + + "\xff\xff\xff\xff\xbf\x8f\xc0\xf0\xff\xff\xff\xff\xc0Z\xd6\x00\xff\xff\xff\xff\xc1\xb0\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80" + + "\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G-m\xf0\x00\x00\x00\x00Gә\x00\x00\x00\x00\x00I\rO\xf0\x00\x00\x00\x00" + + "I\xb3{\x00\x00\x00\x00\x00J\xed1\xf0\x00\x00\x00\x00K\x9c\x97\x80\x00\x00\x00\x00L\xd6Np\x00\x00\x00\x00M|y\x80\x00\x00\x00\x00N\xb60p\x00\x00\x00\x00O\\[\x80\x00\x00\x00\x00P\x96\x12p" + + "\x00\x00\x00\x00Q<=\x80\x00\x00\x00\x00Ru\xf4p\x00\x00\x00\x00S\x1c\x1f\x80\x00\x00\x00\x00TU\xd6p\x00\x00\x00\x00T\xfc\x01\x80\x00\x00\x00\x00V5\xb8p\x00\x00\x00\x00V\xe5\x1e\x00\x00\x00\x00\x00" + + "X\x1e\xd4\xf0\x00\x00\x00\x00X\xc5\x00\x00\x00\x00\x00\x00Y\xfe\xb6\xf0\x00\x00\x00\x00Z\xa4\xe2\x00\x00\x00\x00\x00[ޘ\xf0\x00\x00\x00\x00\\\x84\xc4\x00\x00\x00\x00\x00]\xbez\xf0\x00\x00\x00\x00^d\xa6\x00" + + "\x00\x00\x00\x00_\x9e\\\xf0\x00\x00\x00\x00`M\u0080\x00\x00\x00\x00a\x87yp\x00\x00\x00\x00b-\xa4\x80\x00\x00\x00\x00cg[p\x00\x00\x00\x00d\r\x86\x80\x00\x00\x00\x00eG=p\x00\x00\x00\x00" + + "e\xedh\x80\x00\x00\x00\x00g'\x1fp\x00\x00\x00\x00g\xcdJ\x80\x00\x00\x00\x00i\a\x01p\x00\x00\x00\x00i\xad,\x80\x00\x00\x00\x00j\xe6\xe3p\x00\x00\x00\x00k\x96I\x00\x00\x00\x00\x00l\xcf\xff\xf0" + + "\x00\x00\x00\x00mv+\x00\x00\x00\x00\x00n\xaf\xe1\xf0\x00\x00\x00\x00oV\r\x00\x00\x00\x00\x00p\x8f\xc3\xf0\x00\x00\x00\x00q5\xef\x00\x00\x00\x00\x00ro\xa5\xf0\x00\x00\x00\x00s\x15\xd1\x00\x00\x00\x00\x00" + + "tO\x87\xf0\x00\x00\x00\x00t\xfe\xed\x80\x00\x00\x00\x00v8\xa4p\x00\x00\x00\x00v\xdeπ\x00\x00\x00\x00x\x18\x86p\x00\x00\x00\x00x\xbe\xb1\x80\x00\x00\x00\x00y\xf8hp\x00\x00\x00\x00z\x9e\x93\x80" + + "\x00\x00\x00\x00{\xd8Jp\x00\x00\x00\x00|~u\x80\x00\x00\x00\x00}\xb8,p\x00\x00\x00\x00~^W\x80\x00\x00\x00\x00\u007f\x98\x0ep\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x05\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xad\xd4\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x00\f" + + "\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x01\x14\xff\xff\xab\xa0\x00\bLMT\x00CDT\x00CST\x00EST\x00CWT\x00CPT\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x01\x00\nCST" + + "6CDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa4\xac\xbaE\xd0\x00\x00\x00\xd0\x00\x00\x00\x0f\x00\x1c\x00America/Cr" + + "estonUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\f\x80\x00\x00\x00\x9b\xd6Kp\x9e\xf9;\x00\x01\x02\x01\xff\xff\x92\xc4\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x00\x04LMT\x00" + + "MST\x00PST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff^=p\xbc" + + "\xff\xff\xff\xff\x9b\xd6Kp\xff\xff\xff\xff\x9e\xf9;\x00\x01\x02\x01\xff\xff\x92\xc4\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x00\x04LMT\x00MST\x00PST\x00\nMST7" + + "\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xd7o̥\xae\x01\x00\x00\xae\x01\x00\x00\x0f\x00\x1c\x00America/ManaguaUT\t\x00\x03nӧ^nӧ^u" + + "x\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x06\x00\x00\x00\x14\x80\x00" + + "\x00\x00\xbd-H\xe8\x06Ct`\t\xa4>P\x11Q\xf8\xe0\x11\xd4oP\x131\xda\xe0\x13\xb4QP)a\x91 *\xc1KP+C\xdd\xe02\xc9\xefPBX\xc0\xe0C?iPDTn\x80E\x1f" + + "Y`\x01\x02\x03\x02\x04\x02\x04\x02\x03\x02\x03\x02\x04\x02\x04\x02\xff\xff\xaf\x1c\x00\x00\xff\xff\xaf\x18\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x00\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xab\xa0\x00\bLMT\x00MM" + + "T\x00CST\x00EST\x00CDT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff" + + "\xff\xffi\x87,d\xff\xff\xff\xff\xbd-H\xe8\x00\x00\x00\x00\x06Ct`\x00\x00\x00\x00\t\xa4>P\x00\x00\x00\x00\x11Q\xf8\xe0\x00\x00\x00\x00\x11\xd4oP\x00\x00\x00\x00\x131\xda\xe0\x00\x00\x00\x00\x13\xb4" + + "QP\x00\x00\x00\x00)a\x91 \x00\x00\x00\x00*\xc1KP\x00\x00\x00\x00+C\xdd\xe0\x00\x00\x00\x002\xc9\xefP\x00\x00\x00\x00BX\xc0\xe0\x00\x00\x00\x00C?iP\x00\x00\x00\x00DTn\x80\x00\x00" + + "\x00\x00E\x1fY`\x01\x02\x03\x02\x04\x02\x04\x02\x03\x02\x03\x02\x04\x02\x04\x02\xff\xff\xaf\x1c\x00\x00\xff\xff\xaf\x18\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x00\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xab\xa0\x00\bLM" + + "T\x00MMT\x00CST\x00EST\x00CDT\x00\nCST6\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP#yȝ\xd2\b\x00\x00\xd2\b\x00\x00\x0e\x00\x1c\x00Americ" + + "a/NassauUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\x00\x00\x00\x03\x00\x00\x00\f\x937B\x8a\xf5Oxp\xf6?[`\xf7/Zp\xf8(w\xe0\xf9\x0f\x8f\xd0p?\x9bb\xe0@o\xb2pA\x84\u007f`BO\x94pCda`" + + "D/vpEDC`E\xf3\xa8\xf0G-_\xe0Gӊ\xf0I\rA\xe0I\xb3l\xf0J\xed#\xe0K\x9c\x89pL\xd6@`M|kpN\xb6\"`O\\MpP\x96\x04`Q\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A" + + "\x84\u007f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x00\x00\x00\x00G-_\xe0\x00\x00\x00\x00Gӊ\xf0\x00" + + "\x00\x00\x00I\rA\xe0\x00\x00\x00\x00I\xb3l\xf0\x00\x00\x00\x00J\xed#\xe0\x00\x00\x00\x00K\x9c\x89p\x00\x00\x00\x00L\xd6@`\x00\x00\x00\x00M|kp\x00\x00\x00\x00N\xb6\"`\x00\x00\x00\x00O" + + "\\Mp\x00\x00\x00\x00P\x96\x04`\x00\x00\x00\x00Q5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPC2\xb5\xff\x0e\x03\x00\x00\x0e\x03\x00\x00\x0e\x00" + + "\x1c\x00America/CancunUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\x00\x00\x00\x05\x00\x00\x00\x14\xa5\xb6\xda`\x16\x86\xd5`1gg\xf02r\xfa`3GI\xf04R\xdc`5'+\xf05\xc4\x00`" + + "62\xccp7\a\x1c\x008\x1b\xe8\xf08\xe6\xfe\x009\xfb\xca\xf0:\xf5\x04\x80;\xb6\xc2\xf0<\xaf\xfc\x80=\xbb\x8e\xf0>\x8fހ?\x9bp\xf0@o\xc0\x80A\x84\x8dpBO\xa2\x80Cdop" + + "D/\x84\x80EDQpF\x0ff\x80G$3pG\xf8\x83\x00I\x04\x15pI\xd8e\x00J\xe3\xf7pK\xb8G\x00L\xcd\x13\xf0M\x98)\x00N\xac\xf5\xf0Ox\v\x00P\x8c\xd7\xf0Qa'\x80" + + "Rl\xb9\xf0SA\t\x80TL\x9b\xf0T\xcd\xdd\x00\x01\x03\x02\x03\x02\x03\x02\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\xff\xff" + + "\xae\xa8\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xc7\xc0\x01\b\xff\xff\xb9\xb0\x00\f\xff\xff\xb9\xb0\x01\x10LMT\x00CST\x00EDT\x00EST\x00CDT\x00TZif2\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xda`\x00\x00\x00\x00\x16\x86\xd5`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x00" + + "2r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x005\xc4\x00`\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0" + + "\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00" + + "?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00F\x0ff\x80" + + "\x00\x00\x00\x00G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00K\xb8G\x00\x00\x00\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00" + + "M\x98)\x00\x00\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00Ox\v\x00\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00Rl\xb9\xf0\x00\x00\x00\x00SA\t\x80\x00\x00\x00\x00TL\x9b\xf0" + + "\x00\x00\x00\x00T\xcd\xdd\x00\x01\x03\x02\x03\x02\x03\x02\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\xff\xff\xae\xa8\x00\x00\xff\xff\xab\xa0" + + "\x00\x04\xff\xff\xc7\xc0\x01\b\xff\xff\xb9\xb0\x00\f\xff\xff\xb9\xb0\x01\x10LMT\x00CST\x00EDT\x00EST\x00CDT\x00\nEST5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP" + + "\xa5\xa5\x94w\xcc\x05\x00\x00\xcc\x05\x00\x00\x11\x00\x1c\x00America/ChihuahuaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00" + + "\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Z\x00\x00\x00\x06\x00\x00\x00\x14\xa5\xb6\xe8p\xaf\xf2n\xe0\xb6fV`\xb7C\xd2" + + "`\xb8\f6`\xb8\xfd\x86\xf01gv\x002s\bp3GX\x004R\xeap5'H\x1062ڀ7\a*\x108\x1b\xf7\x008\xe7\f\x109\xfb\xd9\x00:\xf5\x12\x90;\xb6\xd1\x00<\xb0\n" + + "\x90=\xbb\x9d\x00>\x8f\xec\x90?\x9b\u007f\x00@oΐA\x84\x9b\x80BO\xb0\x90Cd}\x80D/\x92\x90ED_\x80F\x0ft\x90G$A\x80G\xf8\x91\x10I\x04#\x80I\xd8s\x10J\xe4\x05" + + "\x80K\xb8U\x10L\xcd\"\x00M\x987\x10N\xad\x04\x00Ox\x19\x10P\x8c\xe6\x00Qa5\x90Rl\xc8\x00SA\x17\x90TL\xaa\x00U \xf9\x90V,\x8c\x00W\x00ېX\x15\xa8\x80X\xe0\xbd" + + "\x90Y\xf5\x8a\x80Z\xc0\x9f\x90[\xd5l\x80\\\xa9\xbc\x10]\xb5N\x80^\x89\x9e\x10_\x950\x80`i\x80\x10a~M\x00bIb\x10c^/\x00d)D\x10e>\x11\x00f\x12`\x90g\x1d\xf3" + + "\x00g\xf2B\x90h\xfd\xd5\x00i\xd2$\x90jݷ\x00k\xb2\x06\x90l\xc6Ӏm\x91\xe8\x90n\xa6\xb5\x80oqʐp\x86\x97\x80qZ\xe7\x10rfy\x80s:\xc9\x10tF[\x80u\x1a\xab" + + "\x10v/x\x00v\xfa\x8d\x10x\x0fZ\x00x\xdao\x10y\xef<\x00z\xbaQ\x10{\xcf\x1e\x00|\xa3m\x90}\xaf\x00\x00~\x83O\x90\u007f\x8e\xe2\x00\x01\x02\x01\x02\x01\x02\x03\x02\x03\x02\x04\x01\x04\x01\x04" + + "\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04" + + "\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\xff\xff\x9c\x8c\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\x9d\x90\x00\x04LMT\x00MST\x00C" + + "ST\x00CDT\x00MDT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Z\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xff\xa5" + + "\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00" + + "\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009" + + "\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\u007f\x00\x00\x00\x00\x00@oΐ\x00" + + "\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80\x00\x00\x00\x00G" + + "\xf8\x91\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00\x00\x00\x00K\xb8U\x10\x00\x00\x00\x00L\xcd\"\x00\x00\x00\x00\x00M\x987\x10\x00\x00\x00\x00N\xad\x04\x00\x00" + + "\x00\x00\x00Ox\x19\x10\x00\x00\x00\x00P\x8c\xe6\x00\x00\x00\x00\x00Qa5\x90\x00\x00\x00\x00Rl\xc8\x00\x00\x00\x00\x00SA\x17\x90\x00\x00\x00\x00TL\xaa\x00\x00\x00\x00\x00U \xf9\x90\x00\x00\x00\x00V" + + ",\x8c\x00\x00\x00\x00\x00W\x00ې\x00\x00\x00\x00X\x15\xa8\x80\x00\x00\x00\x00Xཐ\x00\x00\x00\x00Y\xf5\x8a\x80\x00\x00\x00\x00Z\xc0\x9f\x90\x00\x00\x00\x00[\xd5l\x80\x00\x00\x00\x00\\\xa9\xbc\x10\x00" + + "\x00\x00\x00]\xb5N\x80\x00\x00\x00\x00^\x89\x9e\x10\x00\x00\x00\x00_\x950\x80\x00\x00\x00\x00`i\x80\x10\x00\x00\x00\x00a~M\x00\x00\x00\x00\x00bIb\x10\x00\x00\x00\x00c^/\x00\x00\x00\x00\x00d" + + ")D\x10\x00\x00\x00\x00e>\x11\x00\x00\x00\x00\x00f\x12`\x90\x00\x00\x00\x00g\x1d\xf3\x00\x00\x00\x00\x00g\xf2B\x90\x00\x00\x00\x00h\xfd\xd5\x00\x00\x00\x00\x00i\xd2$\x90\x00\x00\x00\x00jݷ\x00\x00" + + "\x00\x00\x00k\xb2\x06\x90\x00\x00\x00\x00l\xc6Ӏ\x00\x00\x00\x00m\x91\xe8\x90\x00\x00\x00\x00n\xa6\xb5\x80\x00\x00\x00\x00oqʐ\x00\x00\x00\x00p\x86\x97\x80\x00\x00\x00\x00qZ\xe7\x10\x00\x00\x00\x00r" + + "fy\x80\x00\x00\x00\x00s:\xc9\x10\x00\x00\x00\x00tF[\x80\x00\x00\x00\x00u\x1a\xab\x10\x00\x00\x00\x00v/x\x00\x00\x00\x00\x00v\xfa\x8d\x10\x00\x00\x00\x00x\x0fZ\x00\x00\x00\x00\x00x\xdao\x10\x00" + + "\x00\x00\x00y\xef<\x00\x00\x00\x00\x00z\xbaQ\x10\x00\x00\x00\x00{\xcf\x1e\x00\x00\x00\x00\x00|\xa3m\x90\x00\x00\x00\x00}\xaf\x00\x00\x00\x00\x00\x00~\x83O\x90\x00\x00\x00\x00\u007f\x8e\xe2\x00\x01\x02\x01\x02\x01" + + "\x02\x03\x02\x03\x02\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04" + + "\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\xff\xff\x9c\x8c\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\x9d\x90\x00" + + "\x04LMT\x00MST\x00CST\x00CDT\x00MDT\x00\nMST7MDT,M4.1.0,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x93" + + "l\xbbV\xa4\x05\x00\x00\xa4\x05\x00\x00\x14\x00\x1c\x00America/Campo_GrandeUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14" + + "\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\\\x00\x00\x00\x03\x00\x00\x00\f\x96\xaaz4\xb8\x0fW\xf0\xb8\xfdN\xb0\xb9" + + "\xf1B@\xbaނ0\xda8\xbc@\xda\xec\b@\xdc\x19\xef\xc0ܹg0\xdd\xfb#@ޛ\xec0\xdfݨ@\xe0TA0\xf4\x98\r\xc0\xf5\x05l0\xf6\xc0r@\xf7\x0e,\xb0\xf8Q:@\xf8" + + "\xc7\xd30\xfa\n\xe0\xc0\xfa\xa9\x06\xb0\xfb\xec\x14@\xfc\x8b\x8b\xb0\x1dɜ@\x1ex\xe5\xb0\x1f\xa0C\xc0 3ݰ!\x81w@\"\vְ#X\x1e\xc0#\xe2~0%8\x00\xc0%\xd4\xd50'" + + "!\x1d@'\xbd\xf1\xb0)\x00\xff@)\x94\x990*\xea\x1b\xc0+k@\xb0,\xc0\xc3@-f\xd20.\xa0\xa5@/F\xb400\x80\x87@1\x1d[\xb02W.\xc03\x06x048b@4" + + "\xf8\xcf06 -@6\xcfv\xb07\xf6\xd4\xc08\xb8\x9309\xdf\xf1@:\x8f:\xb0;\xc9\r\xc0N\xfe\xb0?\x92\f@@.\xe0\xb0A\x87\x06@B\x17\xfd0C" + + "Q\xd0@C\xf7\xdf0EMa\xc0E\xe0\xfb\xb0G\x11\x94@G\xb7\xa30H\xfa\xb0\xc0I\x97\x850Jڒ\xc0K\x80\xa1\xb0L\xbat\xc0M`\x83\xb0N\x9aV\xc0OI\xa00P\x83s@Q" + + " G\xb0RcU@S\x00)\xb0TC7@T\xe9F0V#\x19@V\xc9(0X\x02\xfb@X\xa9\n0Y\xe2\xdd@Z\x88\xec0[\xden\xc0\\h\xce0\u007f\xff\xff\xff\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\xff\xff\xcc\xcc\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03\x00-04\x00TZi" + + "f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\\\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaaz4\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff" + + "\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xbaނ0\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#" + + "@\xff\xff\xff\xffޛ\xec0\xff\xff\xff\xff\xdfݨ@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff" + + "\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5" + + "\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3ݰ\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"\vְ\x00\x00\x00\x00#X\x1e\xc0\x00\x00\x00\x00#\xe2~0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00" + + "\x00%\xd4\xd50\x00\x00\x00\x00'!\x1d@\x00\x00\x00\x00'\xbd\xf1\xb0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\x94\x990\x00\x00\x00\x00*\xea\x1b\xc0\x00\x00\x00\x00+k@\xb0\x00\x00\x00\x00,\xc0\xc3" + + "@\x00\x00\x00\x00-f\xd20\x00\x00\x00\x00.\xa0\xa5@\x00\x00\x00\x00/F\xb40\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001\x1d[\xb0\x00\x00\x00\x002W.\xc0\x00\x00\x00\x003\x06x0\x00\x00\x00" + + "\x0048b@\x00\x00\x00\x004\xf8\xcf0\x00\x00\x00\x006 -@\x00\x00\x00\x006\xcfv\xb0\x00\x00\x00\x007\xf6\xd4\xc0\x00\x00\x00\x008\xb8\x930\x00\x00\x00\x009\xdf\xf1@\x00\x00\x00\x00:\x8f:" + + "\xb0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00N\xfe\xb0\x00\x00\x00\x00?\x92\f@\x00\x00\x00\x00@.\xe0\xb0\x00\x00\x00\x00A\x87\x06@\x00\x00\x00" + + "\x00B\x17\xfd0\x00\x00\x00\x00CQ\xd0@\x00\x00\x00\x00C\xf7\xdf0\x00\x00\x00\x00EMa\xc0\x00\x00\x00\x00E\xe0\xfb\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xb7\xa30\x00\x00\x00\x00H\xfa\xb0" + + "\xc0\x00\x00\x00\x00I\x97\x850\x00\x00\x00\x00Jڒ\xc0\x00\x00\x00\x00K\x80\xa1\xb0\x00\x00\x00\x00L\xbat\xc0\x00\x00\x00\x00M`\x83\xb0\x00\x00\x00\x00N\x9aV\xc0\x00\x00\x00\x00OI\xa00\x00\x00\x00" + + "\x00P\x83s@\x00\x00\x00\x00Q G\xb0\x00\x00\x00\x00RcU@\x00\x00\x00\x00S\x00)\xb0\x00\x00\x00\x00TC7@\x00\x00\x00\x00T\xe9F0\x00\x00\x00\x00V#\x19@\x00\x00\x00\x00V\xc9(" + + "0\x00\x00\x00\x00X\x02\xfb@\x00\x00\x00\x00X\xa9\n0\x00\x00\x00\x00Y\xe2\xdd@\x00\x00\x00\x00Z\x88\xec0\x00\x00\x00\x00[\xden\xc0\x00\x00\x00\x00\\h\xce0\x00\x00\x00\x00\u007f\xff\xff\xff\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\xff\xff\xcc\xcc\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03\x00-04\x00\n" + + "<-04>4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe8OD\xf3`\r\x00\x00`\r\x00\x00\x0f\x00\x1c\x00America/HalifaxUT\t\x00\x03nӧ" + + "^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\xe4\x00\x00\x00\x05" + + "\x00\x00\x00\x14\x80\U0006b81a\xe4\xde\xc0\x9b\xd6\x130\x9e\xb8\x85`\x9f\xba\xddP\xa2\x9d\x17@\xa30\xb10\xa4zV@\xa5\x1b\x1f0\xa6S\xa0\xc0\xa6\xfcR\xb0\xa8<\xbd@\xa8\xdc4\xb0\xaa\x1c\x9f@" + + "\xaa\xcd:0\xab\xfc\x81@\xac\xbf\x910\xad\xee\xd8@\xae\x8c\xfe0\xaf\xbcE@\xb0\u007fU0\xb1\xae\x9c@\xb2Kp\xb0\xb3\x8e~@\xb4$\xbb0\xb5n`@\xb6\x15\xc0\xb0\xb7NB@\xb8\b\x17\xb0" + + "\xb9$\xe9\xc0\xb9\xe7\xf9\xb0\xbb\x04\xcb\xc0\xbb\xd1\x160\xbd\x00]@\xbd\x9d1\xb0\xbe\xf2\xb4@\xbf\x90\xda0\xc0\xd3\xe7\xc0\xc1^G0\u008d\x8e@\xc3P\x9e0\xc4mp@\xc50\x800\xc6r<@" + + "\xc7\x10b0\xc86n\xc0\xc8\xf9~\xb0\xca\x16P\xc0\xca\xd9`\xb0ˈ\xe2`\xd2#\xf4p\xd2`\xed\xd0\xd3u\xd6\xe0\xd4@\xcf\xd0\xd5U\xb8\xe0\xd6 \xb1\xd0\xd75\x9a\xe0\xd8\x00\x93\xd0\xd9\x15|\xe0" + + "\xd9\xe0u\xd0\xdc\xde{`ݩtP\u07be]`߉VP\xe0\x9e?`\xe1i8P\xe2~!`\xe3I\x1aP\xe6G\x1f\xe0\xe7\x12\x18\xd0\xe8'\x01\xe0\xe8\xf1\xfa\xd0\xea\x06\xe3\xe0\xea\xd1\xdc\xd0" + + "\xeb\xe6\xc5\xe0챾\xd0\xf1\x8f\xa6`\xf2\u007f\x89P\xf3o\x88`\xf4_kP\xf5Oj`\xf6?MP\xf7/L`\xf8(i\xd0\xf9\x0f.`\xfa\bK\xd0\xfa\xf8J\xe0\xfb\xe8-\xd0\xfc\xd8,\xe0" + + "\xfd\xc8\x0f\xd0\xfe\xb8\x0e\xe0\xff\xa7\xf1\xd0\x00\x97\xf0\xe0\x01\x87\xd3\xd0\x02w\xd2\xe0\x03p\xf0P\x04`\xef`\x05P\xd2P\x06@\xd1`\a0\xb4P\b \xb3`\t\x10\x96P\n\x00\x95`\n\xf0xP" + + "\v\xe0w`\fٔ\xd0\r\xc0Y`\x0e\xb9v\xd0\x0f\xa9u\xe0\x10\x99X\xd0\x11\x89W\xe0\x12y:\xd0\x13i9\xe0\x14Y\x1c\xd0\x15I\x1b\xe0\x168\xfe\xd0\x17(\xfd\xe0\x18\"\x1bP\x19\b\xdf\xe0" + + "\x1a\x01\xfdP\x1a\xf1\xfc`\x1b\xe1\xdfP\x1c\xd1\xde`\x1d\xc1\xc1P\x1e\xb1\xc0`\x1f\xa1\xa3P u\xf2\xe0!\x81\x85P\"U\xd4\xe0#j\xa1\xd0$5\xb6\xe0%J\x83\xd0&\x15\x98\xe0'*e\xd0" + + "'\xfe\xb5`)\nG\xd0)ޗ`*\xea)\xd0+\xbey`,\xd3FP-\x9e[`.\xb3(P/~=`0\x93\nP1gY\xe02r\xecP3G;\xe04R\xceP5'\x1d\xe0" + + "62\xb0P7\x06\xff\xe08\x1b\xcc\xd08\xe6\xe1\xe09\xfb\xae\xd0:\xc6\xc3\xe0;ې\xd0<\xaf\xe0`=\xbbr\xd0>\x8f\xc2`?\x9bT\xd0@o\xa4`A\x84qPBO\x86`CdSP" + + "D/h`ED5PE\xf3\x9a\xe0G-Q\xd0G\xd3|\xe0I\r3\xd0I\xb3^\xe0J\xed\x15\xd0K\x9c{`L\xd62PM|]`N\xb6\x14PO\\?`P\x95\xf6PQ\x8f\xc2`" + + "\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@o\xa4`\x00\x00\x00\x00A\x84qP\x00\x00\x00\x00BO\x86`\x00\x00\x00\x00CdSP\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00" + + "E\xf3\x9a\xe0\x00\x00\x00\x00G-Q\xd0\x00\x00\x00\x00G\xd3|\xe0\x00\x00\x00\x00I\r3\xd0\x00\x00\x00\x00I\xb3^\xe0\x00\x00\x00\x00J\xed\x15\xd0\x00\x00\x00\x00K\x9c{`\x00\x00\x00\x00L\xd62P" + + "\x00\x00\x00\x00M|]`\x00\x00\x00\x00N\xb6\x14P\x00\x00\x00\x00O\\?`\x00\x00\x00\x00P\x95\xf6P\x00\x00\x00\x00Q\x8f\xec\x90?\x9b\u007f\x00@oΐA\x84\x9b\x80B" + + "O\xb0\x90Cd}\x80D/\x92\x90ED_\x80E\xf3\xc5\x10G-|\x00Gӧ\x10I\r^\x00I\xb3\x89\x10J\xed@\x00K\x9c\xa5\x90L\xd6\\\x80M|\x87\x90N\xb6>\x80O\\i\x90P" + + "\x96 \x80Q\x8f\xec\x90\x00\x00" + + "\x00\x00?\x9b\u007f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3" + + "\xc5\x10\x00\x00\x00\x00G-|\x00\x00\x00\x00\x00Gӧ\x10\x00\x00\x00\x00I\r^\x00\x00\x00\x00\x00I\xb3\x89\x10\x00\x00\x00\x00J\xed@\x00\x00\x00\x00\x00K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\\\x80\x00\x00" + + "\x00\x00M|\x87\x90\x00\x00\x00\x00N\xb6>\x80\x00\x00\x00\x00O\\i\x90\x00\x00\x00\x00P\x96 \x80\x00\x00\x00\x00Q\x8f\xd0p?\x9bb\xe0@o\xb2pA\x84\u007f`BO\x94pCda`D/vpEDC`E\xf3\xa8\xf0G-_\xe0G" + + "ӊ\xf0I\rA\xe0I\xb3l\xf0J\xed#\xe0K\x9c\x89pL\xd6@`M|kpN\xb6\"`O\\MpP\x96\x04`Q\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\u007f`\x00\x00\x00\x00BO\x94p" + + "\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x00\x00\x00\x00G-_\xe0\x00\x00\x00\x00Gӊ\xf0\x00\x00\x00\x00I\rA\xe0\x00\x00\x00\x00" + + "I\xb3l\xf0\x00\x00\x00\x00J\xed#\xe0\x00\x00\x00\x00K\x9c\x89p\x00\x00\x00\x00L\xd6@`\x00\x00\x00\x00M|kp\x00\x00\x00\x00N\xb6\"`\x00\x00\x00\x00O\\Mp\x00\x00\x00\x00P\x96\x04`" + + "\x00\x00\x00\x00Q\x8f\xa6|?\x9b8\xec" + + "@o\x88|A\x84UlBOj|Cd7lD/L|ED\x19lE\xf3~\xfcG-5\xecG\xd3`\xfcI\r\x17\xecI\xb3B\xfcJ\xec\xf9\xecK\x9c_|L\xd6\x16lM|A|" + + "N\xb6\x14PO\\?`P\x95\xf6PQ\x8f\xa6|\x00\x00\x00\x00?\x9b8\xec\x00\x00\x00\x00@o\x88|\x00\x00\x00" + + "\x00A\x84Ul\x00\x00\x00\x00BOj|\x00\x00\x00\x00Cd7l\x00\x00\x00\x00D/L|\x00\x00\x00\x00ED\x19l\x00\x00\x00\x00E\xf3~\xfc\x00\x00\x00\x00G-5\xec\x00\x00\x00\x00G\xd3`" + + "\xfc\x00\x00\x00\x00I\r\x17\xec\x00\x00\x00\x00I\xb3B\xfc\x00\x00\x00\x00J\xec\xf9\xec\x00\x00\x00\x00K\x9c_|\x00\x00\x00\x00L\xd6\x16l\x00\x00\x00\x00M|A|\x00\x00\x00\x00N\xb6\x14P\x00\x00\x00" + + "\x00O\\?`\x00\x00\x00\x00P\x95\xf6P\x00\x00\x00\x00QN\xf0\xa0?\x91\xfe0@.ҠA\x86\xf80B\x17\xef CQ\xc20C\xf7\xd1" + + " EMS\xb0E\xe0\xed\xa0G\x11\x860G\xb7\x95 H\xfa\xa2\xb0I\x97w Jڄ\xb0K\x80\x93\xa0L\xbaf\xb0M`u\xa0N\x9aH\xb0OI\x92 P\x83e0Q 9\xa0RcG" + + "0S\x00\x1b\xa0TC)0T\xe98 V#\v0V\xc9\x1a X\x02\xed0X\xa8\xfc Y\xe2\xcf0Z\x88\xde [\xde`\xb0\\h\xc0 \u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\xff\xff\xd4L\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00TZif2\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\\\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaar\xb4\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff" + + "\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xff\xde" + + "\x9b\xde \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4Z\t0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff" + + "\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f" + + "\xa05\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00" + + "\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xbd\xe3\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\x94\x8b \x00\x00\x00\x00*\xea\r\xb0\x00\x00\x00\x00+k2\xa0\x00\x00\x00\x00,\xc0\xb50\x00\x00\x00\x00-" + + "f\xc4 \x00\x00\x00\x00.\xa0\x970\x00\x00\x00\x00/F\xa6 \x00\x00\x00\x000\x80y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00\x002W \xb0\x00\x00\x00\x003\x06j \x00\x00\x00\x0048T0\x00" + + "\x00\x00\x004\xf8\xc1 \x00\x00\x00\x006 \x1f0\x00\x00\x00\x006\xcfh\xa0\x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x00:\x8f,\xa0\x00\x00\x00\x00;" + + "\xc8\xff\xb0\x00\x00\x00\x00N\xf0\xa0\x00\x00\x00\x00?\x91\xfe0\x00\x00\x00\x00@.Ҡ\x00\x00\x00\x00A\x86\xf80\x00\x00\x00\x00B\x17\xef \x00" + + "\x00\x00\x00CQ\xc20\x00\x00\x00\x00C\xf7\xd1 \x00\x00\x00\x00EMS\xb0\x00\x00\x00\x00E\xe0\xed\xa0\x00\x00\x00\x00G\x11\x860\x00\x00\x00\x00G\xb7\x95 \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I" + + "\x97w \x00\x00\x00\x00Jڄ\xb0\x00\x00\x00\x00K\x80\x93\xa0\x00\x00\x00\x00L\xbaf\xb0\x00\x00\x00\x00M`u\xa0\x00\x00\x00\x00N\x9aH\xb0\x00\x00\x00\x00OI\x92 \x00\x00\x00\x00P\x83e0\x00" + + "\x00\x00\x00Q 9\xa0\x00\x00\x00\x00RcG0\x00\x00\x00\x00S\x00\x1b\xa0\x00\x00\x00\x00TC)0\x00\x00\x00\x00T\xe98 \x00\x00\x00\x00V#\v0\x00\x00\x00\x00V\xc9\x1a \x00\x00\x00\x00X" + + "\x02\xed0\x00\x00\x00\x00X\xa8\xfc \x00\x00\x00\x00Y\xe2\xcf0\x00\x00\x00\x00Z\x88\xde \x00\x00\x00\x00[\xde`\xb0\x00\x00\x00\x00\\h\xc0 \x00\x00\x00\x00\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\xff\xff\xd4L\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00\n<-03>3" + + "\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf3\x93Ϊ*\x01\x00\x00*\x01\x00\x00\x14\x00\x1c\x00America/Blanc-SablonUT\t\x00\x03nӧ^" + + "nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x05\x00" + + "\x00\x00\x14\x80\x00\x00\x00\x9e\xb8\x85`\x9f\xba\xddPˈ\xe2`\xd2#\xf4p\xd2`\xed\xd0\x02\x01\x02\x03\x04\x02\xff\xff\xcat\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xd5" + + "\xd0\x01\x10LMT\x00ADT\x00AST\x00AWT\x00APT\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00" + + "\x05\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^=9\f\xff\xff\xff\xff\x9e\xb8\x85`\xff\xff\xff\xff\x9f\xba\xddP\xff\xff\xff\xffˈ\xe2`\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff" + + "\xff\xd2`\xed\xd0\x02\x01\x02\x03\x04\x02\xff\xff\xcat\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xd5\xd0\x01\x10LMT\x00ADT\x00AST\x00AWT\x00APT" + + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa9K%7H\x01\x00\x00H\x01\x00\x00\x0f\x00\x1c\x00America/Phoen" + + "ixUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\v\x00\x00\x00\x04\x00\x00\x00\x10\x80\x00\x00\x00\x9e\xa6:\x90\x9f\xbb\a\x80\xa0\x86\x1c\x90\xa1\x9a\xe9\x80ˉ\f\x90\xcf\x17\xdf\x1cϏ\xe5\xacЁ\x1a\x1c\xfa\xf8u\x10\xfb\xe8X\x00\x02\x01" + + "\x02\x01\x02\x03\x02\x03\x02\x01\x02\xff\xff\x96\xee\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\fLMT\x00MDT\x00MST\x00MWT\x00TZif2\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff" + + "\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xcf\x17\xdf\x1c\xff\xff\xff\xffϏ\xe5\xac\xff\xff\xff\xffЁ\x1a\x1c\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X" + + "\x00\x02\x01\x02\x01\x02\x03\x02\x03\x02\x01\x02\xff\xff\x96\xee\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\fLMT\x00MDT\x00MST\x00MWT\x00\nMST7\nPK" + + "\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPENO\xd9P\x01\x00\x00P\x01\x00\x00\x10\x00\x1c\x00America/AtikokanUT\t\x00\x03nӧ^nӧ^ux\v" + + "\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x06\x00\x00\x00\x18\x80\x00\x00\x00" + + "\x9e\xb8\xa1\x80\x9f\xba\xf9p\xc8\xf8W`ˈ\xfe\x80\xd2#\xf4p\xd2a\t\xf0\x02\x01\x02\x01\x03\x04\x05\xff\xff\xaa\x1c\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01" + + "\x10\xff\xff\xb9\xb0\x00\x14LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xffr\xee\x84d\xff\xff\xff\xff\x9e\xb8\xa1\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xc8\xf8W`\xff" + + "\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\x02\x01\x02\x01\x03\x04\x05\xff\xff\xaa\x1c\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10" + + "\xff\xff\xb9\xb0\x00\x14LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00\nEST5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F" + + "\x9cP(x\xa1\xf4\xc6\x00\x00\x00\xc6\x00\x00\x00\x0f\x00\x1c\x00America/CayenneUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00" + + "\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\f\x91\xf4+\x90\xfb\xc35\xc0\u007f\xff\xff\xff\x01\x02\x02" + + "\xff\xff\xce\xf0\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x00\bLMT\x00-04\x00-03\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x91\xf4+\x90\xff\xff\xff\xff\xfb\xc35\xc0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x02\xff\xff\xce\xf0\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x00\bL" + + "MT\x00-04\x00-03\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPv\x89Z\xa8V\a\x00\x00V\a\x00\x00\f\x00\x1c\x00America/Nuu" + + "kUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00" + + "\x00\x00\x00\x00v\x00\x00\x00\x05\x00\x00\x00\f\x9b\x80h\x00\x13M|P\x143\xfa\x90\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae" + + "\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf" + + "\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N" + + "\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]\xcc" + + "\x90d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<" + + "\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f" + + "\x90\u007f\xff\xff\xff\x01\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x02\xff\xffπ\x00\x00\xff\xff\xd5\xd0\x00\x04\xff\xff\xd5\xd0\x00\x04\xff\xff\xe3\xe0\x01\b\xff\xff\xe3\xe0\x01\bLMT\x00-03\x00-02\x00\x00\x00\x01\x01\x00\x00\x00\x01\x01\x00TZif3" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00v\x00\x00\x00\x05\x00\x00\x00\f\xff\xff\xff\xff\x9b\x80h\x00\x00\x00\x00\x00\x13M|P\x00\x00\x00\x00\x14" + + "3\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00" + + "\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"" + + "LT\x10\x00\x00\x00\x00#" + + "\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00" + + "\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L" + + "̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00" + + "\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z" + + "\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00" + + "\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h" + + "\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00" + + "\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v" + + "\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00" + + "\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\xff\xffπ\x00\x00\xff\xff\xd5\xd0\x00\x04\xff\xff\xd5\xd0\x00\x04\xff\xff\xe3\xe0\x01\b\xff\xff\xe3\xe0\x01\bLMT\x00-03\x00-" + + "02\x00\x00\x00\x01\x01\x00\x00\x00\x01\x01\x00\n<-03>3<-02>,M3.5.0/-2,M10.5.0/-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9c" + + "P\x95\"R\xd4&\t\x00\x00&\t\x00\x00\x14\x00\x1c\x00America/Santa_IsabelUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00" + + "\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x95\x00\x00\x00\x06\x00\x00\x00\x18\xa5\xb6\xf6\x80\xa9yOp\xaf\xf2|" + + "\xf0\xb6fdp\xb7\x1b\x10\x00\xb8\n\xf2\xf0\xcbꍀ\xd2#\xf4pҙ\xbap\xd7\x1bY\x00ؑ\xb4\xf0\xe2~K\x90\xe3IR\x90\xe4^-\x90\xe5)4\x90\xe6GJ\x10\xe7\x12Q\x10\xe8'," + + "\x10\xe8\xf23\x10\xea\a\x0e\x10\xea\xd2\x15\x10\xeb\xe6\xf0\x10\xec\xb1\xf7\x10\xed\xc6\xd2\x10\xee\x91\xd9\x10\v\u0be0\f\xd9\xcd\x10\r\xc0\x91\xa0\x0e\xb9\xaf\x10\x0f\xa9\xae \x10\x99\x91\x10\x11\x89\x90 \x12ys" + + "\x10\x13ir \x14YU\x10\x15IT \x1697\x10\x17)6 \x18\"S\x90\x19\t\x18 \x1a\x025\x90\x1a\xf24\xa0\x1b\xe2\x17\x90\x1c\xd2\x16\xa0\x1d\xc1\xf9\x90\x1e\xb1\xf8\xa0\x1f\xa1ې v+" + + " !\x81\xbd\x90\"V\r #j\xda\x10$5\xef %J\xbc\x10&\x15\xd1 '*\x9e\x10'\xfe\xed\xa0)\n\x80\x10)\xdeϠ*\xeab\x10+\xbe\xb1\xa0,\xd3~\x90-\x9e\x93\xa0.\xb3`" + + "\x90/~u\xa00\x93B\x901g\x92 2s$\x903Gt 4S\x06\x905'V 62\xe8\x907\a8 8\x1c\x05\x108\xe7\x1a 9\xfb\xe7\x10:\xc6\xfc ;\xdb\xc9\x10<\xb0\x18" + + "\xa0=\xbb\xab\x10>\x8f\xfa\xa0?\x9b\x8d\x10@oܠA\x84\xa9\x90BO\xbe\xa0Cd\x8b\x90D/\xa0\xa0EDm\x90F\x0f\x82\xa0G$O\x90G\xf8\x9f I\x041\x90I\u0601 J\xe4\x13" + + "\x90K\x9c\xb3\xa0L\xd6j\x90M|\x95\xa0N\xb6L\x90O\\w\xa0P\x96.\x90Q\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00" + + "\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00F\x0f\x82\xa0\x00\x00\x00\x00G$" + + "O\x90\x00\x00\x00\x00G\xf8\x9f \x00\x00\x00\x00I\x041\x90\x00\x00\x00\x00I\u0601 \x00\x00\x00\x00J\xe4\x13\x90\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00M|\x95\xa0\x00\x00" + + "\x00\x00N\xb6L\x90\x00\x00\x00\x00O\\w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q4\nPK\x03\x04\n\x00" + + "\x00\x00\x00\x00\xf5F\x9cP\xa1\xaah\x81\n\x06\x00\x00\n\x06\x00\x00\x16\x00\x1c\x00America/Bahia_BanderasUT\t\x00\x03nӧ^nӧ^u" + + "x\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\x00\x00\x00\a\x00\x00\x00\x18\xa5\xb6" + + "\xe8p\xaf\xf2n\xe0\xb6fV`\xb7C\xd2`\xb8\f6`\xb8\xfd\x86\xf0\xcb\xeaq`ؑ\xb4\xf0\x00\x00p\x801g\x84\x102s\x16\x803Gf\x104R\xf8\x805'H\x1062ڀ7\a" + + "*\x108\x1b\xf7\x008\xe7\f\x109\xfb\xd9\x00:\xf5\x12\x90;\xb6\xd1\x00<\xb0\n\x90=\xbb\x9d\x00>\x8f\xec\x90?\x9b\u007f\x00@oΐA\x84\x9b\x80BO\xb0\x90Cd}\x80D/\x92\x90ED" + + "_\x80F\x0ft\x90G$A\x80G\xf8\x91\x10I\x04#\x80I\xd8s\x10J\xe4\x05\x80K\xb8U\x10L\xcd\x13\xf0M\x98)\x00N\xac\xf5\xf0Ox\v\x00P\x8c\xd7\xf0Qa'\x80Rl\xb9\xf0SA" + + "\t\x80TL\x9b\xf0U \xeb\x80V,}\xf0W\x00̀X\x15\x9apXீY\xf5|pZ\xc0\x91\x80[\xd5^p\\\xa9\xae\x00]\xb5@p^\x89\x90\x00_\x95\"p`ir\x00a~" + + ">\xf0bIT\x00c^ \xf0d)6\x00e>\x02\xf0f\x12R\x80g\x1d\xe4\xf0g\xf24\x80h\xfd\xc6\xf0i\xd2\x16\x80jݨ\xf0k\xb1\xf8\x80l\xc6\xc5pm\x91ڀn\xa6\xa7poq" + + "\xbc\x80p\x86\x89pqZ\xd9\x00rfkps:\xbb\x00tFMpu\x1a\x9d\x00v/i\xf0v\xfa\u007f\x00x\x0fK\xf0x\xdaa\x00y\xef-\xf0z\xbaC\x00{\xcf\x0f\xf0|\xa3_\x80}\xae" + + "\xf1\xf0~\x83A\x80\u007f\x8e\xd3\xf0\x01\x02\x01\x02\x01\x02\x01\x03\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05" + + "\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\xff\xff\x9dT\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00" + + "\b\xff\xff\x8f\x80\x00\f\xff\xff\xab\xa0\x01\x10\xff\xff\xb9\xb0\x01\x14\xff\xff\xab\xa0\x00\bLMT\x00MST\x00CST\x00PST\x00MDT\x00CDT\x00TZif2\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\x00\x00\x00\a\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff" + + "\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xcb\xeaq`\xff\xff\xff\xffؑ\xb4\xf0\x00\x00\x00\x00\x00\x00p\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16" + + "\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00" + + "\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\u007f\x00\x00\x00\x00\x00@o\xce" + + "\x90\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80\x00\x00\x00" + + "\x00G\xf8\x91\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00\x00\x00\x00K\xb8U\x10\x00\x00\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00M\x98)\x00\x00\x00\x00\x00N\xac\xf5" + + "\xf0\x00\x00\x00\x00Ox\v\x00\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00Rl\xb9\xf0\x00\x00\x00\x00SA\t\x80\x00\x00\x00\x00TL\x9b\xf0\x00\x00\x00\x00U \xeb\x80\x00\x00\x00" + + "\x00V,}\xf0\x00\x00\x00\x00W\x00̀\x00\x00\x00\x00X\x15\x9ap\x00\x00\x00\x00Xீ\x00\x00\x00\x00Y\xf5|p\x00\x00\x00\x00Z\xc0\x91\x80\x00\x00\x00\x00[\xd5^p\x00\x00\x00\x00\\\xa9\xae" + + "\x00\x00\x00\x00\x00]\xb5@p\x00\x00\x00\x00^\x89\x90\x00\x00\x00\x00\x00_\x95\"p\x00\x00\x00\x00`ir\x00\x00\x00\x00\x00a~>\xf0\x00\x00\x00\x00bIT\x00\x00\x00\x00\x00c^ \xf0\x00\x00\x00" + + "\x00d)6\x00\x00\x00\x00\x00e>\x02\xf0\x00\x00\x00\x00f\x12R\x80\x00\x00\x00\x00g\x1d\xe4\xf0\x00\x00\x00\x00g\xf24\x80\x00\x00\x00\x00h\xfd\xc6\xf0\x00\x00\x00\x00i\xd2\x16\x80\x00\x00\x00\x00jݨ" + + "\xf0\x00\x00\x00\x00k\xb1\xf8\x80\x00\x00\x00\x00l\xc6\xc5p\x00\x00\x00\x00m\x91ڀ\x00\x00\x00\x00n\xa6\xa7p\x00\x00\x00\x00oq\xbc\x80\x00\x00\x00\x00p\x86\x89p\x00\x00\x00\x00qZ\xd9\x00\x00\x00\x00" + + "\x00rfkp\x00\x00\x00\x00s:\xbb\x00\x00\x00\x00\x00tFMp\x00\x00\x00\x00u\x1a\x9d\x00\x00\x00\x00\x00v/i\xf0\x00\x00\x00\x00v\xfa\u007f\x00\x00\x00\x00\x00x\x0fK\xf0\x00\x00\x00\x00x\xdaa" + + "\x00\x00\x00\x00\x00y\xef-\xf0\x00\x00\x00\x00z\xbaC\x00\x00\x00\x00\x00{\xcf\x0f\xf0\x00\x00\x00\x00|\xa3_\x80\x00\x00\x00\x00}\xae\xf1\xf0\x00\x00\x00\x00~\x83A\x80\x00\x00\x00\x00\u007f\x8e\xd3\xf0\x01\x02\x01" + + "\x02\x01\x02\x01\x03\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02" + + "\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\xff\xff\x9dT\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\x8f\x80\x00\f\xff\xff\xab\xa0\x01\x10" + + "\xff\xff\xb9\xb0\x01\x14\xff\xff\xab\xa0\x00\bLMT\x00MST\x00CST\x00PST\x00MDT\x00CDT\x00\nCST6CDT,M4.1.0,M10.5.0\n" + + "PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x1c\x00America/Indiana/UT\t\x00\x03nӧ^nӧ^u" + + "x\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPz\x9d\x031\x86\x05\x00\x00\x86\x05\x00\x00\x15\x00\x1c\x00America/Indiana/" + + "VevayUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00" + + "\a\x00\x00\x00\x00\x00\x00\x00Q\x00\x00\x00\a\x00\x00\x00\x1c\x80\x00\x00\x00\x9e\xa6,\x80\x9f\xba\xf9p\xa0\x86\x0e\x80\xa1\x9a\xdbpˈ\xfe\x80\xd2#\xf4p\xd2a\t\xf0\xe2~=\x80\xfe\xb8\x1c\xf0\xff\xa7\xff" + + "\xe0\x00\x97\xfe\xf0\x01\x87\xe1\xe0\x02w\xe0\xf0\x03p\xfe`\x04`\xfdp\x05P\xe0`D/vpEDC`E\xf3\xa8\xf0G-_\xe0Gӊ\xf0I\rA\xe0I\xb3l\xf0J\xed#\xe0K\x9c\x89" + + "pL\xd6@`M|kpN\xb6\"`O\\MpP\x96\x04`Q3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x9e4\xa4\x8b4\x04\x00\x004\x04\x00\x00\x19\x00\x1c\x00America/Argentina/Us" + + "huaiaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06\x00\x00\x00\x14\x80\x00\x00\x00\xa2\x92\x8f0\xb6{R@\xb7\x1aɰ\xb8\x1e\x8f@\xb8\xd4p0\xba\x17}\xc0\xba\xb5\xa3\xb0\xbb\xf8\xb1@\xbc\x96\xd70\xbd\xd9\xe4" + + "\xc0\xbex\n\xb0\xbf\xbb\x18@\xc0Z\x8f\xb0\xc1\x9d\x9d@\xc2;\xc30\xc3~\xd0\xc0\xc4\x1c\xf6\xb0\xc5`\x04@\xc5\xfe*0\xc7A7\xc0\xc7\xe0\xaf0ȁ\x94@\xcaM\xa1\xb0\xca\xee\x86\xc0\xceM\xff" + + "0ΰ\xed\xc0\xd3)5\xb0\xd4Cd\xc0\xf4=\b0\xf4\x9f\xf6\xc0\xf5\x05l0\xf62\x10@\xf6柰\xf8\x13C\xc0\xf8\xc7\xd30\xf9\xf4w@\xfa\xd36\xb0\xfb\xc35\xc0\xfc\xbcS0\xfd\xacR" + + "@\xfe\x9c50\xff\x8c4@\a\xa3J\xb0\b$o\xa0#\x94\xb5\xb0$\x10\x94\xa0%7\xf2\xb0%\xf0v\xa0'!\x0f0'\xd0X\xa0)\x00\xf10)\xb0:\xa0*\xe0\xd30+\x99W 7\xf6\xc6" + + "\xb08\xbf*\xb0@\xb9N0@\xd5\v\xc0Gw\t\xb0G\xdc\u007f \u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\x05\xff\xff\xbf\xf8\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5" + + "\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00" + + "\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb1\x88\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba" + + "\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff" + + "\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7" + + "\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff" + + "\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9" + + "\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00" + + "\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)" + + "\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xb9N0\x00\x00\x00\x00@\xd5\v\xc0\x00" + + "\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\u007f \x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\x05\xff\xff\xbf\xf8\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00" + + "\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xaa?b\xbe4\x04\x00\x004\x04\x00\x00\x1b\x00\x1c\x00A" + + "merica/Argentina/CatamarcaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06\x00\x00\x00\x14\x80\x00\x00\x00\xa2\x92\x8f0\xb6{R@\xb7\x1aɰ\xb8\x1e\x8f@\xb8\xd4" + + "p0\xba\x17}\xc0\xba\xb5\xa3\xb0\xbb\xf8\xb1@\xbc\x96\xd70\xbd\xd9\xe4\xc0\xbex\n\xb0\xbf\xbb\x18@\xc0Z\x8f\xb0\xc1\x9d\x9d@\xc2;\xc30\xc3~\xd0\xc0\xc4\x1c\xf6\xb0\xc5`\x04@\xc5\xfe*0\xc7A" + + "7\xc0\xc7\xe0\xaf0ȁ\x94@\xcaM\xa1\xb0\xca\xee\x86\xc0\xceM\xff0ΰ\xed\xc0\xd3)5\xb0\xd4Cd\xc0\xf4=\b0\xf4\x9f\xf6\xc0\xf5\x05l0\xf62\x10@\xf6柰\xf8\x13C\xc0\xf8\xc7" + + "\xd30\xf9\xf4w@\xfa\xd36\xb0\xfb\xc35\xc0\xfc\xbcS0\xfd\xacR@\xfe\x9c50\xff\x8c4@\a\xa3J\xb0\b$o\xa0#\x94\xb5\xb0$\x10\x94\xa0%7\xf2\xb0%\xf0v\xa0'!\x0f0'\xd0" + + "X\xa0)\x00\xff@)\xb0:\xa0*\xe0\xd30+\x99W 7\xf6ư8\xbf*\xb0@\xbb\xf10@\xd5\v\xc0Gw\t\xb0G\xdc\u007f \u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\x05\xff\xff\xc2T\x00\x00\xff\xff\xc3\xd0\x00\x04" + + "\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xaf,\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ" + + "\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff" + + "\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@" + + "\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff" + + "ΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰" + + "\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff" + + "\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0" + + "\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x00" + + "8\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\v\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\u007f \x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\x05\xff\xff\xc2T\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff" + + "\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00" + + "\xf5F\x9cP\xaa?b\xbe4\x04\x00\x004\x04\x00\x00 \x00\x1c\x00America/Argentina/ComodRivadaviaUT\t\x00\x03nӧ" + + "^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06" + + "\x00\x00\x00\x14\x80\x00\x00\x00\xa2\x92\x8f0\xb6{R@\xb7\x1aɰ\xb8\x1e\x8f@\xb8\xd4p0\xba\x17}\xc0\xba\xb5\xa3\xb0\xbb\xf8\xb1@\xbc\x96\xd70\xbd\xd9\xe4\xc0\xbex\n\xb0\xbf\xbb\x18@\xc0Z\x8f\xb0" + + "\xc1\x9d\x9d@\xc2;\xc30\xc3~\xd0\xc0\xc4\x1c\xf6\xb0\xc5`\x04@\xc5\xfe*0\xc7A7\xc0\xc7\xe0\xaf0ȁ\x94@\xcaM\xa1\xb0\xca\xee\x86\xc0\xceM\xff0ΰ\xed\xc0\xd3)5\xb0\xd4Cd\xc0" + + "\xf4=\b0\xf4\x9f\xf6\xc0\xf5\x05l0\xf62\x10@\xf6柰\xf8\x13C\xc0\xf8\xc7\xd30\xf9\xf4w@\xfa\xd36\xb0\xfb\xc35\xc0\xfc\xbcS0\xfd\xacR@\xfe\x9c50\xff\x8c4@\a\xa3J\xb0" + + "\b$o\xa0#\x94\xb5\xb0$\x10\x94\xa0%7\xf2\xb0%\xf0v\xa0'!\x0f0'\xd0X\xa0)\x00\xff@)\xb0:\xa0*\xe0\xd30+\x99W 7\xf6ư8\xbf*\xb0@\xbb\xf10@\xd5\v\xc0" + + "Gw\t\xb0G\xdc\u007f \u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x02\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\x05\xff\xff\xc2T\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-0" + + "4\x00-03\x00-02\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c" + + "\xaf,\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff" + + "\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;" + + "\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff" + + "\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f" + + "\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff" + + "\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94" + + "\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00" + + "\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\v\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc" + + "\u007f \x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x02\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\x05\xff\xff\xc2T\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00" + + "-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xac\xa8\x1a\x9aB\x04\x00\x00B\x04\x00\x00\x1a\x00\x1c\x00America/Argent" + + "ina/San_JuanUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\x00\x00\x00\x06\x00\x00\x00\x14\x80\x00\x00\x00\xa2\x92\x8f0\xb6{R@\xb7\x1aɰ\xb8\x1e\x8f@\xb8\xd4p0\xba\x17}\xc0\xba\xb5\xa3\xb0\xbb\xf8\xb1@" + + "\xbc\x96\xd70\xbd\xd9\xe4\xc0\xbex\n\xb0\xbf\xbb\x18@\xc0Z\x8f\xb0\xc1\x9d\x9d@\xc2;\xc30\xc3~\xd0\xc0\xc4\x1c\xf6\xb0\xc5`\x04@\xc5\xfe*0\xc7A7\xc0\xc7\xe0\xaf0ȁ\x94@\xcaM\xa1\xb0" + + "\xca\xee\x86\xc0\xceM\xff0ΰ\xed\xc0\xd3)5\xb0\xd4Cd\xc0\xf4=\b0\xf4\x9f\xf6\xc0\xf5\x05l0\xf62\x10@\xf6柰\xf8\x13C\xc0\xf8\xc7\xd30\xf9\xf4w@\xfa\xd36\xb0\xfb\xc35\xc0" + + "\xfc\xbcS0\xfd\xacR@\xfe\x9c50\xff\x8c4@\a\xa3J\xb0\b$o\xa0#\x94\xb5\xb0$\x10\x94\xa0%7\xf2\xb0%\xf0v\xa0'!\x0f0'͵\xa0(&&@)\x00\xf10)\xb0:\xa0" + + "*\xe0\xd30+\x99W 7\xf6ư8\xbf*\xb0@\xba\x9f\xb0A\x030@Gw\t\xb0G\xdc\u007f \u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x05\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\x05\xff\xff\xbf\xc4\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5" + + "\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb1\xbc\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff" + + "\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf" + + "\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff" + + "\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3" + + ")5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff" + + "\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff" + + "\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00" + + "\x00\x00\x00'͵\xa0\x00\x00\x00\x00(&&@\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008" + + "\xbf*\xb0\x00\x00\x00\x00@\xba\x9f\xb0\x00\x00\x00\x00A\x030@\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\u007f \x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x05\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\x05\xff\xff\xbf\xc4\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff" + + "\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00" + + "\xf5F\x9cPGB\xad\x0fN\x04\x00\x00N\x04\x00\x00\x1a\x00\x1c\x00America/Argentina/San_LuisUT\t\x00\x03nӧ^nӧ^u" + + "x\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\x00\x00\x00\a\x00\x00\x00\x14\x80\x00" + + "\x00\x00\xa2\x92\x8f0\xb6{R@\xb7\x1aɰ\xb8\x1e\x8f@\xb8\xd4p0\xba\x17}\xc0\xba\xb5\xa3\xb0\xbb\xf8\xb1@\xbc\x96\xd70\xbd\xd9\xe4\xc0\xbex\n\xb0\xbf\xbb\x18@\xc0Z\x8f\xb0\xc1\x9d\x9d@\xc2;" + + "\xc30\xc3~\xd0\xc0\xc4\x1c\xf6\xb0\xc5`\x04@\xc5\xfe*0\xc7A7\xc0\xc7\xe0\xaf0ȁ\x94@\xcaM\xa1\xb0\xca\xee\x86\xc0\xceM\xff0ΰ\xed\xc0\xd3)5\xb0\xd4Cd\xc0\xf4=\b0\xf4\x9f" + + "\xf6\xc0\xf5\x05l0\xf62\x10@\xf6柰\xf8\x13C\xc0\xf8\xc7\xd30\xf9\xf4w@\xfa\xd36\xb0\xfb\xc35\xc0\xfc\xbcS0\xfd\xacR@\xfe\x9c50\xff\x8c4@\a\xa3J\xb0\b$o\xa0#\x94" + + "\xb5\xb0$\x10\x94\xa0%7\xf2\xb0%\xfd\xa5\xa0'\x194@'\xcdð(G\x1b\xc07\xf6ư8\xbf*\xb0@\xba\x9f\xb0A\x030@Gw\t\xb0G\x93\xfc\xa0G\xd3R\xb0H\xf1v@I\xb3" + + "4\xb0J\xd1X@\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03" + + "\x02\x05\x03\x05\x02\x05\x04\x03\x02\x03\x02\x05\x05\xff\xff\xc1\xcc\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\f\xff\xff\xd5\xd0\x01\fLMT\x00C" + + "MT\x00-04\x00-03\x00-02\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\x00\x00\x00\a\x00\x00\x00\x14\xff" + + "\xff\xff\xffr\x9c\xaf\xb4\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba" + + "\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff" + + "\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff\xc8" + + "\x81\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff" + + "\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa" + + "\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00" + + "\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xfd\xa5\xa0\x00\x00\x00\x00'\x194@\x00\x00\x00\x00'\xcdð\x00\x00\x00\x00(G\x1b\xc0\x00\x00\x00\x007" + + "\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xba\x9f\xb0\x00\x00\x00\x00A\x030@\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\x93\xfc\xa0\x00\x00\x00\x00G\xd3R\xb0\x00\x00\x00\x00H\xf1v@\x00" + + "\x00\x00\x00I\xb34\xb0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x05\x03\x05\x02\x05\x04\x03\x02\x03\x02\x05\x05\xff\xff\xc1\xcc\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0" + + "\x00\f\xff\xff\xd5\xd0\x01\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPQy\xf3\n4\x04\x00\x004\x04" + + "\x00\x00\x1e\x00\x1c\x00America/Argentina/Rio_GallegosUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04" + + "\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06\x00\x00\x00\x14\x80\x00\x00\x00\xa2\x92\x8f0\xb6{R@" + + "\xb7\x1aɰ\xb8\x1e\x8f@\xb8\xd4p0\xba\x17}\xc0\xba\xb5\xa3\xb0\xbb\xf8\xb1@\xbc\x96\xd70\xbd\xd9\xe4\xc0\xbex\n\xb0\xbf\xbb\x18@\xc0Z\x8f\xb0\xc1\x9d\x9d@\xc2;\xc30\xc3~\xd0\xc0\xc4\x1c\xf6\xb0" + + "\xc5`\x04@\xc5\xfe*0\xc7A7\xc0\xc7\xe0\xaf0ȁ\x94@\xcaM\xa1\xb0\xca\xee\x86\xc0\xceM\xff0ΰ\xed\xc0\xd3)5\xb0\xd4Cd\xc0\xf4=\b0\xf4\x9f\xf6\xc0\xf5\x05l0\xf62\x10@" + + "\xf6柰\xf8\x13C\xc0\xf8\xc7\xd30\xf9\xf4w@\xfa\xd36\xb0\xfb\xc35\xc0\xfc\xbcS0\xfd\xacR@\xfe\x9c50\xff\x8c4@\a\xa3J\xb0\b$o\xa0#\x94\xb5\xb0$\x10\x94\xa0%7\xf2\xb0" + + "%\xf0v\xa0'!\x0f0'\xd0X\xa0)\x00\xf10)\xb0:\xa0*\xe0\xd30+\x99W 7\xf6ư8\xbf*\xb0@\xbb\xf10@\xd5\v\xc0Gw\t\xb0G\xdc\u007f \u007f\xff\xff\xff\x01\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\x05\xff\xff" + + "\xbf\x1c\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00TZif2\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb2d\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{" + + "R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff" + + "\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c" + + "\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff" + + "\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62" + + "\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff" + + "\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7" + + "\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00" + + "\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\v\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\u007f \x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\x05\xff\xff\xbf\x1c" + + "\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\n" + + "PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf5\"\xa0\xdf\x18\x04\x00\x00\x18\x04\x00\x00\x17\x00\x1c\x00America/Argentina/JujuyUT\t\x00\x03n\xd3" + + "\xa7^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00" + + "\x06\x00\x00\x00\x14\x80\x00\x00\x00\xa2\x92\x8f0\xb6{R@\xb7\x1aɰ\xb8\x1e\x8f@\xb8\xd4p0\xba\x17}\xc0\xba\xb5\xa3\xb0\xbb\xf8\xb1@\xbc\x96\xd70\xbd\xd9\xe4\xc0\xbex\n\xb0\xbf\xbb\x18@\xc0Z\x8f" + + "\xb0\xc1\x9d\x9d@\xc2;\xc30\xc3~\xd0\xc0\xc4\x1c\xf6\xb0\xc5`\x04@\xc5\xfe*0\xc7A7\xc0\xc7\xe0\xaf0ȁ\x94@\xcaM\xa1\xb0\xca\xee\x86\xc0\xceM\xff0ΰ\xed\xc0\xd3)5\xb0\xd4Cd" + + "\xc0\xf4=\b0\xf4\x9f\xf6\xc0\xf5\x05l0\xf62\x10@\xf6柰\xf8\x13C\xc0\xf8\xc7\xd30\xf9\xf4w@\xfa\xd36\xb0\xfb\xc35\xc0\xfc\xbcS0\xfd\xacR@\xfe\x9c50\xff\x8c4@\a\xa3J" + + "\xb0\b$o\xa0#\x94\xb5\xb0$\x10\x94\xa0%7\xf2\xb0%\xf0v\xa0'*W\xc0'\xe2۰(\xee\x8a@)\xb0:\xa0*\xe0\xd30+\x99W 7\xf6ư8\xbf*\xb0Gw\t\xb0G\xdc\u007f" + + " \u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x04\x05\x04\x05" + + "\x03\x05\x04\x05\x05\xff\xff\xc2\xc8\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02" + + "\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xae\xb8\xff\xff\xff\xff\xa2\x92\x8f" + + "0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff" + + "\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0" + + "\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff" + + "\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l" + + "0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff" + + "\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94" + + "\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'*W\xc0\x00\x00\x00\x00'\xe2۰\x00\x00\x00\x00(\xee\x8a@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00" + + "\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\u007f \x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x04\x05\x04\x05\x03\x05\x04\x05\x05\xff\xff\xc2\xc8\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7" + + "\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5" + + "F\x9cPqr%\xd5P\x04\x00\x00P\x04\x00\x00\x19\x00\x1c\x00America/Argentina/TucumanUT\t\x00\x03nӧ^nӧ^ux\v" + + "\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x06\x00\x00\x00\x14\x80\x00\x00\x00" + + "\xa2\x92\x8f0\xb6{R@\xb7\x1aɰ\xb8\x1e\x8f@\xb8\xd4p0\xba\x17}\xc0\xba\xb5\xa3\xb0\xbb\xf8\xb1@\xbc\x96\xd70\xbd\xd9\xe4\xc0\xbex\n\xb0\xbf\xbb\x18@\xc0Z\x8f\xb0\xc1\x9d\x9d@\xc2;\xc30" + + "\xc3~\xd0\xc0\xc4\x1c\xf6\xb0\xc5`\x04@\xc5\xfe*0\xc7A7\xc0\xc7\xe0\xaf0ȁ\x94@\xcaM\xa1\xb0\xca\xee\x86\xc0\xceM\xff0ΰ\xed\xc0\xd3)5\xb0\xd4Cd\xc0\xf4=\b0\xf4\x9f\xf6\xc0" + + "\xf5\x05l0\xf62\x10@\xf6柰\xf8\x13C\xc0\xf8\xc7\xd30\xf9\xf4w@\xfa\xd36\xb0\xfb\xc35\xc0\xfc\xbcS0\xfd\xacR@\xfe\x9c50\xff\x8c4@\a\xa3J\xb0\b$o\xa0#\x94\xb5\xb0" + + "$\x10\x94\xa0%7\xf2\xb0%\xf0v\xa0'!\x0f0'\xd0X\xa0)\x00\xff@)\xb0:\xa0*\xe0\xd30+\x99W 7\xf6ư8\xbf*\xb0@\xbb\xf10@\xcb\xd1@Gw\t\xb0G\xdc\u007f " + + "H\xfa\xa2\xb0I\xbca \u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x02\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\x04\x05\x05\xff\xff\xc2\xdc\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00" + + "-04\x00-03\x00-02\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xff" + + "r\x9c\xae\xa4\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0" + + "\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff" + + "\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@" + + "\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff" + + "\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0" + + "\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00" + + "#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0" + + "\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xcb\xd1@\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00" + + "G\xdc\u007f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\x04\x05\x05\xff\xff\xc2\xdc\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0" + + "\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\t)<\xb24\x04\x00\x004\x04" + + "\x00\x00\x1e\x00\x1c\x00America/Argentina/Buenos_AiresUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04" + + "\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06\x00\x00\x00\x14\x80\x00\x00\x00\xa2\x92\x8f0\xb6{R@" + + "\xb7\x1aɰ\xb8\x1e\x8f@\xb8\xd4p0\xba\x17}\xc0\xba\xb5\xa3\xb0\xbb\xf8\xb1@\xbc\x96\xd70\xbd\xd9\xe4\xc0\xbex\n\xb0\xbf\xbb\x18@\xc0Z\x8f\xb0\xc1\x9d\x9d@\xc2;\xc30\xc3~\xd0\xc0\xc4\x1c\xf6\xb0" + + "\xc5`\x04@\xc5\xfe*0\xc7A7\xc0\xc7\xe0\xaf0ȁ\x94@\xcaM\xa1\xb0\xca\xee\x86\xc0\xceM\xff0ΰ\xed\xc0\xd3)5\xb0\xd4Cd\xc0\xf4=\b0\xf4\x9f\xf6\xc0\xf5\x05l0\xf62\x10@" + + "\xf6柰\xf8\x13C\xc0\xf8\xc7\xd30\xf9\xf4w@\xfa\xd36\xb0\xfb\xc35\xc0\xfc\xbcS0\xfd\xacR@\xfe\x9c50\xff\x8c4@\a\xa3J\xb0\b$o\xa0#\x94\xb5\xb0$\x10\x94\xa0%7\xf2\xb0" + + "%\xf0v\xa0'!\x0f0'\xd0X\xa0)\x00\xf10)\xb0:\xa0*\xe0\xd30+\x99W 7\xf6ư8\xbf*\xb0Gw\t\xb0G\xdc\u007f H\xfa\xa2\xb0I\xbca \u007f\xff\xff\xff\x01\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\x05\xff\xff" + + "\xc94\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00TZif2\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xa8L\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{" + + "R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff" + + "\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c" + + "\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff" + + "\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62" + + "\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff" + + "\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7" + + "\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00" + + "\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\u007f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\x05\xff\xff\xc94" + + "\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\n" + + "PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb6\xb1\xfb\x104\x04\x00\x004\x04\x00\x00\x19\x00\x1c\x00America/Argentina/CordobaUT\t\x00\x03" + + "nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00" + + "\x00\x00\x06\x00\x00\x00\x14\x80\x00\x00\x00\xa2\x92\x8f0\xb6{R@\xb7\x1aɰ\xb8\x1e\x8f@\xb8\xd4p0\xba\x17}\xc0\xba\xb5\xa3\xb0\xbb\xf8\xb1@\xbc\x96\xd70\xbd\xd9\xe4\xc0\xbex\n\xb0\xbf\xbb\x18@\xc0" + + "Z\x8f\xb0\xc1\x9d\x9d@\xc2;\xc30\xc3~\xd0\xc0\xc4\x1c\xf6\xb0\xc5`\x04@\xc5\xfe*0\xc7A7\xc0\xc7\xe0\xaf0ȁ\x94@\xcaM\xa1\xb0\xca\xee\x86\xc0\xceM\xff0ΰ\xed\xc0\xd3)5\xb0\xd4" + + "Cd\xc0\xf4=\b0\xf4\x9f\xf6\xc0\xf5\x05l0\xf62\x10@\xf6柰\xf8\x13C\xc0\xf8\xc7\xd30\xf9\xf4w@\xfa\xd36\xb0\xfb\xc35\xc0\xfc\xbcS0\xfd\xacR@\xfe\x9c50\xff\x8c4@\a" + + "\xa3J\xb0\b$o\xa0#\x94\xb5\xb0$\x10\x94\xa0%7\xf2\xb0%\xf0v\xa0'!\x0f0'\xd0X\xa0)\x00\xff@)\xb0:\xa0*\xe0\xd30+\x99W 7\xf6ư8\xbf*\xb0Gw\t\xb0G" + + "\xdc\u007f H\xfa\xa2\xb0I\xbca \u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\x05\xff\xff\xc3\xd0\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT" + + "\x00-04\x00-03\x00-02\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff" + + "\xffr\x9c\xad\xb0\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3" + + "\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff" + + "\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94" + + "@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff" + + "\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36" + + "\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00" + + "\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:" + + "\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\u007f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00" + + "\x00I\xbca \x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\x05\xff\xff\xc3\xd0\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-" + + "04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa1\xad\x99\x05B\x04\x00\x00B\x04\x00\x00\x1a\x00\x1c\x00America/Arg" + + "entina/La_RiojaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\x00\x00\x00\x06\x00\x00\x00\x14\x80\x00\x00\x00\xa2\x92\x8f0\xb6{R@\xb7\x1aɰ\xb8\x1e\x8f@\xb8\xd4p0\xba\x17}\xc0\xba\xb5\xa3\xb0\xbb" + + "\xf8\xb1@\xbc\x96\xd70\xbd\xd9\xe4\xc0\xbex\n\xb0\xbf\xbb\x18@\xc0Z\x8f\xb0\xc1\x9d\x9d@\xc2;\xc30\xc3~\xd0\xc0\xc4\x1c\xf6\xb0\xc5`\x04@\xc5\xfe*0\xc7A7\xc0\xc7\xe0\xaf0ȁ\x94@\xca" + + "M\xa1\xb0\xca\xee\x86\xc0\xceM\xff0ΰ\xed\xc0\xd3)5\xb0\xd4Cd\xc0\xf4=\b0\xf4\x9f\xf6\xc0\xf5\x05l0\xf62\x10@\xf6柰\xf8\x13C\xc0\xf8\xc7\xd30\xf9\xf4w@\xfa\xd36\xb0\xfb" + + "\xc35\xc0\xfc\xbcS0\xfd\xacR@\xfe\x9c50\xff\x8c4@\a\xa3J\xb0\b$o\xa0#\x94\xb5\xb0$\x10\x94\xa0%7\xf2\xb0%\xf0v\xa0'!\x0f0'͵\xa0(&&@)\x00\xf10)" + + "\xb0:\xa0*\xe0\xd30+\x99W 7\xf6ư8\xbf*\xb0@\xbb\xf10@\xd5\v\xc0Gw\t\xb0G\xdc\u007f \u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x05\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\x05\xff\xff\xc1T\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b" + + "\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb0,\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e" + + "\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff" + + "\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe" + + "*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff" + + "\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13" + + "C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff" + + "\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!" + + "\x0f0\x00\x00\x00\x00'͵\xa0\x00\x00\x00\x00(&&@\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00" + + "\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\v\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\u007f \x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x05\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\x05\xff\xff\xc1T\x00\x00\xff\xff\xc3\xd0\x00" + + "\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00" + + "\x00\x00\x00\xf5F\x9cP\x1a\xdb?\x854\x04\x00\x004\x04\x00\x00\x19\x00\x1c\x00America/Argentina/MendozaUT\t\x00\x03nӧ^nӧ" + + "^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06\x00\x00\x00\x14" + + "\x80\x00\x00\x00\xa2\x92\x8f0\xb6{R@\xb7\x1aɰ\xb8\x1e\x8f@\xb8\xd4p0\xba\x17}\xc0\xba\xb5\xa3\xb0\xbb\xf8\xb1@\xbc\x96\xd70\xbd\xd9\xe4\xc0\xbex\n\xb0\xbf\xbb\x18@\xc0Z\x8f\xb0\xc1\x9d\x9d@" + + "\xc2;\xc30\xc3~\xd0\xc0\xc4\x1c\xf6\xb0\xc5`\x04@\xc5\xfe*0\xc7A7\xc0\xc7\xe0\xaf0ȁ\x94@\xcaM\xa1\xb0\xca\xee\x86\xc0\xceM\xff0ΰ\xed\xc0\xd3)5\xb0\xd4Cd\xc0\xf4=\b0" + + "\xf4\x9f\xf6\xc0\xf5\x05l0\xf62\x10@\xf6柰\xf8\x13C\xc0\xf8\xc7\xd30\xf9\xf4w@\xfa\xd36\xb0\xfb\xc35\xc0\xfc\xbcS0\xfd\xacR@\xfe\x9c50\xff\x8c4@\a\xa3J\xb0\b$o\xa0" + + "#\x94\xb5\xb0$\x10\x94\xa0%7\xf2\xb0%\xf0v\xa0'\x194@'\xcdð(\xfag\xc0)\xb0H\xb0*\xe0\xe1@+\x99W 7\xf6ư8\xbf*\xb0@\xb0\x13\xb0AV>\xc0Gw\t\xb0" + + "G\xdc\u007f \u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x03" + + "\x02\x04\x05\x03\x05\x02\x05\x04\x05\x05\xff\xff\xbf|\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-0" + + "3\x00-02\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb2\x04\xff\xff" + + "\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8" + + "\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff" + + "\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM" + + "\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff" + + "\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc3" + + "5\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00" + + "\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'\x194@\x00\x00\x00\x00'\xcdð\x00\x00\x00\x00(\xfag\xc0\x00\x00\x00\x00)\xb0H\xb0\x00\x00\x00\x00*\xe0" + + "\xe1@\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xb0\x13\xb0\x00\x00\x00\x00AV>\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\u007f \x00\x00" + + "\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x03\x02\x04" + + "\x05\x03\x05\x02\x05\x04\x05\x05\xff\xff\xbf|\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00" + + "-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x0e\xacEg\xe8\x00\x00\x00\xe8\x00\x00\x00\x0e\x00\x1c\x00America/La_PazUT\t\x00" + + "\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04" + + "\x00\x00\x00\x04\x00\x00\x00\x10\x80\x00\x00\x00\xb8\x1e\x96\xe4\xb8\xee\xd5\xd4\u007f\xff\xff\xff\x01\x02\x03\x03\xff\xff\xc0\x1c\x00\x00\xff\xff\xc0\x1c\x00\x04\xff\xff\xce,\x01\b\xff\xff\xc7\xc0\x00\fLMT\x00CMT\x00" + + "BST\x00-04\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87\x1bd" + + "\xff\xff\xff\xff\xb8\x1e\x96\xe4\xff\xff\xff\xff\xb8\xee\xd5\xd4\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x03\xff\xff\xc0\x1c\x00\x00\xff\xff\xc0\x1c\x00\x04\xff\xff\xce,\x01\b\xff\xff\xc7\xc0\x00\fLMT\x00CMT\x00" + + "BST\x00-04\x00\n<-04>4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPЧ\x00\x94@\x06\x00\x00@\x06\x00\x00\x0e\x00\x1c\x00America/Dawson" + + "UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\t\x00\x00\x00\x00" + + "\x00\x00\x00\\\x00\x00\x00\t\x00\x00\x00%\x80\x00\x00\x00\x9e\xb8˰\x9f\xbb#\xa0\xa0\xd0\f\xb0\xa1\xa2Ҁˉ(\xb0\xd2#\xf4p\xd2a4 \xf7/v\x90\xf8(\xa2\x10\a0\xec\x90\x13ir " + + "\x14YU\x10\x15IT \x1697\x10\x17)6 \x18\"S\x90\x19\t\x18 \x1a\x025\x90\x1a\xf24\xa0\x1b\xe2\x17\x90\x1c\xd2\x16\xa0\x1d\xc1\xf9\x90\x1e\xb1\xf8\xa0\x1f\xa1ې v+ !\x81\xbd\x90" + + "\"V\r #j\xda\x10$5\xef %J\xbc\x10&\x15\xd1 '*\x9e\x10'\xfe\xed\xa0)\n\x80\x10)\xdeϠ*\xeab\x10+\xbe\xb1\xa0,\xd3~\x90-\x9e\x93\xa0.\xb3`\x90/~u\xa0" + + "0\x93B\x901g\x92 2s$\x903Gt 4S\x06\x905'V 62\xe8\x907\a8 8\x1c\x05\x108\xe7\x1a 9\xfb\xe7\x10:\xc6\xfc ;\xdb\xc9\x10<\xb0\x18\xa0=\xbb\xab\x10" + + ">\x8f\xfa\xa0?\x9b\x8d\x10@oܠA\x84\xa9\x90BO\xbe\xa0Cd\x8b\x90D/\xa0\xa0EDm\x90E\xf3\xd3 G-\x8a\x10Gӵ I\rl\x10I\xb3\x97 J\xedN\x10K\x9c\xb3\xa0" + + "L\xd6j\x90M|\x95\xa0N\xb6L\x90O\\w\xa0P\x96.\x90Q\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00" + + "\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x00\x00\x00\x00G-\x8a\x10\x00\x00\x00\x00Gӵ \x00\x00\x00\x00I\rl\x10\x00\x00\x00\x00I\xb3\x97 \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3" + + "\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00M|\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\\w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q\x8f\xa6|?\x9b8\xec@o\x88|A\x84UlBOj|Cd7lD/L|ED\x19lE\xf3\x9a\xe0G-Q\xd0G\xd3|\xe0I\r3" + + "\xd0I\xb3^\xe0J\xed\x15\xd0K\x9c{`L\xd62PM|]`N\xb6\x14PO\\?`P\x95\xf6PQ\x8f\xa6|\x00\x00\x00\x00?\x9b8\xec\x00\x00\x00\x00@o\x88|\x00\x00\x00\x00" + + "A\x84Ul\x00\x00\x00\x00BOj|\x00\x00\x00\x00Cd7l\x00\x00\x00\x00D/L|\x00\x00\x00\x00ED\x19l\x00\x00\x00\x00E\xf3\x9a\xe0\x00\x00\x00\x00G-Q\xd0\x00\x00\x00\x00G\xd3|\xe0" + + "\x00\x00\x00\x00I\r3\xd0\x00\x00\x00\x00I\xb3^\xe0\x00\x00\x00\x00J\xed\x15\xd0\x00\x00\x00\x00K\x9c{`\x00\x00\x00\x00L\xd62P\x00\x00\x00\x00M|]`\x00\x00\x00\x00N\xb6\x14P\x00\x00\x00\x00" + + "O\\?`\x00\x00\x00\x00P\x95\xf6P\x00\x00\x00\x00Q\x8fހ?\x9bp\xf0@o\xc0\x80A\x84\x8dpBO\xa2\x80CdopD/\x84\x80EDQpF\x0ff\x80G$3pG\xf8\x83\x00I\x04\x15pI\xd8e\x00J\xe3\xf7pK\x9c" + + "\x97\x80L\xd6NpM|y\x80N\xb60pO\\[\x80P\x96\x12pQ<=\x80Ru\xf4pS\x1c\x1f\x80TU\xd6pT\xfc\x01\x80V5\xb8pV\xe5\x1e\x00X\x1e\xd4\xf0X\xc5\x00\x00Y\xfe" + + "\xb6\xf0Z\xa4\xe2\x00[ޘ\xf0\\\x84\xc4\x00]\xbez\xf0^d\xa6\x00_\x9e\\\xf0`M\u0080a\x87ypb-\xa4\x80cg[pd\r\x86\x80eG=pe\xedh\x80g'\x1fpg\xcd" + + "J\x80i\a\x01pi\xad,\x80j\xe6\xe3pk\x96I\x00l\xcf\xff\xf0mv+\x00n\xaf\xe1\xf0oV\r\x00p\x8f\xc3\xf0q5\xef\x00ro\xa5\xf0s\x15\xd1\x00tO\x87\xf0t\xfe\xed\x80v8" + + "\xa4pv\xdeπx\x18\x86px\xbe\xb1\x80y\xf8hpz\x9e\x93\x80{\xd8Jp|~u\x80}\xb8,p~^W\x80\u007f\x98\x0ep\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xa2@\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x01\bLMT\x00CST\x00CDT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00W\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xa5\xb6\xda`\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002" + + "s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00" + + "\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@" + + "o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00F\x0ff\x80\x00\x00\x00\x00G$3p\x00" + + "\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00K\x9c\x97\x80\x00\x00\x00\x00L\xd6Np\x00\x00\x00\x00M|y\x80\x00\x00\x00\x00N" + + "\xb60p\x00\x00\x00\x00O\\[\x80\x00\x00\x00\x00P\x96\x12p\x00\x00\x00\x00Q<=\x80\x00\x00\x00\x00Ru\xf4p\x00\x00\x00\x00S\x1c\x1f\x80\x00\x00\x00\x00TU\xd6p\x00\x00\x00\x00T\xfc\x01\x80\x00" + + "\x00\x00\x00V5\xb8p\x00\x00\x00\x00V\xe5\x1e\x00\x00\x00\x00\x00X\x1e\xd4\xf0\x00\x00\x00\x00X\xc5\x00\x00\x00\x00\x00\x00Y\xfe\xb6\xf0\x00\x00\x00\x00Z\xa4\xe2\x00\x00\x00\x00\x00[ޘ\xf0\x00\x00\x00\x00\\" + + "\x84\xc4\x00\x00\x00\x00\x00]\xbez\xf0\x00\x00\x00\x00^d\xa6\x00\x00\x00\x00\x00_\x9e\\\xf0\x00\x00\x00\x00`M\u0080\x00\x00\x00\x00a\x87yp\x00\x00\x00\x00b-\xa4\x80\x00\x00\x00\x00cg[p\x00" + + "\x00\x00\x00d\r\x86\x80\x00\x00\x00\x00eG=p\x00\x00\x00\x00e\xedh\x80\x00\x00\x00\x00g'\x1fp\x00\x00\x00\x00g\xcdJ\x80\x00\x00\x00\x00i\a\x01p\x00\x00\x00\x00i\xad,\x80\x00\x00\x00\x00j" + + "\xe6\xe3p\x00\x00\x00\x00k\x96I\x00\x00\x00\x00\x00l\xcf\xff\xf0\x00\x00\x00\x00mv+\x00\x00\x00\x00\x00n\xaf\xe1\xf0\x00\x00\x00\x00oV\r\x00\x00\x00\x00\x00p\x8f\xc3\xf0\x00\x00\x00\x00q5\xef\x00\x00" + + "\x00\x00\x00ro\xa5\xf0\x00\x00\x00\x00s\x15\xd1\x00\x00\x00\x00\x00tO\x87\xf0\x00\x00\x00\x00t\xfe\xed\x80\x00\x00\x00\x00v8\xa4p\x00\x00\x00\x00v\xdeπ\x00\x00\x00\x00x\x18\x86p\x00\x00\x00\x00x" + + "\xbe\xb1\x80\x00\x00\x00\x00y\xf8hp\x00\x00\x00\x00z\x9e\x93\x80\x00\x00\x00\x00{\xd8Jp\x00\x00\x00\x00|~u\x80\x00\x00\x00\x00}\xb8,p\x00\x00\x00\x00~^W\x80\x00\x00\x00\x00\u007f\x98\x0ep\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xa2@\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x01\bLMT\x00CST\x00CDT\x00\nCST" + + "6CDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xcf|3(\x94\x00\x00\x00\x94\x00\x00\x00\x12\x00\x1c\x00America/St" + + "_VincentUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\x9373\xac\x01\xff\xff\xc6T\x00\x00\xff\xff\xc7\xc0\x00\x04LMT\x00AST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x9373\xac\x01\xff\xff\xc6T\x00\x00\xff\xff\xc7\xc0\x00\x04LMT\x00AST\x00\nA" + + "ST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xd2k\xc2\xda\xd4\x03\x00\x00\xd4\x03\x00\x00\x0e\x00\x1c\x00America/ReginaUT\t\x00\x03nӧ^nӧ" + + "^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00\x06\x00\x00\x00\x18" + + "\x86\xfd\x93\x1c\x9e\xb8\xaf\x90\x9f\xbb\a\x80\xb5eO\xf0\xb60H\xe0\xb7E1\xf0\xb8\x10*\xe0\xb9%\x13\xf0\xb9\xf0\f\xe0\xbb\x0e0p\xbb\xcf\xee\xe0\xbc\xee\x12p\xbd\xb9\v`\xc2r\b\xf0\xc3a\xeb\xe0" + + "\xc4Q\xea\xf0\xc58\x93`\xc61\xcc\xf0\xc7!\xaf\xe0\xc8\x1a\xe9p\xc9\n\xcc`\xc9\xfa\xcbp\xca\xea\xae`ˉ\f\x90\xd2#\xf4p\xd2a\x18\x00\xd3c\x8c\x10\xd4So\x00\xd5U\xe3\x10\xd6 \xdc\x00" + + "\xd75\xc5\x10\xd8\x00\xbe\x00\xd9\x15\xa7\x10\xd9\xe0\xa0\x00\xda\xfeÐ\xdb\xc0\x82\x00\xdcޥ\x90ݩ\x9e\x80\u07be\x87\x90߉\x80\x80\xe0\x9ei\x90\xe1ib\x80\xe2~K\x90\xe3ID\x80\xe4^-\x90" + + "\xe5)&\x80\xe6GJ\x10\xe7\x12C\x00\xe8',\x10\xe8\xf2%\x00\xeb\xe6\xf0\x10\xec\xd6\xd3\x00\xed\xc6\xd2\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\xff\xff\x9d\xe4\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xab\xa0\x00" + + "\x14LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CST\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\x86\xfd\x93\x1c\xff\xff\xff\xff\x9e\xb8\xaf\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xb5eO\xf0\xff\xff\xff\xff\xb60H" + + "\xe0\xff\xff\xff\xff\xb7E1\xf0\xff\xff\xff\xff\xb8\x10*\xe0\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xf0\f\xe0\xff\xff\xff\xff\xbb\x0e0p\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xee\x12p\xff\xff\xff" + + "\xff\xbd\xb9\v`\xff\xff\xff\xff\xc2r\b\xf0\xff\xff\xff\xff\xc3a\xeb\xe0\xff\xff\xff\xff\xc4Q\xea\xf0\xff\xff\xff\xff\xc58\x93`\xff\xff\xff\xff\xc61\xcc\xf0\xff\xff\xff\xff\xc7!\xaf\xe0\xff\xff\xff\xff\xc8\x1a\xe9" + + "p\xff\xff\xff\xff\xc9\n\xcc`\xff\xff\xff\xff\xc9\xfa\xcbp\xff\xff\xff\xff\xca\xea\xae`\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xd3c\x8c\x10\xff\xff\xff" + + "\xff\xd4So\x00\xff\xff\xff\xff\xd5U\xe3\x10\xff\xff\xff\xff\xd6 \xdc\x00\xff\xff\xff\xff\xd75\xc5\x10\xff\xff\xff\xff\xd8\x00\xbe\x00\xff\xff\xff\xff\xd9\x15\xa7\x10\xff\xff\xff\xff\xd9\xe0\xa0\x00\xff\xff\xff\xff\xda\xfe\xc3" + + "\x90\xff\xff\xff\xff\xdb\xc0\x82\x00\xff\xff\xff\xff\xdcޥ\x90\xff\xff\xff\xffݩ\x9e\x80\xff\xff\xff\xff\u07be\x87\x90\xff\xff\xff\xff߉\x80\x80\xff\xff\xff\xff\xe0\x9ei\x90\xff\xff\xff\xff\xe1ib\x80\xff\xff\xff" + + "\xff\xe2~K\x90\xff\xff\xff\xff\xe3ID\x80\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)&\x80\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12C\x00\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf2%" + + "\x00\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xd6\xd3\x00\xff\xff\xff\xff\xed\xc6\xd2\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\xff\xff\x9d\xe4\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xab\xa0\x00\x14LMT\x00MD" + + "T\x00MST\x00MWT\x00MPT\x00CST\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00\nCST6\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa0\xea\xacW\xae\a\x00\x00\xae\a" + + "\x00\x00\x13\x00\x1c\x00America/YellowknifeUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00z\x00\x00\x00\x06\x00\x00\x00\x19\xbe*\x18\x00ˉ\f\x90\xd2#\xf4p\xd2a\x18\x00\xf7/Zp\xf8(\x85" + + "\xf0\x13id\x10\x14YG\x00\x15IF\x10\x169)\x00\x17)(\x10\x18\"E\x80\x19\t\n\x10\x1a\x02'\x80\x1a\xf2&\x90\x1b\xe2\t\x80\x1c\xd2\b\x90\x1d\xc1\xeb\x80\x1e\xb1\xea\x90\x1f\xa1̀ v\x1d" + + "\x10!\x81\xaf\x80\"U\xff\x10#j\xcc\x00$5\xe1\x10%J\xae\x00&\x15\xc3\x10'*\x90\x00'\xfeߐ)\nr\x00)\xde\xc1\x90*\xeaT\x00+\xbe\xa3\x90,\xd3p\x80-\x9e\x85\x90.\xb3R" + + "\x80/~g\x900\x934\x801g\x84\x102s\x16\x803Gf\x104R\xf8\x805'H\x1062ڀ7\a*\x108\x1b\xf7\x008\xe7\f\x109\xfb\xd9\x00:\xc6\xee\x10;ۻ\x00<\xb0\n" + + "\x90=\xbb\x9d\x00>\x8f\xec\x90?\x9b\u007f\x00@oΐA\x84\x9b\x80BO\xb0\x90Cd}\x80D/\x92\x90ED_\x80E\xf3\xc5\x10G-|\x00Gӧ\x10I\r^\x00I\xb3\x89\x10J\xed@" + + "\x00K\x9c\xa5\x90L\xd6\\\x80M|\x87\x90N\xb6>\x80O\\i\x90P\x96 \x80Q\x8f\xec\x90\x00\x00\x00\x00?\x9b\u007f\x00\x00\x00\x00\x00" + + "@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x00\x00\x00\x00G-|\x00" + + "\x00\x00\x00\x00Gӧ\x10\x00\x00\x00\x00I\r^\x00\x00\x00\x00\x00I\xb3\x89\x10\x00\x00\x00\x00J\xed@\x00\x00\x00\x00\x00K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\\\x80\x00\x00\x00\x00M|\x87\x90\x00\x00\x00\x00" + + "N\xb6>\x80\x00\x00\x00\x00O\\i\x90\x00\x00\x00\x00P\x96 \x80\x00\x00\x00\x00Q\x8fހ?\x9bp\xf0@o\xc0\x80A\x84\x8dpBO\xa2\x80CdopD/\x84\x80EDQpE\xf3\xb7\x00G-m\xf0Gә\x00I\rO\xf0I\xb3{\x00J\xed1\xf0K\x9c\x97\x80" + + "L\xd6NpM|y\x80N\xb60pO\\[\x80P\x96\x12pQ<=\x80Ru\xf4pS\x1c\x1f\x80TU\xd6pT\xfc\x01\x80V5\xb8pV\xe5\x1e\x00X\x1e\xd4\xf0X\xc5\x00\x00Y\xfe\xb6\xf0" + + "Z\xa4\xe2\x00[ޘ\xf0\\\x84\xc4\x00]\xbez\xf0^d\xa6\x00_\x9e\\\xf0`M\u0080a\x87ypb-\xa4\x80cg[pd\r\x86\x80eG=pe\xedh\x80g'\x1fpg\xcdJ\x80" + + "i\a\x01pi\xad,\x80j\xe6\xe3pk\x96I\x00l\xcf\xff\xf0mv+\x00n\xaf\xe1\xf0oV\r\x00p\x8f\xc3\xf0q5\xef\x00ro\xa5\xf0s\x15\xd1\x00tO\x87\xf0t\xfe\xed\x80v8\xa4p" + + "v\xdeπx\x18\x86px\xbe\xb1\x80y\xf8hpz\x9e\x93\x80{\xd8Jp|~u\x80}\xb8,p~^W\x80\u007f\x98\x0ep\x02\x01\x02\x01\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xa7X\x00" + + "\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10LMT\x00CDT\x00CST\x00CWT\x00CPT\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01TZif2" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x87\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffr\xee\x87(\xff\xff\xff\xff\x9e\xb8\xa1\x80\xff\xff\xff\xff\x9f" + + "\xba\xf9p\xff\xff\xff\xff\xc8\xf8W`\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\x00\x00\x00\x00\b π\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\n\x00\xb1\x80\x00" + + "\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11" + + "\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00" + + "\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f" + + "\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00" + + "\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-" + + "\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00" + + "\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;" + + "۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00" + + "\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G-m\xf0\x00\x00\x00\x00Gә\x00\x00\x00\x00\x00I\rO\xf0\x00\x00\x00\x00I" + + "\xb3{\x00\x00\x00\x00\x00J\xed1\xf0\x00\x00\x00\x00K\x9c\x97\x80\x00\x00\x00\x00L\xd6Np\x00\x00\x00\x00M|y\x80\x00\x00\x00\x00N\xb60p\x00\x00\x00\x00O\\[\x80\x00\x00\x00\x00P\x96\x12p\x00" + + "\x00\x00\x00Q<=\x80\x00\x00\x00\x00Ru\xf4p\x00\x00\x00\x00S\x1c\x1f\x80\x00\x00\x00\x00TU\xd6p\x00\x00\x00\x00T\xfc\x01\x80\x00\x00\x00\x00V5\xb8p\x00\x00\x00\x00V\xe5\x1e\x00\x00\x00\x00\x00X" + + "\x1e\xd4\xf0\x00\x00\x00\x00X\xc5\x00\x00\x00\x00\x00\x00Y\xfe\xb6\xf0\x00\x00\x00\x00Z\xa4\xe2\x00\x00\x00\x00\x00[ޘ\xf0\x00\x00\x00\x00\\\x84\xc4\x00\x00\x00\x00\x00]\xbez\xf0\x00\x00\x00\x00^d\xa6\x00\x00" + + "\x00\x00\x00_\x9e\\\xf0\x00\x00\x00\x00`M\u0080\x00\x00\x00\x00a\x87yp\x00\x00\x00\x00b-\xa4\x80\x00\x00\x00\x00cg[p\x00\x00\x00\x00d\r\x86\x80\x00\x00\x00\x00eG=p\x00\x00\x00\x00e" + + "\xedh\x80\x00\x00\x00\x00g'\x1fp\x00\x00\x00\x00g\xcdJ\x80\x00\x00\x00\x00i\a\x01p\x00\x00\x00\x00i\xad,\x80\x00\x00\x00\x00j\xe6\xe3p\x00\x00\x00\x00k\x96I\x00\x00\x00\x00\x00l\xcf\xff\xf0\x00" + + "\x00\x00\x00mv+\x00\x00\x00\x00\x00n\xaf\xe1\xf0\x00\x00\x00\x00oV\r\x00\x00\x00\x00\x00p\x8f\xc3\xf0\x00\x00\x00\x00q5\xef\x00\x00\x00\x00\x00ro\xa5\xf0\x00\x00\x00\x00s\x15\xd1\x00\x00\x00\x00\x00t" + + "O\x87\xf0\x00\x00\x00\x00t\xfe\xed\x80\x00\x00\x00\x00v8\xa4p\x00\x00\x00\x00v\xdeπ\x00\x00\x00\x00x\x18\x86p\x00\x00\x00\x00x\xbe\xb1\x80\x00\x00\x00\x00y\xf8hp\x00\x00\x00\x00z\x9e\x93\x80\x00" + + "\x00\x00\x00{\xd8Jp\x00\x00\x00\x00|~u\x80\x00\x00\x00\x00}\xb8,p\x00\x00\x00\x00~^W\x80\x00\x00\x00\x00\u007f\x98\x0ep\x02\x01\x02\x01\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xa7X\x00\x00" + + "\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10LMT\x00CDT\x00CST\x00CWT\x00CPT\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\nCST6C" + + "DT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP#\x16\x92r\xba\x00\x00\x00\xba\x00\x00\x00\x12\x00\x1c\x00America/Kral" + + "endijkUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x0e\x93\x1e.#\xf6\x98\xecH\x01\x02\xff\xff\xbf]\x00\x00\xff\xff\xc0\xb8\x00\x04\xff\xff\xc7\xc0\x00\nLMT\x00-0430\x00AST\x00" + + "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xff\x93\x1e.#\xff\xff\xff\xff\xf6\x98\xecH" + + "\x01\x02\xff\xff\xbf]\x00\x00\xff\xff\xc0\xb8\x00\x04\xff\xff\xc7\xc0\x00\nLMT\x00-0430\x00AST\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP.m\x983n\x05" + + "\x00\x00n\x05\x00\x00\x11\x00\x1c\x00America/MonterreyUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00W\x00\x00\x00\x03\x00\x00\x00\f\xa5\xb6\xda`\"U\xf1\x00#j\xbd\xf01gv\x002s\bp3" + + "GX\x004R\xeap5':\x0062\xccp7\a\x1c\x008\x1b\xe8\xf08\xe6\xfe\x009\xfb\xca\xf0:\xf5\x04\x80;\xb6\xc2\xf0<\xaf\xfc\x80=\xbb\x8e\xf0>\x8fހ?\x9bp\xf0@o\xc0\x80A" + + "\x84\x8dpBO\xa2\x80CdopD/\x84\x80EDQpF\x0ff\x80G$3pG\xf8\x83\x00I\x04\x15pI\xd8e\x00J\xe3\xf7pK\xb8G\x00L\xcd\x13\xf0M\x98)\x00N\xac\xf5\xf0O" + + "x\v\x00P\x8c\xd7\xf0Qa'\x80Rl\xb9\xf0SA\t\x80TL\x9b\xf0U \xeb\x80V,}\xf0W\x00̀X\x15\x9apXீY\xf5|pZ\xc0\x91\x80[\xd5^p\\\xa9\xae\x00]" + + "\xb5@p^\x89\x90\x00_\x95\"p`ir\x00a~>\xf0bIT\x00c^ \xf0d)6\x00e>\x02\xf0f\x12R\x80g\x1d\xe4\xf0g\xf24\x80h\xfd\xc6\xf0i\xd2\x16\x80jݨ\xf0k" + + "\xb1\xf8\x80l\xc6\xc5pm\x91ڀn\xa6\xa7poq\xbc\x80p\x86\x89pqZ\xd9\x00rfkps:\xbb\x00tFMpu\x1a\x9d\x00v/i\xf0v\xfa\u007f\x00x\x0fK\xf0x\xdaa\x00y" + + "\xef-\xf0z\xbaC\x00{\xcf\x0f\xf0|\xa3_\x80}\xae\xf1\xf0~\x83A\x80\u007f\x8e\xd3\xf0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xa1\xf4\x00\x00" + + "\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x01\bLMT\x00CST\x00CDT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00W" + + "\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xa5\xb6\xda`\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x00" + + "4R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80" + + "\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00" + + "BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00F\x0ff\x80\x00\x00\x00\x00G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p" + + "\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00K\xb8G\x00\x00\x00\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00M\x98)\x00\x00\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00Ox\v\x00\x00\x00\x00\x00" + + "P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00Rl\xb9\xf0\x00\x00\x00\x00SA\t\x80\x00\x00\x00\x00TL\x9b\xf0\x00\x00\x00\x00U \xeb\x80\x00\x00\x00\x00V,}\xf0\x00\x00\x00\x00W\x00̀" + + "\x00\x00\x00\x00X\x15\x9ap\x00\x00\x00\x00Xீ\x00\x00\x00\x00Y\xf5|p\x00\x00\x00\x00Z\xc0\x91\x80\x00\x00\x00\x00[\xd5^p\x00\x00\x00\x00\\\xa9\xae\x00\x00\x00\x00\x00]\xb5@p\x00\x00\x00\x00" + + "^\x89\x90\x00\x00\x00\x00\x00_\x95\"p\x00\x00\x00\x00`ir\x00\x00\x00\x00\x00a~>\xf0\x00\x00\x00\x00bIT\x00\x00\x00\x00\x00c^ \xf0\x00\x00\x00\x00d)6\x00\x00\x00\x00\x00e>\x02\xf0" + + "\x00\x00\x00\x00f\x12R\x80\x00\x00\x00\x00g\x1d\xe4\xf0\x00\x00\x00\x00g\xf24\x80\x00\x00\x00\x00h\xfd\xc6\xf0\x00\x00\x00\x00i\xd2\x16\x80\x00\x00\x00\x00jݨ\xf0\x00\x00\x00\x00k\xb1\xf8\x80\x00\x00\x00\x00" + + "l\xc6\xc5p\x00\x00\x00\x00m\x91ڀ\x00\x00\x00\x00n\xa6\xa7p\x00\x00\x00\x00oq\xbc\x80\x00\x00\x00\x00p\x86\x89p\x00\x00\x00\x00qZ\xd9\x00\x00\x00\x00\x00rfkp\x00\x00\x00\x00s:\xbb\x00" + + "\x00\x00\x00\x00tFMp\x00\x00\x00\x00u\x1a\x9d\x00\x00\x00\x00\x00v/i\xf0\x00\x00\x00\x00v\xfa\u007f\x00\x00\x00\x00\x00x\x0fK\xf0\x00\x00\x00\x00x\xdaa\x00\x00\x00\x00\x00y\xef-\xf0\x00\x00\x00\x00" + + "z\xbaC\x00\x00\x00\x00\x00{\xcf\x0f\xf0\x00\x00\x00\x00|\xa3_\x80\x00\x00\x00\x00}\xae\xf1\xf0\x00\x00\x00\x00~\x83A\x80\x00\x00\x00\x00\u007f\x8e\xd3\xf0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xa1\xf4\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x01\bLMT\x00CST\x00CDT\x00\nCST6CDT,M4.1.0,M10" + + ".5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf9,\x94G\xe2\x01\x00\x00\xe2\x01\x00\x00\x0f\x00\x1c\x00America/JamaicaUT\t\x00\x03nӧ^n" + + "ӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x04\x00\x00" + + "\x00\x10\x80\x00\x00\x00\x93\x0f\xb4\xfe\a\x8d\x19p\t\x10\xa4`\t\xad\x94\xf0\n\xf0\x86`\v\xe0\x85p\f٢\xe0\r\xc0gp\x0e\xb9\x84\xe0\x0f\xa9\x83\xf0\x10\x99f\xe0\x11\x89e\xf0\x12yH\xe0\x13i" + + "G\xf0\x14Y*\xe0\x15I)\xf0\x169\f\xe0\x17)\v\xf0\x18\")`\x19\b\xed\xf0\x1a\x02\v`\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\xff\xff\xb8\x02\x00\x00\xff\xff" + + "\xb8\x02\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\fLMT\x00KMT\x00EST\x00EDT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87#~\xff\xff\xff\xff\x93\x0f\xb4\xfe\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\t\xad\x94\xf0\x00\x00\x00\x00" + + "\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0" + + "\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00" + + "\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\xff\xff\xb8\x02\x00\x00\xff\xff\xb8\x02\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\fLM" + + "T\x00KMT\x00EST\x00EDT\x00\nEST5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPAkx\xeap\t\x00\x00p\t\x00\x00\x0e\x00\x1c\x00America/Ha" + + "vanaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06" + + "\x00\x00\x00\x00\x00\x00\x00\x9c\x00\x00\x00\x06\x00\x00\x00\x10\x80\x00\x00\x00\xacb\u0080\xb1ӔP\xb2t]@\xc8[f\xd0\xc8\xd3Q@\xca;H\xd0ʼm\xc0\xcc$eP̜O\xc0\xd1\xc4\vP" + + "\xd2;\xf5\xc0ӣ\xedP\xd4\x1b\xd7\xc0\xf7`\x05\xd0\xf7\xff}@\xf9=D\xd0\xf9\xe3S\xc0\xfa\xdb;\xd0\xfb\xa7\x86@\xfcũ\xd0\xfd\x87h@\xfe\xb8\x00\xd0\xff\xa7\xe3\xc0\x00\x97\xe2\xd0\x01\x87\xc5\xc0" + + "\x02w\xc4\xd0\x03p\xe2@\x04`\xe1P\x055\x14\xc0\x06@\xc3P\a\x16H@\b \xa5P\b\xf7{\xc0\n\x00\x87P\n\xf0j@\v\xe0iP\fن\xc0\r\xc0KP\x0e\xb9h\xc0\x0f\xb2\xa2P" + + "\x10}\x9b@\x11Q\xea\xd0\x12f\xb7\xc0\x131\xcc\xd0\x14F\x99\xc0\x15[\x82\xd0\x16&{\xc0\x17;d\xd0\x18\x06]\xc0\x19\x1bF\xd0\x19\xe6?\xc0\x1a\xfb(\xd0\x1b\xcf\\@\x1c\xdb\n\xd0\x1d\xaf>@" + + "\x1ezSP\x1f\x8f @ Z5P!o\x02@\"CQ\xd0#N\xe4@$#3\xd0%.\xc6@&\x15\x8a\xd0'\x17\xe2\xc0'\xfe\xa7P(\xf7\xd2\xd0)މP*״\xd0+\xbekP" + + ",\xb7\x96\xd0-\x9eMP.\x97x\xd0/~/P0wZ\xd01gK\xd02W<\xd03G-\xd04@YP5\x1d\xd5P62\xb0P6\xfd\xb7P8\x1b\xcc\xd08\xe6\xd3\xd09\xfb\xae\xd0" + + ":Ƶ\xd0;ې\xd0<\xaf\xd2P=\xbbr\xd0>\x8f\xb4P?\x9bT\xd0@f[\xd0ED5PE\xf3\x8c\xd0G$\x17PGܩPI\x03\xf9PI\xb3P\xd0J\xe3\xdbPK\x9cmP" + + "L\xcc\xf7\xd0M\x85\x89\xd0N\xbfN\xd0Ow\xe0\xd0P\x95\xf6PQ<\x13PRu\xd8PS\x1b\xf5PTU\xbaPT\xfb\xd7PV5\x9cPV\xe4\xf3\xd0X\x1e\xb8\xd0X\xc4\xd5\xd0Y\xfe\x9a\xd0" + + "Z\xa4\xb7\xd0[\xde|\xd0\\\x84\x99\xd0]\xbe^\xd0^d{\xd0_\x9e@\xd0`M\x98Pa\x87]Pb-zPcg?Pd\r\\PeG!Pe\xed>Pg'\x03Pg\xcd P" + + "i\x06\xe5Pi\xad\x02Pj\xe6\xc7Pk\x96\x1e\xd0l\xcf\xe3\xd0mv\x00\xd0n\xaf\xc5\xd0oU\xe2\xd0p\x8f\xa7\xd0q5\xc4\xd0ro\x89\xd0s\x15\xa6\xd0tOk\xd0t\xfe\xc3Pv8\x88P" + + "vޥPx\x18jPx\xbe\x87Py\xf8LPz\x9eiP{\xd8.P|~KP}\xb8\x10P~^-P\u007f\x97\xf2P\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\xff\xff\xb2\xc8\x00\x00\xff\xff\xb2\xc0\x00\x04\xff\xff\xc7\xc0\x01\b\xff\xff\xb9\xb0\x00\f\xff\xff\xb9\xb0\x00\f\xff\xff\xc7\xc0\x01\bLMT\x00HMT\x00" + + "CDT\x00CST\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x9c\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff" + + "\xff\xffi\x87(\xb8\xff\xff\xff\xff\xacb\u0080\xff\xff\xff\xff\xb1ӔP\xff\xff\xff\xff\xb2t]@\xff\xff\xff\xff\xc8[f\xd0\xff\xff\xff\xff\xc8\xd3Q@\xff\xff\xff\xff\xca;H\xd0\xff\xff\xff\xffʼ" + + "m\xc0\xff\xff\xff\xff\xcc$eP\xff\xff\xff\xff̜O\xc0\xff\xff\xff\xff\xd1\xc4\vP\xff\xff\xff\xff\xd2;\xf5\xc0\xff\xff\xff\xffӣ\xedP\xff\xff\xff\xff\xd4\x1b\xd7\xc0\xff\xff\xff\xff\xf7`\x05\xd0\xff\xff" + + "\xff\xff\xf7\xff}@\xff\xff\xff\xff\xf9=D\xd0\xff\xff\xff\xff\xf9\xe3S\xc0\xff\xff\xff\xff\xfa\xdb;\xd0\xff\xff\xff\xff\xfb\xa7\x86@\xff\xff\xff\xff\xfcũ\xd0\xff\xff\xff\xff\xfd\x87h@\xff\xff\xff\xff\xfe\xb8" + + "\x00\xd0\xff\xff\xff\xff\xff\xa7\xe3\xc0\x00\x00\x00\x00\x00\x97\xe2\xd0\x00\x00\x00\x00\x01\x87\xc5\xc0\x00\x00\x00\x00\x02w\xc4\xd0\x00\x00\x00\x00\x03p\xe2@\x00\x00\x00\x00\x04`\xe1P\x00\x00\x00\x00\x055\x14\xc0\x00\x00" + + "\x00\x00\x06@\xc3P\x00\x00\x00\x00\a\x16H@\x00\x00\x00\x00\b \xa5P\x00\x00\x00\x00\b\xf7{\xc0\x00\x00\x00\x00\n\x00\x87P\x00\x00\x00\x00\n\xf0j@\x00\x00\x00\x00\v\xe0iP\x00\x00\x00\x00\f\xd9" + + "\x86\xc0\x00\x00\x00\x00\r\xc0KP\x00\x00\x00\x00\x0e\xb9h\xc0\x00\x00\x00\x00\x0f\xb2\xa2P\x00\x00\x00\x00\x10}\x9b@\x00\x00\x00\x00\x11Q\xea\xd0\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x131\xcc\xd0\x00\x00" + + "\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15[\x82\xd0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x17;d\xd0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x19\x1bF\xd0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xfb" + + "(\xd0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\xdb\n\xd0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ezSP\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 Z5P\x00\x00\x00\x00!o\x02@\x00\x00" + + "\x00\x00\"CQ\xd0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$#3\xd0\x00\x00\x00\x00%.\xc6@\x00\x00\x00\x00&\x15\x8a\xd0\x00\x00\x00\x00'\x17\xe2\xc0\x00\x00\x00\x00'\xfe\xa7P\x00\x00\x00\x00(\xf7" + + "\xd2\xd0\x00\x00\x00\x00)މP\x00\x00\x00\x00*״\xd0\x00\x00\x00\x00+\xbekP\x00\x00\x00\x00,\xb7\x96\xd0\x00\x00\x00\x00-\x9eMP\x00\x00\x00\x00.\x97x\xd0\x00\x00\x00\x00/~/P\x00\x00" + + "\x00\x000wZ\xd0\x00\x00\x00\x001gK\xd0\x00\x00\x00\x002W<\xd0\x00\x00\x00\x003G-\xd0\x00\x00\x00\x004@YP\x00\x00\x00\x005\x1d\xd5P\x00\x00\x00\x0062\xb0P\x00\x00\x00\x006\xfd" + + "\xb7P\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xd3\xd0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:Ƶ\xd0\x00\x00\x00\x00;ې\xd0\x00\x00\x00\x00<\xaf\xd2P\x00\x00\x00\x00=\xbbr\xd0\x00\x00" + + "\x00\x00>\x8f\xb4P\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@f[\xd0\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x8c\xd0\x00\x00\x00\x00G$\x17P\x00\x00\x00\x00GܩP\x00\x00\x00\x00I\x03" + + "\xf9P\x00\x00\x00\x00I\xb3P\xd0\x00\x00\x00\x00J\xe3\xdbP\x00\x00\x00\x00K\x9cmP\x00\x00\x00\x00L\xcc\xf7\xd0\x00\x00\x00\x00M\x85\x89\xd0\x00\x00\x00\x00N\xbfN\xd0\x00\x00\x00\x00Ow\xe0\xd0\x00\x00" + + "\x00\x00P\x95\xf6P\x00\x00\x00\x00Q<\x13P\x00\x00\x00\x00Ru\xd8P\x00\x00\x00\x00S\x1b\xf5P\x00\x00\x00\x00TU\xbaP\x00\x00\x00\x00T\xfb\xd7P\x00\x00\x00\x00V5\x9cP\x00\x00\x00\x00V\xe4" + + "\xf3\xd0\x00\x00\x00\x00X\x1e\xb8\xd0\x00\x00\x00\x00X\xc4\xd5\xd0\x00\x00\x00\x00Y\xfe\x9a\xd0\x00\x00\x00\x00Z\xa4\xb7\xd0\x00\x00\x00\x00[\xde|\xd0\x00\x00\x00\x00\\\x84\x99\xd0\x00\x00\x00\x00]\xbe^\xd0\x00\x00" + + "\x00\x00^d{\xd0\x00\x00\x00\x00_\x9e@\xd0\x00\x00\x00\x00`M\x98P\x00\x00\x00\x00a\x87]P\x00\x00\x00\x00b-zP\x00\x00\x00\x00cg?P\x00\x00\x00\x00d\r\\P\x00\x00\x00\x00eG" + + "!P\x00\x00\x00\x00e\xed>P\x00\x00\x00\x00g'\x03P\x00\x00\x00\x00g\xcd P\x00\x00\x00\x00i\x06\xe5P\x00\x00\x00\x00i\xad\x02P\x00\x00\x00\x00j\xe6\xc7P\x00\x00\x00\x00k\x96\x1e\xd0\x00\x00" + + "\x00\x00l\xcf\xe3\xd0\x00\x00\x00\x00mv\x00\xd0\x00\x00\x00\x00n\xaf\xc5\xd0\x00\x00\x00\x00oU\xe2\xd0\x00\x00\x00\x00p\x8f\xa7\xd0\x00\x00\x00\x00q5\xc4\xd0\x00\x00\x00\x00ro\x89\xd0\x00\x00\x00\x00s\x15" + + "\xa6\xd0\x00\x00\x00\x00tOk\xd0\x00\x00\x00\x00t\xfe\xc3P\x00\x00\x00\x00v8\x88P\x00\x00\x00\x00vޥP\x00\x00\x00\x00x\x18jP\x00\x00\x00\x00x\xbe\x87P\x00\x00\x00\x00y\xf8LP\x00\x00" + + "\x00\x00z\x9eiP\x00\x00\x00\x00{\xd8.P\x00\x00\x00\x00|~KP\x00\x00\x00\x00}\xb8\x10P\x00\x00\x00\x00~^-P\x00\x00\x00\x00\u007f\x97\xf2P\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04" + + "\x02\x04\x02\x04\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\xff\xff\xb2\xc8\x00\x00\xff\xff\xb2\xc0\x00\x04\xff\xff\xc7\xc0\x01\b\xff\xff\xb9\xb0\x00\f\xff\xff\xb9\xb0\x00\f\xff\xff\xc7\xc0\x01\bLM" + + "T\x00HMT\x00CDT\x00CST\x00\x00\x00\x00\x00\x01\x01\nCST5CDT,M3.2.0/0,M11.1.0/1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F" + + "\x9cP\xa9ב\xa5\xfc\x00\x00\x00\xfc\x00\x00\x00\x13\x00\x1c\x00America/TegucigalpaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00" + + "\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x03\x00\x00\x00\f\xa4LKD \x9a\xdc\xe0!\\\x9b" + + "P\"z\xbe\xe0#<}PD]\x8c\xe0D\xd6\xc8\xd0\x02\x01\x02\x01\x02\x01\x02\xff\xff\xae<\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\bLMT\x00CDT\x00CST\x00TZif2\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xa4LKD\x00\x00\x00\x00 \x9a\xdc\xe0\x00\x00\x00\x00!\\" + + "\x9bP\x00\x00\x00\x00\"z\xbe\xe0\x00\x00\x00\x00#<}P\x00\x00\x00\x00D]\x8c\xe0\x00\x00\x00\x00D\xd6\xc8\xd0\x02\x01\x02\x01\x02\x01\x02\xff\xff\xae<\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\bL" + + "MT\x00CDT\x00CST\x00\nCST6\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPgt\xddX\xf6\x00\x00\x00\xf6\x00\x00\x00\x11\x00\x1c\x00America/Guaya" + + "quilUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x10\x80\x00\x00\x00\xb6\xa4B\x18+\x16\xfc\xd0+q\xe6@\u007f\xff\xff\xff\x01\x03\x02\x03\x03\xff\xff\xb5(\x00\x00\xff\xff\xb6h\x00\x04\xff\xff\xc7\xc0\x01\b\xff" + + "\xff\xb9\xb0\x00\fLMT\x00QMT\x00-04\x00-05\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00" + + "\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87&X\xff\xff\xff\xff\xb6\xa4B\x18\x00\x00\x00\x00+\x16\xfc\xd0\x00\x00\x00\x00+q\xe6@\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x03\xff\xff\xb5(\x00\x00\xff\xff\xb6h" + + "\x00\x04\xff\xff\xc7\xc0\x01\b\xff\xff\xb9\xb0\x00\fLMT\x00QMT\x00-04\x00-05\x00\n<-05>5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb4\xa0\x9aƏ\x05\x00\x00" + + "\x8f\x05\x00\x00\x12\x00\x1c\x00America/MetlakatlaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00P\x00\x00\x00\a\x00\x00\x00\x1e\x80\x00\x00\x00ˉ\x1a\xa0\xd2#\xf4p\xd2a&\x10\xfe\xb8G \xff\xa8" + + "*\x10\x00\x98) \x01\x88\f\x10\x02x\v \x03q(\x90\x04a'\xa0\x05Q\n\x90\x06A\t\xa0\a0\xec\x90\a\x8dC\xa0\t\x10ΐ\t\xad\xbf \n\xf0\xb0\x90\v\u0be0\f\xd9\xcd\x10\r\xc0" + + "\x91\xa0\x0e\xb9\xaf\x10\x0f\xa9\xae \x10\x99\x91\x10\x11\x89\x90 \x12ys\x10\x13ir \x14YU\x10\x15IT \x1697\x10\x17)6 \x18\"S\x90\x19\t\x18 \x1a\x025\x90V5\xe2\xa0V\xe5" + + "H0X\x1e\xff X\xc5*0Y\xfe\xe1 Z\xa5\f0[\xde\xc3 \\DF\xa0\\\x84\xee0]\xbe\xa5 ^d\xd00_\x9e\x87 `M\xec\xb0a\x87\xa3\xa0b-ΰcg\x85\xa0d\r" + + "\xb0\xb0eGg\xa0e풰g'I\xa0g\xcdt\xb0i\a+\xa0i\xadV\xb0j\xe7\r\xa0k\x96s0l\xd0* mvU0n\xb0\f oV70p\x8f\xee q6\x190ro" + + "\xd0 s\x15\xfb0tO\xb2 t\xff\x17\xb0v8Πv\xde\xf9\xb0x\x18\xb0\xa0x\xbe۰y\xf8\x92\xa0z\x9e\xbd\xb0{\xd8t\xa0|~\x9f\xb0}\xb8V\xa0~^\x81\xb0\u007f\x988\xa0\x01\x02" + + "\x03\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x05\x06\x05\x06\x05\x06\x01\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x00\x00\xd6&\x00\x00\xff\xff\x8f\x80\x00\x04\xff\xff\x9d\x90\x01\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x81p\x00\x14\xff\xff\x8f\x80\x01\x19" + + "LMT\x00PST\x00PWT\x00PPT\x00PDT\x00AKST\x00AKDT\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00Q\x00\x00\x00\b\x00\x00\x00\x1e\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x870\x1a\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p" + + "\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00" + + "\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\a\x8dC\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\t\xad\xbf \x00\x00\x00\x00\n\xf0\xb0\x90" + + "\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00" + + "\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 " + + "\x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00V5\xe2\xa0\x00\x00\x00\x00V\xe5H0\x00\x00\x00\x00X\x1e\xff \x00\x00\x00\x00X\xc5*0\x00\x00\x00\x00Y\xfe\xe1 \x00\x00\x00\x00Z\xa5\f0\x00\x00\x00\x00" + + "[\xde\xc3 \x00\x00\x00\x00\\DF\xa0\x00\x00\x00\x00\\\x84\xee0\x00\x00\x00\x00]\xbe\xa5 \x00\x00\x00\x00^d\xd00\x00\x00\x00\x00_\x9e\x87 \x00\x00\x00\x00`M\xec\xb0\x00\x00\x00\x00a\x87\xa3\xa0" + + "\x00\x00\x00\x00b-ΰ\x00\x00\x00\x00cg\x85\xa0\x00\x00\x00\x00d\r\xb0\xb0\x00\x00\x00\x00eGg\xa0\x00\x00\x00\x00e풰\x00\x00\x00\x00g'I\xa0\x00\x00\x00\x00g\xcdt\xb0\x00\x00\x00\x00" + + "i\a+\xa0\x00\x00\x00\x00i\xadV\xb0\x00\x00\x00\x00j\xe7\r\xa0\x00\x00\x00\x00k\x96s0\x00\x00\x00\x00l\xd0* \x00\x00\x00\x00mvU0\x00\x00\x00\x00n\xb0\f \x00\x00\x00\x00oV70" + + "\x00\x00\x00\x00p\x8f\xee \x00\x00\x00\x00q6\x190\x00\x00\x00\x00ro\xd0 \x00\x00\x00\x00s\x15\xfb0\x00\x00\x00\x00tO\xb2 \x00\x00\x00\x00t\xff\x17\xb0\x00\x00\x00\x00v8Π\x00\x00\x00\x00" + + "v\xde\xf9\xb0\x00\x00\x00\x00x\x18\xb0\xa0\x00\x00\x00\x00x\xbe۰\x00\x00\x00\x00y\xf8\x92\xa0\x00\x00\x00\x00z\x9e\xbd\xb0\x00\x00\x00\x00{\xd8t\xa0\x00\x00\x00\x00|~\x9f\xb0\x00\x00\x00\x00}\xb8V\xa0" + + "\x00\x00\x00\x00~^\x81\xb0\x00\x00\x00\x00\u007f\x988\xa0\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x06\a\x06\a\x06\a\x02\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\x00\x00\xd6&\x00\x00\xff\xff\x84\xa6\x00\x00\xff\xff\x8f\x80\x00\x04\xff\xff\x9d\x90\x01" + + "\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x81p\x00\x14\xff\xff\x8f\x80\x01\x19LMT\x00PST\x00PWT\x00PPT\x00PDT\x00AKST\x00AKDT\x00\x00\x00\x00\x00\x01" + + "\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\nAKST9AKDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPv:D\x98\xf6\x05\x00\x00\xf6" + + "\x05\x00\x00\x10\x00\x1c\x00America/MazatlanUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\x00\x00\x00\x06\x00\x00\x00\x14\xa5\xb6\xe8p\xaf\xf2n\xe0\xb6fV`\xb7C\xd2`\xb8\f6`\xb8\xfd\x86\xf0\xcb" + + "\xeaq`ؑ\xb4\xf0\x00\x00p\x801g\x84\x102s\x16\x803Gf\x104R\xf8\x805'H\x1062ڀ7\a*\x108\x1b\xf7\x008\xe7\f\x109\xfb\xd9\x00:\xf5\x12\x90;\xb6\xd1\x00<" + + "\xb0\n\x90=\xbb\x9d\x00>\x8f\xec\x90?\x9b\u007f\x00@oΐA\x84\x9b\x80BO\xb0\x90Cd}\x80D/\x92\x90ED_\x80F\x0ft\x90G$A\x80G\xf8\x91\x10I\x04#\x80I\xd8s\x10J" + + "\xe4\x05\x80K\xb8U\x10L\xcd\"\x00M\x987\x10N\xad\x04\x00Ox\x19\x10P\x8c\xe6\x00Qa5\x90Rl\xc8\x00SA\x17\x90TL\xaa\x00U \xf9\x90V,\x8c\x00W\x00ېX\x15\xa8\x80X" + + "ཐY\xf5\x8a\x80Z\xc0\x9f\x90[\xd5l\x80\\\xa9\xbc\x10]\xb5N\x80^\x89\x9e\x10_\x950\x80`i\x80\x10a~M\x00bIb\x10c^/\x00d)D\x10e>\x11\x00f\x12`\x90g" + + "\x1d\xf3\x00g\xf2B\x90h\xfd\xd5\x00i\xd2$\x90jݷ\x00k\xb2\x06\x90l\xc6Ӏm\x91\xe8\x90n\xa6\xb5\x80oqʐp\x86\x97\x80qZ\xe7\x10rfy\x80s:\xc9\x10tF[\x80u" + + "\x1a\xab\x10v/x\x00v\xfa\x8d\x10x\x0fZ\x00x\xdao\x10y\xef<\x00z\xbaQ\x10{\xcf\x1e\x00|\xa3m\x90}\xaf\x00\x00~\x83O\x90\u007f\x8e\xe2\x00\x01\x02\x01\x02\x01\x02\x01\x03\x01\x04\x01\x04\x01" + + "\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01" + + "\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\xff\xff\x9c<\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\x8f\x80\x00\f\xff\xff\xab\xa0\x01\x10\xff\xff\x9d\x90\x00\x04LMT\x00" + + "MST\x00CST\x00PST\x00MDT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\x00\x00\x00\x06\x00\x00\x00\x14" + + "\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xcb\xeaq`\xff\xff\xff\xff" + + "ؑ\xb4\xf0\x00\x00\x00\x00\x00\x00p\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ" + + "\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00" + + "=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\u007f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90" + + "\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80\x00\x00\x00\x00G\xf8\x91\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00\x00\x00\x00" + + "K\xb8U\x10\x00\x00\x00\x00L\xcd\"\x00\x00\x00\x00\x00M\x987\x10\x00\x00\x00\x00N\xad\x04\x00\x00\x00\x00\x00Ox\x19\x10\x00\x00\x00\x00P\x8c\xe6\x00\x00\x00\x00\x00Qa5\x90\x00\x00\x00\x00Rl\xc8\x00" + + "\x00\x00\x00\x00SA\x17\x90\x00\x00\x00\x00TL\xaa\x00\x00\x00\x00\x00U \xf9\x90\x00\x00\x00\x00V,\x8c\x00\x00\x00\x00\x00W\x00ې\x00\x00\x00\x00X\x15\xa8\x80\x00\x00\x00\x00Xཐ\x00\x00\x00\x00" + + "Y\xf5\x8a\x80\x00\x00\x00\x00Z\xc0\x9f\x90\x00\x00\x00\x00[\xd5l\x80\x00\x00\x00\x00\\\xa9\xbc\x10\x00\x00\x00\x00]\xb5N\x80\x00\x00\x00\x00^\x89\x9e\x10\x00\x00\x00\x00_\x950\x80\x00\x00\x00\x00`i\x80\x10" + + "\x00\x00\x00\x00a~M\x00\x00\x00\x00\x00bIb\x10\x00\x00\x00\x00c^/\x00\x00\x00\x00\x00d)D\x10\x00\x00\x00\x00e>\x11\x00\x00\x00\x00\x00f\x12`\x90\x00\x00\x00\x00g\x1d\xf3\x00\x00\x00\x00\x00" + + "g\xf2B\x90\x00\x00\x00\x00h\xfd\xd5\x00\x00\x00\x00\x00i\xd2$\x90\x00\x00\x00\x00jݷ\x00\x00\x00\x00\x00k\xb2\x06\x90\x00\x00\x00\x00l\xc6Ӏ\x00\x00\x00\x00m\x91\xe8\x90\x00\x00\x00\x00n\xa6\xb5\x80" + + "\x00\x00\x00\x00oqʐ\x00\x00\x00\x00p\x86\x97\x80\x00\x00\x00\x00qZ\xe7\x10\x00\x00\x00\x00rfy\x80\x00\x00\x00\x00s:\xc9\x10\x00\x00\x00\x00tF[\x80\x00\x00\x00\x00u\x1a\xab\x10\x00\x00\x00\x00" + + "v/x\x00\x00\x00\x00\x00v\xfa\x8d\x10\x00\x00\x00\x00x\x0fZ\x00\x00\x00\x00\x00x\xdao\x10\x00\x00\x00\x00y\xef<\x00\x00\x00\x00\x00z\xbaQ\x10\x00\x00\x00\x00{\xcf\x1e\x00\x00\x00\x00\x00|\xa3m\x90" + + "\x00\x00\x00\x00}\xaf\x00\x00\x00\x00\x00\x00~\x83O\x90\x00\x00\x00\x00\u007f\x8e\xe2\x00\x01\x02\x01\x02\x01\x02\x01\x03\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04" + + "\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\xff\xff\x9c" + + "<\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\x8f\x80\x00\f\xff\xff\xab\xa0\x01\x10\xff\xff\x9d\x90\x00\x04LMT\x00MST\x00CST\x00PST\x00MDT\x00\nMST7MD" + + "T,M4.1.0,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe2\xa9(\xfc\xb4\x03\x00\x00\xb4\x03\x00\x00\x0e\x00\x1c\x00America/Beliz" + + "eUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x007\x00\x00\x00\x04\x00\x00\x00\x12\x93^ٰ\x9f\x9f;\xe0\xa0EQء\u007f\x1d\xe0\xa2.nX\xa3^\xff\xe0\xa4\x0ePX\xa5>\xe1\xe0\xa5\xee2X\xa7'\xfe`\xa7\xce\x14X\xa9\a\xe0" + + "`\xa9\xad\xf6X\xaa\xe7\xc2`\xab\x97\x12جǤ`\xadv\xf4خ\xa7\x86`\xafV\xd6ذ\x87h`\xb16\xb8زp\x84\xe0\xb3\x16\x9aشPf\xe0\xb4\xf6|ض0H\xe0\xb6ߙ" + + "X\xb8\x10*฿{X\xb9\xf0\fຟ]X\xbb\xd9)`\xbc\u007f?X\xbd\xb9\v`\xbe_!X\xbf\x98\xed`\xc0?\x03X\xc1x\xcf`\xc2(\x1f\xd8\xc3X\xb1`\xc4\b\x01\xd8\xc58\x93" + + "`\xc5\xe7\xe3\xd8\xc7!\xaf\xe0\xc7\xc7\xc5\xd8\xc9\x01\x91\xe0ɧ\xa7\xd8\xca\xe1s\xe0ː\xc4X\xcc\xc1U\xe0\xcdp\xa6X\ab\xdb`\a\xb9\xd0P\x18aq`\x18\xab7P\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x03\x02\xff\xff\xadP\x00\x00\xff\xff\xb2\xa8\x01\x04" + + "\xff\xff\xab\xa0\x00\n\xff\xff\xb9\xb0\x01\x0eLMT\x00-0530\x00CST\x00CDT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x007\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x93^ٰ\xff\xff\xff\xff\x9f\x9f;\xe0\xff\xff\xff\xff\xa0EQ\xd8\xff\xff\xff\xff\xa1\u007f\x1d\xe0\xff\xff\xff\xff\xa2.nX\xff\xff\xff\xff\xa3^" + + "\xff\xe0\xff\xff\xff\xff\xa4\x0ePX\xff\xff\xff\xff\xa5>\xe1\xe0\xff\xff\xff\xff\xa5\xee2X\xff\xff\xff\xff\xa7'\xfe`\xff\xff\xff\xff\xa7\xce\x14X\xff\xff\xff\xff\xa9\a\xe0`\xff\xff\xff\xff\xa9\xad\xf6X\xff\xff" + + "\xff\xff\xaa\xe7\xc2`\xff\xff\xff\xff\xab\x97\x12\xd8\xff\xff\xff\xff\xacǤ`\xff\xff\xff\xff\xadv\xf4\xd8\xff\xff\xff\xff\xae\xa7\x86`\xff\xff\xff\xff\xafV\xd6\xd8\xff\xff\xff\xff\xb0\x87h`\xff\xff\xff\xff\xb16" + + "\xb8\xd8\xff\xff\xff\xff\xb2p\x84\xe0\xff\xff\xff\xff\xb3\x16\x9a\xd8\xff\xff\xff\xff\xb4Pf\xe0\xff\xff\xff\xff\xb4\xf6|\xd8\xff\xff\xff\xff\xb60H\xe0\xff\xff\xff\xff\xb6ߙX\xff\xff\xff\xff\xb8\x10*\xe0\xff\xff" + + "\xff\xff\xb8\xbf{X\xff\xff\xff\xff\xb9\xf0\f\xe0\xff\xff\xff\xff\xba\x9f]X\xff\xff\xff\xff\xbb\xd9)`\xff\xff\xff\xff\xbc\u007f?X\xff\xff\xff\xff\xbd\xb9\v`\xff\xff\xff\xff\xbe_!X\xff\xff\xff\xff\xbf\x98" + + "\xed`\xff\xff\xff\xff\xc0?\x03X\xff\xff\xff\xff\xc1x\xcf`\xff\xff\xff\xff\xc2(\x1f\xd8\xff\xff\xff\xff\xc3X\xb1`\xff\xff\xff\xff\xc4\b\x01\xd8\xff\xff\xff\xff\xc58\x93`\xff\xff\xff\xff\xc5\xe7\xe3\xd8\xff\xff" + + "\xff\xff\xc7!\xaf\xe0\xff\xff\xff\xff\xc7\xc7\xc5\xd8\xff\xff\xff\xff\xc9\x01\x91\xe0\xff\xff\xff\xffɧ\xa7\xd8\xff\xff\xff\xff\xca\xe1s\xe0\xff\xff\xff\xffː\xc4X\xff\xff\xff\xff\xcc\xc1U\xe0\xff\xff\xff\xff\xcdp" + + "\xa6X\x00\x00\x00\x00\ab\xdb`\x00\x00\x00\x00\a\xb9\xd0P\x00\x00\x00\x00\x18aq`\x00\x00\x00\x00\x18\xab7P\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x03\x02\xff\xff\xadP\x00\x00\xff\xff\xb2\xa8\x01\x04\xff\xff\xab\xa0\x00\n\xff\xff\xb9\xb0\x01\x0eLMT\x00-05" + + "30\x00CST\x00CDT\x00\nCST6\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPh։\xbc|\t\x00\x00|\t\x00\x00\x0f\x00\x1c\x00America/Knox_" + + "INUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00" + + "\x00\x00\x00\x00\x00\x9a\x00\x00\x00\a\x00\x00\x00\x18\x80\x00\x00\x00\x9e\xa6,\x80\x9f\xba\xf9p\xa0\x86\x0e\x80\xa1\x9a\xdbpˈ\xfe\x80\xd2#\xf4p\xd2a\t\xf0\xd5U\xd5\x00\xd6 \xcd\xf0\xd75\xb7\x00\xd8\x00" + + "\xaf\xf0\xd9\x15\x99\x00\xd9\xe0\x91\xf0\xda\xfe\xb5\x80\xdb\xc0s\xf0\xdcޗ\x80ݩ\x90p\u07bey\x80߉rp\xe0\x9e[\x80\xe1iTp\xe2~=\x80\xe3I6p\xe4^\x1f\x80\xe5W<\xf0\xe6G" + + "<\x00\xe77\x1e\xf0\xe8'\x1e\x00\xe8\xf2\x16\xf0\xea\a\x00\x00\xea\xd1\xf8\xf0\xeb\xe6\xe2\x00\xec\xd6\xc4\xf0\xed\xc6\xc4\x00\xee\xbf\xe1p\xef\xaf\xe0\x80\xf0\x9f\xc3p\xf1\x8f\u0080\xf4_\x87p\xfa\xf8g\x00\xfb\xe8" + + "I\xf0\xfc\xd8I\x00\xfd\xc8+\xf0\xfe\xb8+\x00\xff\xa8\r\xf0\x00\x98\r\x00\x01\x87\xef\xf0\x02w\xef\x00\x03q\fp\x04a\v\x80\x05P\xeep\x06@\xed\x80\a0\xd0p\a\x8d'\x80\t\x10\xb2p\t\xad" + + "\xa3\x00\n\xf0\x94p\v\xe0\x93\x80\fٰ\xf0\r\xc0u\x80\x0e\xb9\x92\xf0\x0f\xa9\x92\x00\x10\x99t\xf0\x11\x89t\x00\x12yV\xf0\x13iV\x00\x14Y8\xf0\x15I8\x00\x169\x1a\xf0\x17)\x1a\x00\x18\"" + + "7p\x19\b\xfc\x00\x1a\x02\x19p\x1a\xf2\x18\x80\x1b\xe1\xfbp\x1c\xd1\xfa\x80\x1d\xc1\xddp\x1e\xb1܀\x1f\xa1\xbfp v\x0f\x00!\x81\xa1p\"U\xf1\x00#j\xbd\xf0$5\xd3\x00%J\x9f\xf0&\x15" + + "\xb5\x00'*\x81\xf0'\xfeр)\nc\xf0D/vpEDQpE\xf3\xb7\x00G-m\xf0Gә\x00I\rO\xf0I\xb3{\x00J\xed1\xf0K\x9c\x97\x80L\xd6NpM|y\x80N\xb6" + + "0pO\\[\x80P\x96\x12pQ<=\x80Ru\xf4pS\x1c\x1f\x80TU\xd6pT\xfc\x01\x80V5\xb8pV\xe5\x1e\x00X\x1e\xd4\xf0X\xc5\x00\x00Y\xfe\xb6\xf0Z\xa4\xe2\x00[ޘ\xf0\\\x84" + + "\xc4\x00]\xbez\xf0^d\xa6\x00_\x9e\\\xf0`M\u0080a\x87ypb-\xa4\x80cg[pd\r\x86\x80eG=pe\xedh\x80g'\x1fpg\xcdJ\x80i\a\x01pi\xad,\x80j\xe6" + + "\xe3pk\x96I\x00l\xcf\xff\xf0mv+\x00n\xaf\xe1\xf0oV\r\x00p\x8f\xc3\xf0q5\xef\x00ro\xa5\xf0s\x15\xd1\x00tO\x87\xf0t\xfe\xed\x80v8\xa4pv\xdeπx\x18\x86px\xbe" + + "\xb1\x80y\xf8hpz\x9e\x93\x80{\xd8Jp|~u\x80}\xb8,p~^W\x80\u007f\x98\x0ep\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x05" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\xff\xff\xae\xca\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xab\xa0\x00\bLMT\x00CDT\x00CST\x00CW" + + "T\x00CPT\x00EST\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x01\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x9a" + + "\x00\x00\x00\a\x00\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff" + + "\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0" + + "\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff" + + "\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5W<\xf0\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00" + + "\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff" + + "\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\u0080\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0" + + "\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00" + + "\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80" + + "\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00" + + "\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p" + + "\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00" + + "!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр" + + "\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G-m\xf0\x00\x00\x00\x00Gә\x00\x00\x00\x00\x00I\rO\xf0\x00\x00\x00\x00" + + "I\xb3{\x00\x00\x00\x00\x00J\xed1\xf0\x00\x00\x00\x00K\x9c\x97\x80\x00\x00\x00\x00L\xd6Np\x00\x00\x00\x00M|y\x80\x00\x00\x00\x00N\xb60p\x00\x00\x00\x00O\\[\x80\x00\x00\x00\x00P\x96\x12p" + + "\x00\x00\x00\x00Q<=\x80\x00\x00\x00\x00Ru\xf4p\x00\x00\x00\x00S\x1c\x1f\x80\x00\x00\x00\x00TU\xd6p\x00\x00\x00\x00T\xfc\x01\x80\x00\x00\x00\x00V5\xb8p\x00\x00\x00\x00V\xe5\x1e\x00\x00\x00\x00\x00" + + "X\x1e\xd4\xf0\x00\x00\x00\x00X\xc5\x00\x00\x00\x00\x00\x00Y\xfe\xb6\xf0\x00\x00\x00\x00Z\xa4\xe2\x00\x00\x00\x00\x00[ޘ\xf0\x00\x00\x00\x00\\\x84\xc4\x00\x00\x00\x00\x00]\xbez\xf0\x00\x00\x00\x00^d\xa6\x00" + + "\x00\x00\x00\x00_\x9e\\\xf0\x00\x00\x00\x00`M\u0080\x00\x00\x00\x00a\x87yp\x00\x00\x00\x00b-\xa4\x80\x00\x00\x00\x00cg[p\x00\x00\x00\x00d\r\x86\x80\x00\x00\x00\x00eG=p\x00\x00\x00\x00" + + "e\xedh\x80\x00\x00\x00\x00g'\x1fp\x00\x00\x00\x00g\xcdJ\x80\x00\x00\x00\x00i\a\x01p\x00\x00\x00\x00i\xad,\x80\x00\x00\x00\x00j\xe6\xe3p\x00\x00\x00\x00k\x96I\x00\x00\x00\x00\x00l\xcf\xff\xf0" + + "\x00\x00\x00\x00mv+\x00\x00\x00\x00\x00n\xaf\xe1\xf0\x00\x00\x00\x00oV\r\x00\x00\x00\x00\x00p\x8f\xc3\xf0\x00\x00\x00\x00q5\xef\x00\x00\x00\x00\x00ro\xa5\xf0\x00\x00\x00\x00s\x15\xd1\x00\x00\x00\x00\x00" + + "tO\x87\xf0\x00\x00\x00\x00t\xfe\xed\x80\x00\x00\x00\x00v8\xa4p\x00\x00\x00\x00v\xdeπ\x00\x00\x00\x00x\x18\x86p\x00\x00\x00\x00x\xbe\xb1\x80\x00\x00\x00\x00y\xf8hp\x00\x00\x00\x00z\x9e\x93\x80" + + "\x00\x00\x00\x00{\xd8Jp\x00\x00\x00\x00|~u\x80\x00\x00\x00\x00}\xb8,p\x00\x00\x00\x00~^W\x80\x00\x00\x00\x00\u007f\x98\x0ep\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x05\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xae\xca\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xab\xa0\x00\bLMT\x00" + + "CDT\x00CST\x00CWT\x00CPT\x00EST\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x01\x00\x00\nCST6CDT,M3.2.0,M11.1.0\nPK" + + "\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x8a\xa3\xa5\x8a\x88\x05\x00\x00\x88\x05\x00\x00\x0e\x00\x1c\x00America/CuiabaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01" + + "\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Z\x00\x00\x00\x03\x00\x00\x00\f\x96\xaa{\x94\xb8\x0f" + + "W\xf0\xb8\xfdN\xb0\xb9\xf1B@\xbaނ0\xda8\xbc@\xda\xec\b@\xdc\x19\xef\xc0ܹg0\xdd\xfb#@ޛ\xec0\xdfݨ@\xe0TA0\xf4\x98\r\xc0\xf5\x05l0\xf6\xc0r@\xf7\x0e" + + ",\xb0\xf8Q:@\xf8\xc7\xd30\xfa\n\xe0\xc0\xfa\xa9\x06\xb0\xfb\xec\x14@\xfc\x8b\x8b\xb0\x1dɜ@\x1ex\xe5\xb0\x1f\xa0C\xc0 3ݰ!\x81w@\"\vְ#X\x1e\xc0#\xe2~0%8" + + "\x00\xc0%\xd4\xd50'!\x1d@'\xbd\xf1\xb0)\x00\xff@)\x94\x990*\xea\x1b\xc0+k@\xb0,\xc0\xc3@-f\xd20.\xa0\xa5@/F\xb400\x80\x87@1\x1d[\xb02W.\xc03\x06" + + "x048b@4\xf8\xcf06 -@6\xcfv\xb07\xf6\xd4\xc08\xb8\x9309\xdf\xf1@:\x8f:\xb0;\xc9\r\xc0N\xfe\xb0A\x87\x06@B\x17\xfd0CQ" + + "\xd0@C\xf7\xdf0EMa\xc0E\xe0\xfb\xb0G\x11\x94@G\xb7\xa30H\xfa\xb0\xc0I\x97\x850Jڒ\xc0K\x80\xa1\xb0L\xbat\xc0M`\x83\xb0N\x9aV\xc0OI\xa00P\x83s@Q " + + "G\xb0RcU@S\x00)\xb0TC7@T\xe9F0V#\x19@V\xc9(0X\x02\xfb@X\xa9\n0Y\xe2\xdd@Z\x88\xec0[\xden\xc0\\h\xce0\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\xff\xff\xcbl\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03\x00-04\x00TZif2\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Z\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa{\x94\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfd" + + "N\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xbaނ0\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#@\xff\xff" + + "\xff\xffޛ\xec0\xff\xff\xff\xff\xdfݨ@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q" + + ":@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00" + + "\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3ݰ\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"\vְ\x00\x00\x00\x00#X\x1e\xc0\x00\x00\x00\x00#\xe2~0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xd4" + + "\xd50\x00\x00\x00\x00'!\x1d@\x00\x00\x00\x00'\xbd\xf1\xb0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\x94\x990\x00\x00\x00\x00*\xea\x1b\xc0\x00\x00\x00\x00+k@\xb0\x00\x00\x00\x00,\xc0\xc3@\x00\x00" + + "\x00\x00-f\xd20\x00\x00\x00\x00.\xa0\xa5@\x00\x00\x00\x00/F\xb40\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001\x1d[\xb0\x00\x00\x00\x002W.\xc0\x00\x00\x00\x003\x06x0\x00\x00\x00\x0048" + + "b@\x00\x00\x00\x004\xf8\xcf0\x00\x00\x00\x006 -@\x00\x00\x00\x006\xcfv\xb0\x00\x00\x00\x007\xf6\xd4\xc0\x00\x00\x00\x008\xb8\x930\x00\x00\x00\x009\xdf\xf1@\x00\x00\x00\x00:\x8f:\xb0\x00\x00" + + "\x00\x00;\xc9\r\xc0\x00\x00\x00\x00N\xfe\xb0\x00\x00\x00\x00A\x87\x06@\x00\x00\x00\x00B\x17\xfd0\x00\x00\x00\x00CQ\xd0@\x00\x00\x00\x00C\xf7" + + "\xdf0\x00\x00\x00\x00EMa\xc0\x00\x00\x00\x00E\xe0\xfb\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xb7\xa30\x00\x00\x00\x00H\xfa\xb0\xc0\x00\x00\x00\x00I\x97\x850\x00\x00\x00\x00Jڒ\xc0\x00\x00" + + "\x00\x00K\x80\xa1\xb0\x00\x00\x00\x00L\xbat\xc0\x00\x00\x00\x00M`\x83\xb0\x00\x00\x00\x00N\x9aV\xc0\x00\x00\x00\x00OI\xa00\x00\x00\x00\x00P\x83s@\x00\x00\x00\x00Q G\xb0\x00\x00\x00\x00Rc" + + "U@\x00\x00\x00\x00S\x00)\xb0\x00\x00\x00\x00TC7@\x00\x00\x00\x00T\xe9F0\x00\x00\x00\x00V#\x19@\x00\x00\x00\x00V\xc9(0\x00\x00\x00\x00X\x02\xfb@\x00\x00\x00\x00X\xa9\n0\x00\x00" + + "\x00\x00Y\xe2\xdd@\x00\x00\x00\x00Z\x88\xec0\x00\x00\x00\x00[\xden\xc0\x00\x00\x00\x00\\h\xce0\x00\x00\x00\x00\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x02\xff\xff\xcbl\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03\x00-04\x00\n<-04>4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP" + + "\xa7\xaa/\x17\x8e\x05\x00\x00\x8e\x05\x00\x00\x0e\x00\x1c\x00America/MeridaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZ" + + "if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00W\x00\x00\x00\x05\x00\x00\x00\x10\xa5\xb6\xda`\x16\x86\xd5`\x18LKP1gv\x002s" + + "\bp3GX\x004R\xeap5':\x0062\xccp7\a\x1c\x008\x1b\xe8\xf08\xe6\xfe\x009\xfb\xca\xf0:\xf5\x04\x80;\xb6\xc2\xf0<\xaf\xfc\x80=\xbb\x8e\xf0>\x8fހ?\x9bp\xf0@o" + + "\xc0\x80A\x84\x8dpBO\xa2\x80CdopD/\x84\x80EDQpF\x0ff\x80G$3pG\xf8\x83\x00I\x04\x15pI\xd8e\x00J\xe3\xf7pK\xb8G\x00L\xcd\x13\xf0M\x98)\x00N\xac" + + "\xf5\xf0Ox\v\x00P\x8c\xd7\xf0Qa'\x80Rl\xb9\xf0SA\t\x80TL\x9b\xf0U \xeb\x80V,}\xf0W\x00̀X\x15\x9apXீY\xf5|pZ\xc0\x91\x80[\xd5^p\\\xa9" + + "\xae\x00]\xb5@p^\x89\x90\x00_\x95\"p`ir\x00a~>\xf0bIT\x00c^ \xf0d)6\x00e>\x02\xf0f\x12R\x80g\x1d\xe4\xf0g\xf24\x80h\xfd\xc6\xf0i\xd2\x16\x80j\xdd" + + "\xa8\xf0k\xb1\xf8\x80l\xc6\xc5pm\x91ڀn\xa6\xa7poq\xbc\x80p\x86\x89pqZ\xd9\x00rfkps:\xbb\x00tFMpu\x1a\x9d\x00v/i\xf0v\xfa\u007f\x00x\x0fK\xf0x\xda" + + "a\x00y\xef-\xf0z\xbaC\x00{\xcf\x0f\xf0|\xa3_\x80}\xae\xf1\xf0~\x83A\x80\u007f\x8e\xd3\xf0\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03" + + "\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\xff\xff\xab" + + "\xfc\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xab\xa0\x00\x04LMT\x00CST\x00EST\x00CDT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00W\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xa5\xb6\xda`\x00\x00\x00\x00\x16\x86\xd5`\x00\x00\x00\x00\x18LKP\x00\x00\x00\x001gv\x00\x00" + + "\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008" + + "\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00" + + "\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00F\x0ff\x80\x00\x00\x00\x00G" + + "$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00K\xb8G\x00\x00\x00\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00M\x98)\x00\x00" + + "\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00Ox\v\x00\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00Rl\xb9\xf0\x00\x00\x00\x00SA\t\x80\x00\x00\x00\x00TL\x9b\xf0\x00\x00\x00\x00U" + + " \xeb\x80\x00\x00\x00\x00V,}\xf0\x00\x00\x00\x00W\x00̀\x00\x00\x00\x00X\x15\x9ap\x00\x00\x00\x00Xீ\x00\x00\x00\x00Y\xf5|p\x00\x00\x00\x00Z\xc0\x91\x80\x00\x00\x00\x00[\xd5^p\x00" + + "\x00\x00\x00\\\xa9\xae\x00\x00\x00\x00\x00]\xb5@p\x00\x00\x00\x00^\x89\x90\x00\x00\x00\x00\x00_\x95\"p\x00\x00\x00\x00`ir\x00\x00\x00\x00\x00a~>\xf0\x00\x00\x00\x00bIT\x00\x00\x00\x00\x00c" + + "^ \xf0\x00\x00\x00\x00d)6\x00\x00\x00\x00\x00e>\x02\xf0\x00\x00\x00\x00f\x12R\x80\x00\x00\x00\x00g\x1d\xe4\xf0\x00\x00\x00\x00g\xf24\x80\x00\x00\x00\x00h\xfd\xc6\xf0\x00\x00\x00\x00i\xd2\x16\x80\x00" + + "\x00\x00\x00jݨ\xf0\x00\x00\x00\x00k\xb1\xf8\x80\x00\x00\x00\x00l\xc6\xc5p\x00\x00\x00\x00m\x91ڀ\x00\x00\x00\x00n\xa6\xa7p\x00\x00\x00\x00oq\xbc\x80\x00\x00\x00\x00p\x86\x89p\x00\x00\x00\x00q" + + "Z\xd9\x00\x00\x00\x00\x00rfkp\x00\x00\x00\x00s:\xbb\x00\x00\x00\x00\x00tFMp\x00\x00\x00\x00u\x1a\x9d\x00\x00\x00\x00\x00v/i\xf0\x00\x00\x00\x00v\xfa\u007f\x00\x00\x00\x00\x00x\x0fK\xf0\x00" + + "\x00\x00\x00x\xdaa\x00\x00\x00\x00\x00y\xef-\xf0\x00\x00\x00\x00z\xbaC\x00\x00\x00\x00\x00{\xcf\x0f\xf0\x00\x00\x00\x00|\xa3_\x80\x00\x00\x00\x00}\xae\xf1\xf0\x00\x00\x00\x00~\x83A\x80\x00\x00\x00\x00\u007f" + + "\x8e\xd3\xf0\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01" + + "\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\xff\xff\xab\xfc\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xab\xa0\x00\x04" + + "LMT\x00CST\x00EST\x00CDT\x00\nCST6CDT,M4.1.0,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf5\"\xa0\xdf\x18\x04" + + "\x00\x00\x18\x04\x00\x00\r\x00\x1c\x00America/JujuyUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x06\x00\x00\x00\x14\x80\x00\x00\x00\xa2\x92\x8f0\xb6{R@\xb7\x1aɰ\xb8\x1e\x8f@\xb8\xd4p0\xba" + + "\x17}\xc0\xba\xb5\xa3\xb0\xbb\xf8\xb1@\xbc\x96\xd70\xbd\xd9\xe4\xc0\xbex\n\xb0\xbf\xbb\x18@\xc0Z\x8f\xb0\xc1\x9d\x9d@\xc2;\xc30\xc3~\xd0\xc0\xc4\x1c\xf6\xb0\xc5`\x04@\xc5\xfe*0\xc7A7\xc0\xc7" + + "\xe0\xaf0ȁ\x94@\xcaM\xa1\xb0\xca\xee\x86\xc0\xceM\xff0ΰ\xed\xc0\xd3)5\xb0\xd4Cd\xc0\xf4=\b0\xf4\x9f\xf6\xc0\xf5\x05l0\xf62\x10@\xf6柰\xf8\x13C\xc0\xf8\xc7\xd30\xf9" + + "\xf4w@\xfa\xd36\xb0\xfb\xc35\xc0\xfc\xbcS0\xfd\xacR@\xfe\x9c50\xff\x8c4@\a\xa3J\xb0\b$o\xa0#\x94\xb5\xb0$\x10\x94\xa0%7\xf2\xb0%\xf0v\xa0'*W\xc0'\xe2۰(" + + "\xee\x8a@)\xb0:\xa0*\xe0\xd30+\x99W 7\xf6ư8\xbf*\xb0Gw\t\xb0G\xdc\u007f \u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x04\x05\x04\x05\x03\x05\x04\x05\x05\xff\xff\xc2\xc8\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff" + + "\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xae\xb8\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8" + + "\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff" + + "\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7" + + "A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff" + + "\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8" + + "\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00" + + "\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'*W\xc0\x00\x00\x00\x00'" + + "\xe2۰\x00\x00\x00\x00(\xee\x8a@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00" + + "\x00\x00\x00G\xdc\u007f \x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05" + + "\x04\x05\x04\x02\x03\x02\x04\x05\x04\x05\x03\x05\x04\x05\x05\xff\xff\xc2\xc8\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-" + + "04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x98`\x15n\xb6\x00\x00\x00\xb6\x00\x00\x00\x0e\x00\x1c\x00America/Cay" + + "manUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\x80\x00\x00\x00\x8b\xf4a\xe8\x01\x02\xff\xff\xb5p\x00\x00\xff\xff\xb5\x18\x00\x04\xff\xff\xb9\xb0\x00\bLMT\x00CMT\x00EST\x00TZif2" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffi\x87&\x10\xff\xff\xff\xff\x8b\xf4a\xe8\x01\x02\xff\xff\xb5" + + "p\x00\x00\xff\xff\xb5\x18\x00\x04\xff\xff\xb9\xb0\x00\bLMT\x00CMT\x00EST\x00\nEST5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\v\xab\xa3\xd0@\x02\x00\x00@\x02\x00\x00\r" + + "\x00\x1c\x00America/BelemUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x03\x00\x00\x00\f\x96\xaatt\xb8\x0fI\xe0\xb8\xfd@\xa0\xb9\xf140\xba\xdet \xda8\xae0\xda\xeb\xfa0\xdc\x19\xe1\xb0" + + "ܹY \xdd\xfb\x150ޛ\xde \xdfݚ0\xe0T3 \xf4\x97\xff\xb0\xf5\x05^ \xf6\xc0d0\xf7\x0e\x1e\xa0\xf8Q,0\xf8\xc7\xc5 \xfa\nҰ\xfa\xa8\xf8\xa0\xfb\xec\x060\xfc\x8b}\xa0" + + "\x1dɎ0\x1exנ\x1f\xa05\xb0 3Ϡ!\x81i0\"\vȠ\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\xff\xff" + + "Ҍ\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x1e\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaatt\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0" + + "\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff" + + "\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0" + + "\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00" + + "\"\vȠ\x00\x00\x00\x00\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\xff\xffҌ\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\b" + + "LMT\x00-02\x00-03\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x937\x86\x9f\x90\x02\x00\x00\x90\x02\x00\x00\x10\x00\x1c\x00America/Ei" + + "runepeUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\x05\x00\x00\x00\f\x96\xaa\x88\x80\xb8\x0ff\x00\xb8\xfd\\\xc0\xb9\xf1PP\xbaސ@\xda8\xcaP\xda\xec\x16P\xdc\x19\xfd\xd0ܹu@\xdd\xfb1Pޛ" + + "\xfa@\xdfݶP\xe0TO@\xf4\x98\x1b\xd0\xf5\x05z@\xf6\xc0\x80P\xf7\x0e:\xc0\xf8QHP\xf8\xc7\xe1@\xfa\n\xee\xd0\xfa\xa9\x14\xc0\xfb\xec\"P\xfc\x8b\x99\xc0\x1dɪP\x1ex\xf3\xc0\x1f\xa0" + + "Q\xd0 3\xeb\xc0!\x81\x85P\"\v\xe4\xc0,\xc0\xd1P-f\xe0@H`\u007fPR\u007f\x04\xc0\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x03\x02\x02\xff\xff\xbe\x80\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\x04\xff\xff\xb9\xb0\x00\bLMT\x00-04\x00-05\x00TZif2\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\x05\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x88\x80\xff\xff\xff\xff\xb8\x0ff\x00\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff" + + "\xff\xff\xb9\xf1PP\xff\xff\xff\xff\xbaސ@\xff\xff\xff\xff\xda8\xcaP\xff\xff\xff\xff\xda\xec\x16P\xff\xff\xff\xff\xdc\x19\xfd\xd0\xff\xff\xff\xffܹu@\xff\xff\xff\xff\xdd\xfb1P\xff\xff\xff\xffޛ" + + "\xfa@\xff\xff\xff\xff\xdfݶP\xff\xff\xff\xff\xe0TO@\xff\xff\xff\xff\xf4\x98\x1b\xd0\xff\xff\xff\xff\xf5\x05z@\xff\xff\xff\xff\xf6\xc0\x80P\xff\xff\xff\xff\xf7\x0e:\xc0\xff\xff\xff\xff\xf8QHP\xff\xff" + + "\xff\xff\xf8\xc7\xe1@\xff\xff\xff\xff\xfa\n\xee\xd0\xff\xff\xff\xff\xfa\xa9\x14\xc0\xff\xff\xff\xff\xfb\xec\"P\xff\xff\xff\xff\xfc\x8b\x99\xc0\x00\x00\x00\x00\x1dɪP\x00\x00\x00\x00\x1ex\xf3\xc0\x00\x00\x00\x00\x1f\xa0" + + "Q\xd0\x00\x00\x00\x00 3\xeb\xc0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"\v\xe4\xc0\x00\x00\x00\x00,\xc0\xd1P\x00\x00\x00\x00-f\xe0@\x00\x00\x00\x00H`\u007fP\x00\x00\x00\x00R\u007f\x04\xc0\x00\x00" + + "\x00\x00\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x02\xff\xff\xbe\x80\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff" + + "\xc7\xc0\x00\x04\xff\xff\xb9\xb0\x00\bLMT\x00-04\x00-05\x00\n<-05>5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xcf|3(\x94\x00\x00\x00\x94\x00\x00\x00\x10\x00\x1c\x00" + + "America/St_LuciaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\x9373\xac\x01\xff\xff\xc6T\x00\x00\xff\xff\xc7\xc0\x00\x04LMT\x00AST\x00TZif2\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x9373\xac\x01\xff\xff\xc6T\x00\x00\xff\xff\xc7\xc0\x00\x04LM" + + "T\x00AST\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP:L\xec/\x00\x04\x00\x00\x00\x04\x00\x00\r\x00\x1c\x00America/BahiaUT\t\x00\x03" + + "nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00" + + "\x00\x00\x03\x00\x00\x00\f\x96\xaak\x1c\xb8\x0fI\xe0\xb8\xfd@\xa0\xb9\xf140\xba\xdet \xda8\xae0\xda\xeb\xfa0\xdc\x19\xe1\xb0ܹY \xdd\xfb\x150ޛ\xde \xdfݚ0\xe0T3 \xf4" + + "\x97\xff\xb0\xf5\x05^ \xf6\xc0d0\xf7\x0e\x1e\xa0\xf8Q,0\xf8\xc7\xc5 \xfa\nҰ\xfa\xa8\xf8\xa0\xfb\xec\x060\xfc\x8b}\xa0\x1dɎ0\x1exנ\x1f\xa05\xb0 3Ϡ!\x81i0\"" + + "\vȠ#X\x10\xb0#\xe2p %7\xf2\xb0%\xd4\xc7 '!\x0f0'\xbd\xe3\xa0)\x00\xf10)\x94\x8b *\xea\r\xb0+k2\xa0,\xc0\xb50-f\xc4 .\xa0\x970/F\xa6 0" + + "\x80y01\x1dM\xa02W \xb03\x06j 48T04\xf8\xc1 6 \x1f06\xcfh\xa07\xf6ư8\xb8\x85 9\xdf\xe30:\x8f,\xa0;\xc8\xff\xb0" + + "N\xf0\xa0N\x9aH\xb0OI\x92 \u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\xff\xff\xdb\xe4\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaak\x1c\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9" + + "\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff" + + "\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8" + + "\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00" + + "\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x00'" + + "!\x0f0\x00\x00\x00\x00'\xbd\xe3\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\x94\x8b \x00\x00\x00\x00*\xea\r\xb0\x00\x00\x00\x00+k2\xa0\x00\x00\x00\x00,\xc0\xb50\x00\x00\x00\x00-f\xc4 \x00" + + "\x00\x00\x00.\xa0\x970\x00\x00\x00\x00/F\xa6 \x00\x00\x00\x000\x80y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00\x002W \xb0\x00\x00\x00\x003\x06j \x00\x00\x00\x0048T0\x00\x00\x00\x004" + + "\xf8\xc1 \x00\x00\x00\x006 \x1f0\x00\x00\x00\x006\xcfh\xa0\x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x00:\x8f,\xa0\x00\x00\x00\x00;\xc8\xff\xb0\x00" + + "\x00\x00\x00N\xf0\xa0\x00\x00\x00\x00N\x9aH\xb0\x00\x00\x00\x00OI\x92 \x00\x00\x00\x00\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\xff\xff\xdb\xe4\x00\x00\xff\xff\xe3\xe0\x01" + + "\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x82\x10\xfe\x93@\x06\x00\x00@\x06\x00\x00\x12\x00\x1c\x00Ame" + + "rica/WhitehorseUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\\\x00\x00\x00\t\x00\x00\x00%\x80\x00\x00\x00\x9e\xb8˰\x9f\xbb#\xa0\xa0\xd0\f\xb0\xa1\xa2Ҁˉ(\xb0\xd2#\xf4p\xd2a4 \xf7" + + "/v\x90\xf8(\xa2\x10\xfb\x1d_\x10\x13ir \x14YU\x10\x15IT \x1697\x10\x17)6 \x18\"S\x90\x19\t\x18 \x1a\x025\x90\x1a\xf24\xa0\x1b\xe2\x17\x90\x1c\xd2\x16\xa0\x1d\xc1\xf9\x90\x1e" + + "\xb1\xf8\xa0\x1f\xa1ې v+ !\x81\xbd\x90\"V\r #j\xda\x10$5\xef %J\xbc\x10&\x15\xd1 '*\x9e\x10'\xfe\xed\xa0)\n\x80\x10)\xdeϠ*\xeab\x10+\xbe\xb1\xa0," + + "\xd3~\x90-\x9e\x93\xa0.\xb3`\x90/~u\xa00\x93B\x901g\x92 2s$\x903Gt 4S\x06\x905'V 62\xe8\x907\a8 8\x1c\x05\x108\xe7\x1a 9\xfb\xe7\x10:" + + "\xc6\xfc ;\xdb\xc9\x10<\xb0\x18\xa0=\xbb\xab\x10>\x8f\xfa\xa0?\x9b\x8d\x10@oܠA\x84\xa9\x90BO\xbe\xa0Cd\x8b\x90D/\xa0\xa0EDm\x90E\xf3\xd3 G-\x8a\x10Gӵ I" + + "\rl\x10I\xb3\x97 J\xedN\x10K\x9c\xb3\xa0L\xd6j\x90M|\x95\xa0N\xb6L\x90O\\w\xa0P\x96.\x90Q\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00" + + "Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x00\x00\x00\x00G-\x8a\x10\x00\x00\x00\x00Gӵ \x00\x00\x00\x00I\rl\x10\x00\x00\x00\x00I\xb3\x97 " + + "\x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00M|\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\\w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00" + + "Q\x8f\xfa\xa0?\x9b\x8d\x10@oܠA\x84\xa9\x90BO\xbe\xa0Cd\x8b\x90D/\xa0\xa0EDm\x90E\xf3\xd3 G-\x8a\x10Gӵ I\rl\x10I\xb3\x97 J\xedN\x10K" + + "\x9c\xb3\xa0L\xd6j\x90M|\x95\xa0N\xb6L\x90O\\w\xa0P\x96.\x90Q\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@o\xdc" + + "\xa0\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x00\x00\x00\x00G-\x8a\x10\x00\x00\x00" + + "\x00Gӵ \x00\x00\x00\x00I\rl\x10\x00\x00\x00\x00I\xb3\x97 \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00M|\x95\xa0\x00\x00\x00\x00N\xb6L" + + "\x90\x00\x00\x00\x00O\\w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q\x8f\xec\x90?\x9b\u007f\x00@oΐA" + + "\x84\x9b\x80BO\xb0\x90Cd}\x80D/\x92\x90ED_\x80E\xf3\xc5\x10G-|\x00Gӧ\x10I\r^\x00I\xb3\x89\x10J\xed@\x00K\x9c\xa5\x90L\xd6\\\x80M|\x87\x90N\xb6>\x80O" + + "\\i\x90P\x96 \x80Q\x8f\xec\x90\x00\x00\x00\x00?\x9b\u007f\x00\x00\x00" + + "\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x00\x00\x00\x00G-" + + "|\x00\x00\x00\x00\x00Gӧ\x10\x00\x00\x00\x00I\r^\x00\x00\x00\x00\x00I\xb3\x89\x10\x00\x00\x00\x00J\xed@\x00\x00\x00\x00\x00K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\\\x80\x00\x00\x00\x00M|\x87\x90\x00\x00" + + "\x00\x00N\xb6>\x80\x00\x00\x00\x00O\\i\x90\x00\x00\x00\x00P\x96 \x80\x00\x00\x00\x00Q3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x92)G\x11" + + "\xcc\x02\x00\x00\xcc\x02\x00\x00\x0f\x00\x1c\x00America/NoronhaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00(\x00\x00\x00\x03\x00\x00\x00\f\x96\xaaed\xb8\x0f;и\xfd2\x90\xb9\xf1& \xba\xdef\x10\xda" + + "8\xa0 \xda\xeb\xec \xdc\x19ӠܹK\x10\xdd\xfb\a ޛ\xd0\x10\xdf\u074c \xe0T%\x10\xf4\x97\xf1\xa0\xf5\x05P\x10\xf6\xc0V \xf7\x0e\x10\x90\xf8Q\x1e \xf8Ƿ\x10\xfa\nĠ\xfa" + + "\xa8\xea\x90\xfb\xeb\xf8 \xfc\x8bo\x90\x1dɀ \x1exɐ\x1f\xa0'\xa0 3\xc1\x90!\x81[ \"\v\xba\x90#X\x02\xa0#\xe2b\x10%7\xe4\xa0%Թ\x107\xf6\xb8\xa08\xb8w\x109" + + "\xdf\xd5 9\xe9\x01\x90;\xc8\xf1\xa02\nPK\x03\x04\n\x00\x00\x00\x00" + + "\x00\xf5F\x9cP\t)<\xb24\x04\x00\x004\x04\x00\x00\x14\x00\x1c\x00America/Buenos_AiresUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04" + + "\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06\x00\x00\x00\x14\x80\x00\x00\x00\xa2\x92\x8f" + + "0\xb6{R@\xb7\x1aɰ\xb8\x1e\x8f@\xb8\xd4p0\xba\x17}\xc0\xba\xb5\xa3\xb0\xbb\xf8\xb1@\xbc\x96\xd70\xbd\xd9\xe4\xc0\xbex\n\xb0\xbf\xbb\x18@\xc0Z\x8f\xb0\xc1\x9d\x9d@\xc2;\xc30\xc3~\xd0" + + "\xc0\xc4\x1c\xf6\xb0\xc5`\x04@\xc5\xfe*0\xc7A7\xc0\xc7\xe0\xaf0ȁ\x94@\xcaM\xa1\xb0\xca\xee\x86\xc0\xceM\xff0ΰ\xed\xc0\xd3)5\xb0\xd4Cd\xc0\xf4=\b0\xf4\x9f\xf6\xc0\xf5\x05l" + + "0\xf62\x10@\xf6柰\xf8\x13C\xc0\xf8\xc7\xd30\xf9\xf4w@\xfa\xd36\xb0\xfb\xc35\xc0\xfc\xbcS0\xfd\xacR@\xfe\x9c50\xff\x8c4@\a\xa3J\xb0\b$o\xa0#\x94\xb5\xb0$\x10\x94" + + "\xa0%7\xf2\xb0%\xf0v\xa0'!\x0f0'\xd0X\xa0)\x00\xf10)\xb0:\xa0*\xe0\xd30+\x99W 7\xf6ư8\xbf*\xb0Gw\t\xb0G\xdc\u007f H\xfa\xa2\xb0I\xbca \u007f\xff\xff" + + "\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x04\x05" + + "\x04\x05\x05\xff\xff\xc94\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00T" + + "Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xa8L\xff\xff\xff\xff\xa2\x92\x8f0\xff" + + "\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc" + + "\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff" + + "\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca" + + "\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff" + + "\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc" + + "\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00" + + "\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+" + + "\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\u007f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x00\x00\x00\x00\u007f\xff\xff\xff\x01" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05" + + "\x05\xff\xff\xc94\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-" + + "03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPʇ(-\x14\v\x00\x00\x14\v\x00\x00\x13\x00\x1c\x00America/Los_AngelesUT\t\x00\x03n" + + "ӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\xba\x00\x00" + + "\x00\x05\x00\x00\x00\x14\x80\x00\x00\x00\x9e\xa6H\xa0\x9f\xbb\x15\x90\xa0\x86*\xa0\xa1\x9a\xf7\x90ˉ\x1a\xa0\xd2#\xf4p\xd2a&\x10\xd6\xfet\\\u0600\xad\x90\xda\xfeÐ\xdb\xc0\x90\x10\xdcޥ\x90ݩ" + + "\xac\x90\u07be\x87\x90߉\x8e\x90\xe0\x9ei\x90\xe1ip\x90\xe2~K\x90\xe3IR\x90\xe4^-\x90\xe5)4\x90\xe6GJ\x10\xe7\x12Q\x10\xe8',\x10\xe8\xf23\x10\xea\a\x0e\x10\xea\xd2\x15\x10\xeb\xe6" + + "\xf0\x10\xec\xb1\xf7\x10\xed\xc6\xd2\x10\xee\x91\xd9\x10\xef\xaf\xee\x90\xf0q\xbb\x10\xf1\x8fА\xf2\u007f\xc1\x90\xf3o\xb2\x90\xf4_\xa3\x90\xf5O\x94\x90\xf6?\x85\x90\xf7/v\x90\xf8(\xa2\x10\xf9\x0fX\x90\xfa\b" + + "\x84\x10\xfa\xf8\x83 \xfb\xe8f\x10\xfc\xd8e \xfd\xc8H\x10\xfe\xb8G \xff\xa8*\x10\x00\x98) \x01\x88\f\x10\x02x\v \x03q(\x90\x04a'\xa0\x05Q\n\x90\x06A\t\xa0\a0\xec\x90\a\x8d" + + "C\xa0\t\x10ΐ\t\xad\xbf \n\xf0\xb0\x90\v\u0be0\f\xd9\xcd\x10\r\xc0\x91\xa0\x0e\xb9\xaf\x10\x0f\xa9\xae \x10\x99\x91\x10\x11\x89\x90 \x12ys\x10\x13ir \x14YU\x10\x15IT \x169" + + "7\x10\x17)6 \x18\"S\x90\x19\t\x18 \x1a\x025\x90\x1a\xf24\xa0\x1b\xe2\x17\x90\x1c\xd2\x16\xa0\x1d\xc1\xf9\x90\x1e\xb1\xf8\xa0\x1f\xa1ې v+ !\x81\xbd\x90\"V\r #j\xda\x10$5" + + "\xef %J\xbc\x10&\x15\xd1 '*\x9e\x10'\xfe\xed\xa0)\n\x80\x10)\xdeϠ*\xeab\x10+\xbe\xb1\xa0,\xd3~\x90-\x9e\x93\xa0.\xb3`\x90/~u\xa00\x93B\x901g\x92 2s" + + "$\x903Gt 4S\x06\x905'V 62\xe8\x907\a8 8\x1c\x05\x108\xe7\x1a 9\xfb\xe7\x10:\xc6\xfc ;\xdb\xc9\x10<\xb0\x18\xa0=\xbb\xab\x10>\x8f\xfa\xa0?\x9b\x8d\x10@o" + + "ܠA\x84\xa9\x90BO\xbe\xa0Cd\x8b\x90D/\xa0\xa0EDm\x90E\xf3\xd3 G-\x8a\x10Gӵ I\rl\x10I\xb3\x97 J\xedN\x10K\x9c\xb3\xa0L\xd6j\x90M|\x95\xa0N\xb6" + + "L\x90O\\w\xa0P\x96.\x90Q\x8f\xfa\xa0\x00\x00\x00\x00" + + "?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 " + + "\x00\x00\x00\x00G-\x8a\x10\x00\x00\x00\x00Gӵ \x00\x00\x00\x00I\rl\x10\x00\x00\x00\x00I\xb3\x97 \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00" + + "M|\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\\w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q\x8f\xec\x90?\x9b\u007f\x00@oΐA\x84\x9b\x80BO\xb0\x90Cd}\x80D/\x92\x90ED_\x80E" + + "\xf3\xc5\x10G-|\x00Gӧ\x10I\r^\x00I\xb3\x89\x10J\xed@\x00K\x9c\xa5\x90L\xd6\\\x80M|\x87\x90N\xb6>\x80O\\i\x90P\x96 \x80Q\x8f\xec\x90\x00\x00\x00\x00?\x9b\u007f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}" + + "\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x00\x00\x00\x00G-|\x00\x00\x00\x00\x00Gӧ\x10\x00\x00\x00\x00I\r^\x00\x00\x00\x00\x00I\xb3\x89\x10\x00\x00\x00" + + "\x00J\xed@\x00\x00\x00\x00\x00K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\\\x80\x00\x00\x00\x00M|\x87\x90\x00\x00\x00\x00N\xb6>\x80\x00\x00\x00\x00O\\i\x90\x00\x00\x00\x00P\x96 \x80\x00\x00\x00\x00Q\x8f\xd0p?\x9bb\xe0@o\xb2pA\x84\u007f`BO\x94pCda`D/vpEDC`E\xf3\xa8\xf0G-_\xe0Gӊ\xf0I\rA" + + "\xe0I\xb3l\xf0J\xed#\xe0K\x9c\x89pL\xd6@`M|kpN\xb6\"`O\\MpP\x96\x04`Q\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\u007f`\x00\x00\x00\x00B" + + "O\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x00\x00\x00\x00G-_\xe0\x00\x00\x00\x00Gӊ\xf0\x00\x00\x00\x00I\rA\xe0\x00" + + "\x00\x00\x00I\xb3l\xf0\x00\x00\x00\x00J\xed#\xe0\x00\x00\x00\x00K\x9c\x89p\x00\x00\x00\x00L\xd6@`\x00\x00\x00\x00M|kp\x00\x00\x00\x00N\xb6\"`\x00\x00\x00\x00O\\Mp\x00\x00\x00\x00P" + + "\x96\x04`\x00\x00\x00\x00Q\x8f\xd0p?\x9bb\xe0@o" + + "\xb2pA\x84\u007f`BO\x94pCda`D/vpEDC`E\xf3\xa8\xf0G-_\xe0Gӊ\xf0I\rA\xe0I\xb3l\xf0J\xed#\xe0K\x9c\x89pL\xd6@`M|kpN\xb6" + + "\"`O\\MpP\x96\x04`Q\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84" + + "\u007f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x00\x00\x00\x00G-_\xe0\x00\x00\x00\x00Gӊ\xf0\x00\x00" + + "\x00\x00I\rA\xe0\x00\x00\x00\x00I\xb3l\xf0\x00\x00\x00\x00J\xed#\xe0\x00\x00\x00\x00K\x9c\x89p\x00\x00\x00\x00L\xd6@`\x00\x00\x00\x00M|kp\x00\x00\x00\x00N\xb6\"`\x00\x00\x00\x00O\\" + + "Mp\x00\x00\x00\x00P\x96\x04`\x00\x00\x00\x00Q\x8f\xec" + + "\x90?\x9b\u007f\x00@o\xc0\x80A\x84\x8dpBO\xa2\x80CdopD/\x84\x80EDQpE\xf3\xb7\x00G-m\xf0Gә\x00I\rO\xf0I\xb3{\x00J\xed1\xf0K\x9c\x97\x80L\xd6N" + + "pM|y\x80N\xb60pO\\[\x80P\x96\x12pQ<=\x80Ru\xf4pS\x1c\x1f\x80TU\xd6pT\xfc\x01\x80V5\xb8pV\xe5\x1e\x00X\x1e\xd4\xf0X\xc5\x00\x00Y\xfe\xb6\xf0Z\xa4\xe2" + + "\x00[ޘ\xf0\\\x84\xc4\x00]\xbez\xf0^d\xa6\x00_\x9e\\\xf0`M\u0080a\x87ypb-\xa4\x80cg[pd\r\x86\x80eG=pe\xedh\x80g'\x1fpg\xcdJ\x80i\a\x01" + + "pi\xad,\x80j\xe6\xe3pk\x96I\x00l\xcf\xff\xf0mv+\x00n\xaf\xe1\xf0oV\r\x00p\x8f\xc3\xf0q5\xef\x00ro\xa5\xf0s\x15\xd1\x00tO\x87\xf0t\xfe\xed\x80v8\xa4pv\xde\xcf" + + "\x80x\x18\x86px\xbe\xb1\x80y\xf8hpz\x9e\x93\x80{\xd8Jp|~u\x80}\xb8,p~^W\x80\u007f\x98\x0ep\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\xff\xff\xa0\xed\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xb9\xb0\x01\x14\xff\xff\xab\xa0\x00\x18LMT\x00MDT\x00MST" + + "\x00MWT\x00MPT\x00CDT\x00CST\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x01\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00" + + "\x00\x00\x00\x00\x00\x00\x96\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xff\xcb" + + "\x89\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff" + + "\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06" + + "@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00" + + "\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14" + + "YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00" + + "\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"" + + "U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00" + + "\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000" + + "\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00" + + "\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>" + + "\x8f\xec\x90\x00\x00\x00\x00?\x9b\u007f\x00\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00" + + "\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G-m\xf0\x00\x00\x00\x00Gә\x00\x00\x00\x00\x00I\rO\xf0\x00\x00\x00\x00I\xb3{\x00\x00\x00\x00\x00J\xed1\xf0\x00\x00\x00\x00K\x9c\x97\x80\x00\x00\x00\x00L" + + "\xd6Np\x00\x00\x00\x00M|y\x80\x00\x00\x00\x00N\xb60p\x00\x00\x00\x00O\\[\x80\x00\x00\x00\x00P\x96\x12p\x00\x00\x00\x00Q<=\x80\x00\x00\x00\x00Ru\xf4p\x00\x00\x00\x00S\x1c\x1f\x80\x00" + + "\x00\x00\x00TU\xd6p\x00\x00\x00\x00T\xfc\x01\x80\x00\x00\x00\x00V5\xb8p\x00\x00\x00\x00V\xe5\x1e\x00\x00\x00\x00\x00X\x1e\xd4\xf0\x00\x00\x00\x00X\xc5\x00\x00\x00\x00\x00\x00Y\xfe\xb6\xf0\x00\x00\x00\x00Z" + + "\xa4\xe2\x00\x00\x00\x00\x00[ޘ\xf0\x00\x00\x00\x00\\\x84\xc4\x00\x00\x00\x00\x00]\xbez\xf0\x00\x00\x00\x00^d\xa6\x00\x00\x00\x00\x00_\x9e\\\xf0\x00\x00\x00\x00`M\u0080\x00\x00\x00\x00a\x87yp\x00" + + "\x00\x00\x00b-\xa4\x80\x00\x00\x00\x00cg[p\x00\x00\x00\x00d\r\x86\x80\x00\x00\x00\x00eG=p\x00\x00\x00\x00e\xedh\x80\x00\x00\x00\x00g'\x1fp\x00\x00\x00\x00g\xcdJ\x80\x00\x00\x00\x00i" + + "\a\x01p\x00\x00\x00\x00i\xad,\x80\x00\x00\x00\x00j\xe6\xe3p\x00\x00\x00\x00k\x96I\x00\x00\x00\x00\x00l\xcf\xff\xf0\x00\x00\x00\x00mv+\x00\x00\x00\x00\x00n\xaf\xe1\xf0\x00\x00\x00\x00oV\r\x00\x00" + + "\x00\x00\x00p\x8f\xc3\xf0\x00\x00\x00\x00q5\xef\x00\x00\x00\x00\x00ro\xa5\xf0\x00\x00\x00\x00s\x15\xd1\x00\x00\x00\x00\x00tO\x87\xf0\x00\x00\x00\x00t\xfe\xed\x80\x00\x00\x00\x00v8\xa4p\x00\x00\x00\x00v" + + "\xdeπ\x00\x00\x00\x00x\x18\x86p\x00\x00\x00\x00x\xbe\xb1\x80\x00\x00\x00\x00y\xf8hp\x00\x00\x00\x00z\x9e\x93\x80\x00\x00\x00\x00{\xd8Jp\x00\x00\x00\x00|~u\x80\x00\x00\x00\x00}\xb8,p\x00" + + "\x00\x00\x00~^W\x80\x00\x00\x00\x00\u007f\x98\x0ep\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xa0\xed\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d" + + "\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xb9\xb0\x01\x14\xff\xff\xab\xa0\x00\x18LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CDT\x00CST\x00\x00\x00\x00\x00\x01" + + "\x00\x00\x00\x00\x00\x00\x01\x00\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP4?\x8e\xc5L\t\x00\x00L\t\x00\x00\x1b" + + "\x00\x1c\x00America/North_Dakota/CenterUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZ" + + "if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x96\x00\x00\x00\a\x00\x00\x00\x1c\x80\x00\x00\x00\x9e\xa6:\x90\x9f\xbb\a\x80\xa0\x86\x1c\x90\xa1\x9a" + + "\xe9\x80ˉ\f\x90\xd2#\xf4p\xd2a\x18\x00\xfa\xf8u\x10\xfb\xe8X\x00\xfc\xd8W\x10\xfd\xc8:\x00\xfe\xb89\x10\xff\xa8\x1c\x00\x00\x98\x1b\x10\x01\x87\xfe\x00\x02w\xfd\x10\x03q\x1a\x80\x04a\x19\x90\x05P" + + "\xfc\x80\x06@\xfb\x90\a0ހ\a\x8d5\x90\t\x10\xc0\x80\t\xad\xb1\x10\n\xf0\xa2\x80\vࡐ\fٿ\x00\r\xc0\x83\x90\x0e\xb9\xa1\x00\x0f\xa9\xa0\x10\x10\x99\x83\x00\x11\x89\x82\x10\x12ye\x00\x13i" + + "d\x10\x14YG\x00\x15IF\x10\x169)\x00\x17)(\x10\x18\"E\x80\x19\t\n\x10\x1a\x02'\x80\x1a\xf2&\x90\x1b\xe2\t\x80\x1c\xd2\b\x90\x1d\xc1\xeb\x80\x1e\xb1\xea\x90\x1f\xa1̀ v\x1d\x10!\x81" + + "\xaf\x80\"U\xff\x10#j\xcc\x00$5\xe1\x10%J\xae\x00&\x15\xc3\x10'*\x90\x00'\xfeߐ)\nr\x00)\xde\xc1\x90*\xeaT\x00+\xbe\x95\x80,\xd3bp-\x9ew\x80.\xb3Dp/~" + + "Y\x800\x93&p1gv\x002s\bp3GX\x004R\xeap5':\x0062\xccp7\a\x1c\x008\x1b\xe8\xf08\xe6\xfe\x009\xfb\xca\xf0:\xc6\xe0\x00;۬\xf0<\xaf\xfc\x80=\xbb" + + "\x8e\xf0>\x8fހ?\x9bp\xf0@o\xc0\x80A\x84\x8dpBO\xa2\x80CdopD/\x84\x80EDQpE\xf3\xb7\x00G-m\xf0Gә\x00I\rO\xf0I\xb3{\x00J\xed1\xf0K\x9c" + + "\x97\x80L\xd6NpM|y\x80N\xb60pO\\[\x80P\x96\x12pQ<=\x80Ru\xf4pS\x1c\x1f\x80TU\xd6pT\xfc\x01\x80V5\xb8pV\xe5\x1e\x00X\x1e\xd4\xf0X\xc5\x00\x00Y\xfe" + + "\xb6\xf0Z\xa4\xe2\x00[ޘ\xf0\\\x84\xc4\x00]\xbez\xf0^d\xa6\x00_\x9e\\\xf0`M\u0080a\x87ypb-\xa4\x80cg[pd\r\x86\x80eG=pe\xedh\x80g'\x1fpg\xcd" + + "J\x80i\a\x01pi\xad,\x80j\xe6\xe3pk\x96I\x00l\xcf\xff\xf0mv+\x00n\xaf\xe1\xf0oV\r\x00p\x8f\xc3\xf0q5\xef\x00ro\xa5\xf0s\x15\xd1\x00tO\x87\xf0t\xfe\xed\x80v8" + + "\xa4pv\xdeπx\x18\x86px\xbe\xb1\x80y\xf8hpz\x9e\x93\x80{\xd8Jp|~u\x80}\xb8,p~^W\x80\u007f\x98\x0ep\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xa1\b\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xb9\xb0\x01\x14\xff\xff\xab\xa0\x00\x18LMT\x00MD" + + "T\x00MST\x00MWT\x00MPT\x00CDT\x00CST\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x01\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a" + + "\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x96\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80" + + "\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff" + + "\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80" + + "\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00" + + "\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10" + + "\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00" + + "\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80" + + "\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00" + + ")\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80" + + "\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x00" + + "7\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0" + + "\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00" + + "EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G-m\xf0\x00\x00\x00\x00Gә\x00\x00\x00\x00\x00I\rO\xf0\x00\x00\x00\x00I\xb3{\x00\x00\x00\x00\x00J\xed1\xf0\x00\x00\x00\x00K\x9c\x97\x80" + + "\x00\x00\x00\x00L\xd6Np\x00\x00\x00\x00M|y\x80\x00\x00\x00\x00N\xb60p\x00\x00\x00\x00O\\[\x80\x00\x00\x00\x00P\x96\x12p\x00\x00\x00\x00Q<=\x80\x00\x00\x00\x00Ru\xf4p\x00\x00\x00\x00" + + "S\x1c\x1f\x80\x00\x00\x00\x00TU\xd6p\x00\x00\x00\x00T\xfc\x01\x80\x00\x00\x00\x00V5\xb8p\x00\x00\x00\x00V\xe5\x1e\x00\x00\x00\x00\x00X\x1e\xd4\xf0\x00\x00\x00\x00X\xc5\x00\x00\x00\x00\x00\x00Y\xfe\xb6\xf0" + + "\x00\x00\x00\x00Z\xa4\xe2\x00\x00\x00\x00\x00[ޘ\xf0\x00\x00\x00\x00\\\x84\xc4\x00\x00\x00\x00\x00]\xbez\xf0\x00\x00\x00\x00^d\xa6\x00\x00\x00\x00\x00_\x9e\\\xf0\x00\x00\x00\x00`M\u0080\x00\x00\x00\x00" + + "a\x87yp\x00\x00\x00\x00b-\xa4\x80\x00\x00\x00\x00cg[p\x00\x00\x00\x00d\r\x86\x80\x00\x00\x00\x00eG=p\x00\x00\x00\x00e\xedh\x80\x00\x00\x00\x00g'\x1fp\x00\x00\x00\x00g\xcdJ\x80" + + "\x00\x00\x00\x00i\a\x01p\x00\x00\x00\x00i\xad,\x80\x00\x00\x00\x00j\xe6\xe3p\x00\x00\x00\x00k\x96I\x00\x00\x00\x00\x00l\xcf\xff\xf0\x00\x00\x00\x00mv+\x00\x00\x00\x00\x00n\xaf\xe1\xf0\x00\x00\x00\x00" + + "oV\r\x00\x00\x00\x00\x00p\x8f\xc3\xf0\x00\x00\x00\x00q5\xef\x00\x00\x00\x00\x00ro\xa5\xf0\x00\x00\x00\x00s\x15\xd1\x00\x00\x00\x00\x00tO\x87\xf0\x00\x00\x00\x00t\xfe\xed\x80\x00\x00\x00\x00v8\xa4p" + + "\x00\x00\x00\x00v\xdeπ\x00\x00\x00\x00x\x18\x86p\x00\x00\x00\x00x\xbe\xb1\x80\x00\x00\x00\x00y\xf8hp\x00\x00\x00\x00z\x9e\x93\x80\x00\x00\x00\x00{\xd8Jp\x00\x00\x00\x00|~u\x80\x00\x00\x00\x00" + + "}\xb8,p\x00\x00\x00\x00~^W\x80\x00\x00\x00\x00\u007f\x98\x0ep\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xa1\b\x00\x00\xff\xff\xab\xa0" + + "\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xb9\xb0\x01\x14\xff\xff\xab\xa0\x00\x18LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CDT\x00CST\x00" + + "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x01\x00\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xed\r#\xdeL\t\x00\x00" + + "L\t\x00\x00\x1b\x00\x1c\x00America/North_Dakota/BeulahUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14" + + "\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x96\x00\x00\x00\a\x00\x00\x00\x1c\x80\x00\x00\x00\x9e\xa6:\x90\x9f\xbb\a\x80\xa0" + + "\x86\x1c\x90\xa1\x9a\xe9\x80ˉ\f\x90\xd2#\xf4p\xd2a\x18\x00\xfa\xf8u\x10\xfb\xe8X\x00\xfc\xd8W\x10\xfd\xc8:\x00\xfe\xb89\x10\xff\xa8\x1c\x00\x00\x98\x1b\x10\x01\x87\xfe\x00\x02w\xfd\x10\x03q\x1a\x80\x04" + + "a\x19\x90\x05P\xfc\x80\x06@\xfb\x90\a0ހ\a\x8d5\x90\t\x10\xc0\x80\t\xad\xb1\x10\n\xf0\xa2\x80\vࡐ\fٿ\x00\r\xc0\x83\x90\x0e\xb9\xa1\x00\x0f\xa9\xa0\x10\x10\x99\x83\x00\x11\x89\x82\x10\x12" + + "ye\x00\x13id\x10\x14YG\x00\x15IF\x10\x169)\x00\x17)(\x10\x18\"E\x80\x19\t\n\x10\x1a\x02'\x80\x1a\xf2&\x90\x1b\xe2\t\x80\x1c\xd2\b\x90\x1d\xc1\xeb\x80\x1e\xb1\xea\x90\x1f\xa1̀ " + + "v\x1d\x10!\x81\xaf\x80\"U\xff\x10#j\xcc\x00$5\xe1\x10%J\xae\x00&\x15\xc3\x10'*\x90\x00'\xfeߐ)\nr\x00)\xde\xc1\x90*\xeaT\x00+\xbe\xa3\x90,\xd3p\x80-\x9e\x85\x90." + + "\xb3R\x80/~g\x900\x934\x801g\x84\x102s\x16\x803Gf\x104R\xf8\x805'H\x1062ڀ7\a*\x108\x1b\xf7\x008\xe7\f\x109\xfb\xd9\x00:\xc6\xee\x10;ۻ\x00<" + + "\xb0\n\x90=\xbb\x9d\x00>\x8f\xec\x90?\x9b\u007f\x00@oΐA\x84\x9b\x80BO\xb0\x90Cd}\x80D/\x92\x90ED_\x80E\xf3\xc5\x10G-|\x00Gӧ\x10I\r^\x00I\xb3\x89\x10J" + + "\xed@\x00K\x9c\xa5\x90L\xd6\\\x80M|y\x80N\xb60pO\\[\x80P\x96\x12pQ<=\x80Ru\xf4pS\x1c\x1f\x80TU\xd6pT\xfc\x01\x80V5\xb8pV\xe5\x1e\x00X\x1e\xd4\xf0X" + + "\xc5\x00\x00Y\xfe\xb6\xf0Z\xa4\xe2\x00[ޘ\xf0\\\x84\xc4\x00]\xbez\xf0^d\xa6\x00_\x9e\\\xf0`M\u0080a\x87ypb-\xa4\x80cg[pd\r\x86\x80eG=pe\xedh\x80g" + + "'\x1fpg\xcdJ\x80i\a\x01pi\xad,\x80j\xe6\xe3pk\x96I\x00l\xcf\xff\xf0mv+\x00n\xaf\xe1\xf0oV\r\x00p\x8f\xc3\xf0q5\xef\x00ro\xa5\xf0s\x15\xd1\x00tO\x87\xf0t" + + "\xfe\xed\x80v8\xa4pv\xdeπx\x18\x86px\xbe\xb1\x80y\xf8hpz\x9e\x93\x80{\xd8Jp|~u\x80}\xb8,p~^W\x80\u007f\x98\x0ep\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xa0\x95\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xb9\xb0\x01\x14\xff\xff\xab\xa0\x00\x18L" + + "MT\x00MDT\x00MST\x00MWT\x00MPT\x00CDT\x00CST\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x01\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x96\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff" + + "\xff\xa1\x9a\xe9\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:" + + "\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00" + + "\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\v\xe0\xa1" + + "\x90\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00" + + "\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'" + + "\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00" + + "\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfe\xdf" + + "\x90\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00" + + "\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062\xda" + + "\x80\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00" + + "\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\u007f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92" + + "\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x00\x00\x00\x00G-|\x00\x00\x00\x00\x00Gӧ\x10\x00\x00\x00\x00I\r^\x00\x00\x00\x00\x00I\xb3\x89\x10\x00\x00\x00\x00J\xed@\x00\x00\x00\x00" + + "\x00K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\\\x80\x00\x00\x00\x00M|y\x80\x00\x00\x00\x00N\xb60p\x00\x00\x00\x00O\\[\x80\x00\x00\x00\x00P\x96\x12p\x00\x00\x00\x00Q<=\x80\x00\x00\x00\x00Ru\xf4" + + "p\x00\x00\x00\x00S\x1c\x1f\x80\x00\x00\x00\x00TU\xd6p\x00\x00\x00\x00T\xfc\x01\x80\x00\x00\x00\x00V5\xb8p\x00\x00\x00\x00V\xe5\x1e\x00\x00\x00\x00\x00X\x1e\xd4\xf0\x00\x00\x00\x00X\xc5\x00\x00\x00\x00\x00" + + "\x00Y\xfe\xb6\xf0\x00\x00\x00\x00Z\xa4\xe2\x00\x00\x00\x00\x00[ޘ\xf0\x00\x00\x00\x00\\\x84\xc4\x00\x00\x00\x00\x00]\xbez\xf0\x00\x00\x00\x00^d\xa6\x00\x00\x00\x00\x00_\x9e\\\xf0\x00\x00\x00\x00`M\xc2" + + "\x80\x00\x00\x00\x00a\x87yp\x00\x00\x00\x00b-\xa4\x80\x00\x00\x00\x00cg[p\x00\x00\x00\x00d\r\x86\x80\x00\x00\x00\x00eG=p\x00\x00\x00\x00e\xedh\x80\x00\x00\x00\x00g'\x1fp\x00\x00\x00" + + "\x00g\xcdJ\x80\x00\x00\x00\x00i\a\x01p\x00\x00\x00\x00i\xad,\x80\x00\x00\x00\x00j\xe6\xe3p\x00\x00\x00\x00k\x96I\x00\x00\x00\x00\x00l\xcf\xff\xf0\x00\x00\x00\x00mv+\x00\x00\x00\x00\x00n\xaf\xe1" + + "\xf0\x00\x00\x00\x00oV\r\x00\x00\x00\x00\x00p\x8f\xc3\xf0\x00\x00\x00\x00q5\xef\x00\x00\x00\x00\x00ro\xa5\xf0\x00\x00\x00\x00s\x15\xd1\x00\x00\x00\x00\x00tO\x87\xf0\x00\x00\x00\x00t\xfe\xed\x80\x00\x00\x00" + + "\x00v8\xa4p\x00\x00\x00\x00v\xdeπ\x00\x00\x00\x00x\x18\x86p\x00\x00\x00\x00x\xbe\xb1\x80\x00\x00\x00\x00y\xf8hp\x00\x00\x00\x00z\x9e\x93\x80\x00\x00\x00\x00{\xd8Jp\x00\x00\x00\x00|~u" + + "\x80\x00\x00\x00\x00}\xb8,p\x00\x00\x00\x00~^W\x80\x00\x00\x00\x00\u007f\x98\x0ep\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xa0\x95\x00" + + "\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xb9\xb0\x01\x14\xff\xff\xab\xa0\x00\x18LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CDT" + + "\x00CST\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x01\x00\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPƘ<" + + "&\x90\b\x00\x00\x90\b\x00\x00\x11\x00\x1c\x00America/Glace_BayUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZ" + + "if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x8c\x00\x00\x00\x05\x00\x00\x00\x14\x80\xf1\xa84\x9e\xb8\x85`\x9f\xba\xddPˈ\xe2`\xd2#" + + "\xf4p\xd2`\xed\xd0\xe0\x9e?`\xe1i8P\x04`\xef`\x05P\xd2P\x06@\xd1`\a0\xb4P\b \xb3`\t\x10\x96P\n\x00\x95`\n\xf0xP\v\xe0w`\fٔ\xd0\r\xc0Y`\x0e\xb9" + + "v\xd0\x0f\xa9u\xe0\x10\x99X\xd0\x11\x89W\xe0\x12y:\xd0\x13i9\xe0\x14Y\x1c\xd0\x15I\x1b\xe0\x168\xfe\xd0\x17(\xfd\xe0\x18\"\x1bP\x19\b\xdf\xe0\x1a\x01\xfdP\x1a\xf1\xfc`\x1b\xe1\xdfP\x1c\xd1" + + "\xde`\x1d\xc1\xc1P\x1e\xb1\xc0`\x1f\xa1\xa3P u\xf2\xe0!\x81\x85P\"U\xd4\xe0#j\xa1\xd0$5\xb6\xe0%J\x83\xd0&\x15\x98\xe0'*e\xd0'\xfe\xb5`)\nG\xd0)ޗ`*\xea" + + ")\xd0+\xbey`,\xd3FP-\x9e[`.\xb3(P/~=`0\x93\nP1gY\xe02r\xecP3G;\xe04R\xceP5'\x1d\xe062\xb0P7\x06\xff\xe08\x1b\xcc\xd08\xe6" + + "\xe1\xe09\xfb\xae\xd0:\xc6\xc3\xe0;ې\xd0<\xaf\xe0`=\xbbr\xd0>\x8f\xc2`?\x9bT\xd0@o\xa4`A\x84qPBO\x86`CdSPD/h`ED5PE\xf3\x9a\xe0G-" + + "Q\xd0G\xd3|\xe0I\r3\xd0I\xb3^\xe0J\xed\x15\xd0K\x9c{`L\xd62PM|]`N\xb6\x14PO\\?`P\x95\xf6PQ\x8f\xc2`\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@o\xa4`\x00\x00\x00\x00A\x84qP\x00\x00" + + "\x00\x00BO\x86`\x00\x00\x00\x00CdSP\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x9a\xe0\x00\x00\x00\x00G-Q\xd0\x00\x00\x00\x00G\xd3|\xe0\x00\x00\x00\x00I\r" + + "3\xd0\x00\x00\x00\x00I\xb3^\xe0\x00\x00\x00\x00J\xed\x15\xd0\x00\x00\x00\x00K\x9c{`\x00\x00\x00\x00L\xd62P\x00\x00\x00\x00M|]`\x00\x00\x00\x00N\xb6\x14P\x00\x00\x00\x00O\\?`\x00\x00" + + "\x00\x00P\x95\xf6P\x00\x00\x00\x00Q\x8f\xd0p?\x9bb\xe0@o\xb2pA\x84\u007f`BO\x94pCda`D/vpEDC`E\xf3\xa8\xf0G-_\xe0Gӊ\xf0I\rA\xe0I\xb3l\xf0J\xed#\xe0K" + + "\x9c\x89pL\xd6@`M|kpN\xb6\"`O\\MpP\x96\x04`Q\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\u007f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp" + + "\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x00\x00\x00\x00G-_\xe0\x00\x00\x00\x00Gӊ\xf0\x00\x00\x00\x00I\rA\xe0\x00\x00\x00\x00I\xb3l\xf0\x00\x00\x00\x00J\xed#\xe0\x00\x00\x00\x00" + + "K\x9c\x89p\x00\x00\x00\x00L\xd6@`\x00\x00\x00\x00M|kp\x00\x00\x00\x00N\xb6\"`\x00\x00\x00\x00O\\Mp\x00\x00\x00\x00P\x96\x04`\x00\x00\x00\x00Q\x00\x00\x00\x06\x00\x00\x00\x14\x80\x00\x00\x00\xa2\x92\x8f0" + + "\xb6{R@\xb7\x1aɰ\xb8\x1e\x8f@\xb8\xd4p0\xba\x17}\xc0\xba\xb5\xa3\xb0\xbb\xf8\xb1@\xbc\x96\xd70\xbd\xd9\xe4\xc0\xbex\n\xb0\xbf\xbb\x18@\xc0Z\x8f\xb0\xc1\x9d\x9d@\xc2;\xc30\xc3~\xd0\xc0" + + "\xc4\x1c\xf6\xb0\xc5`\x04@\xc5\xfe*0\xc7A7\xc0\xc7\xe0\xaf0ȁ\x94@\xcaM\xa1\xb0\xca\xee\x86\xc0\xceM\xff0ΰ\xed\xc0\xd3)5\xb0\xd4Cd\xc0\xf4=\b0\xf4\x9f\xf6\xc0\xf5\x05l0" + + "\xf62\x10@\xf6柰\xf8\x13C\xc0\xf8\xc7\xd30\xf9\xf4w@\xfa\xd36\xb0\xfb\xc35\xc0\xfc\xbcS0\xfd\xacR@\xfe\x9c50\xff\x8c4@\a\xa3J\xb0\b$o\xa0#\x94\xb5\xb0$\x10\x94\xa0" + + "%7\xf2\xb0%\xf0v\xa0'!\x0f0'\xd0X\xa0)\x00\xff@)\xb0:\xa0*\xe0\xd30+\x99W 7\xf6ư8\xbf*\xb0Gw\t\xb0G\xdc\u007f H\xfa\xa2\xb0I\xbca \u007f\xff\xff\xff" + + "\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x04\x05\x04" + + "\x05\x05\xff\xff\xc3\xd0\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00TZ" + + "if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xad\xb0\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff" + + "\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96" + + "\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff" + + "\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee" + + "\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff" + + "\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbc" + + "S0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00" + + "\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99" + + "W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\u007f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\x05" + + "\xff\xff\xc3\xd0\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-0" + + "3>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xee\xd7\x17\xe1\xd4\n\x00\x00\xd4\n\x00\x00\x12\x00\x1c\x00America/LouisvilleUT\t\x00\x03nӧ" + + "^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xb2\x00\x00\x00\a" + + "\x00\x00\x00\x1c\x80\x00\x00\x00\x9e\xa6,\x80\x9f\xba\xf9p\xa0\x86\x0e\x80\xa1\x9a\xdbp\xa4s\xf7\x00\xa5\x16\x11p\xca\rN\x80\xca\xd8Gpˈ\xfe\x80\xd2#\xf4p\xd2a\t\xf0\xd3u\xd7\x1cӤ\tp" + + "\xda\xfe\xb5\x80\xdb\xc0s\xf0\xdcޗ\x80ݩ\x90p\u07bey\x80߉rp\xe0\x9e[\x80\xe1iTp\xe2~=\x80\xe3I6p\xe4^\x1f\x80\xe5)\x18p\xe6G<\x00\xe77\x1e\xf0\xe8'\x1e\x00" + + "\xe9\x17\x00\xf0\xea\a\x00\x00\xea\xf6\xe2\xf0\xeb\xe6\xe2\x00\xec\xd6\xc4\xf0\xed\xc6\xc4\x00\xee\xbf\xe1p\xef\xaf\xe0\x80\xf0\x1e\x90p\xfc\xd8:\xf0\xfd\xc8\x1d\xe0\xfe\xb8\x1c\xf0\xff\xa7\xff\xe0\x00\x97\xfe\xf0\x01\x87\xe1\xe0" + + "\x02w\xe0\xf0\x03p\xfe`\x04`\xfdp\x05P\xe0`\x06@\xdfp\a0\xc2`\a\x8d\x19p\t\x10\xb2p\t\xad\x94\xf0\n\xf0\x86`\v\xe0\x85p\f٢\xe0\r\xc0gp\x0e\xb9\x84\xe0\x0f\xa9\x83\xf0" + + "\x10\x99f\xe0\x11\x89e\xf0\x12yH\xe0\x13iG\xf0\x14Y*\xe0\x15I)\xf0\x169\f\xe0\x17)\v\xf0\x18\")`\x19\b\xed\xf0\x1a\x02\v`\x1a\xf2\np\x1b\xe1\xed`\x1c\xd1\xecp\x1d\xc1\xcf`" + + "\x1e\xb1\xcep\x1f\xa1\xb1` v\x00\xf0!\x81\x93`\"U\xe2\xf0#j\xaf\xe0$5\xc4\xf0%J\x91\xe0&\x15\xa6\xf0'*s\xe0'\xfe\xc3p)\nU\xe0)ޥp*\xea7\xe0+\xbe\x87p" + + ",\xd3T`-\x9eip.\xb36`/~Kp0\x93\x18`1gg\xf02r\xfa`3GI\xf04R\xdc`5'+\xf062\xbe`7\a\r\xf08\x1b\xda\xe08\xe6\xef\xf09\xfb\xbc\xe0" + + ":\xc6\xd1\xf0;۞\xe0<\xaf\xeep=\xbb\x80\xe0>\x8f\xd0p?\x9bb\xe0@o\xb2pA\x84\u007f`BO\x94pCda`D/vpEDC`E\xf3\xa8\xf0G-_\xe0Gӊ\xf0" + + "I\rA\xe0I\xb3l\xf0J\xed#\xe0K\x9c\x89pL\xd6@`M|kpN\xb6\"`O\\MpP\x96\x04`Q\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\u007f`\x00\x00" + + "\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x00\x00\x00\x00G-_\xe0\x00\x00\x00\x00Gӊ\xf0\x00\x00\x00\x00I\r" + + "A\xe0\x00\x00\x00\x00I\xb3l\xf0\x00\x00\x00\x00J\xed#\xe0\x00\x00\x00\x00K\x9c\x89p\x00\x00\x00\x00L\xd6@`\x00\x00\x00\x00M|kp\x00\x00\x00\x00N\xb6\"`\x00\x00\x00\x00O\\Mp\x00\x00" + + "\x00\x00P\x96\x04`\x00\x00\x00\x00Q\x8f\xfa\xa0?\x9b\x8d\x10@oܠA\x84" + + "\xa9\x90BO\xbe\xa0Cd\x8b\x90D/\xa0\xa0EDm\x90F\x0f\x82\xa0G$O\x90G\xf8\x9f I\x041\x90I\u0601 J\xe4\x13\x90K\x9c\xb3\xa0L\xd6j\x90M|\x95\xa0N\xb6L\x90O\\" + + "w\xa0P\x96.\x90Q\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00B" + + "O\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00F\x0f\x82\xa0\x00\x00\x00\x00G$O\x90\x00\x00\x00\x00G\xf8\x9f \x00\x00\x00\x00I\x041\x90\x00" + + "\x00\x00\x00I\u0601 \x00\x00\x00\x00J\xe4\x13\x90\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00M|\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\\w\xa0\x00\x00\x00\x00P" + + "\x96.\x90\x00\x00\x00\x00Q\x8f\xec\x90?\x9b\u007f\x00@oΐA\x84\x9b\x80BO\xb0\x90Cd" + + "}\x80D/\x92\x90ED_\x80E\xf3\xc5\x10G-|\x00Gӧ\x10I\r^\x00I\xb3\x89\x10J\xed@\x00K\x9c\xa5\x90L\xd6\\\x80M|\x87\x90N\xb6>\x80O\\i\x90P\x96 \x80Q<" + + "K\x90Rv\x02\x80S\x1c-\x90TU\xe4\x80T\xfc\x0f\x90V5ƀV\xe5,\x10X\x1e\xe3\x00X\xc5\x0e\x10Y\xfe\xc5\x00Z\xa4\xf0\x10[ާ\x00\\\x84\xd2\x10]\xbe\x89\x00^d\xb4\x10_\x9e" + + "k\x00`MАa\x87\x87\x80b-\xb2\x90cgi\x80d\r\x94\x90eGK\x80e\xedv\x90g'-\x80g\xcdX\x90i\a\x0f\x80i\xad:\x90j\xe6\xf1\x80k\x96W\x10l\xd0\x0e\x00mv" + + "9\x10n\xaf\xf0\x00oV\x1b\x10p\x8f\xd2\x00q5\xfd\x10ro\xb4\x00s\x15\xdf\x10tO\x96\x00t\xfe\xfb\x90v8\xb2\x80v\xdeݐx\x18\x94\x80x\xbe\xbf\x90y\xf8v\x80z\x9e\xa1\x90{\xd8" + + "X\x80|~\x83\x90}\xb8:\x80~^e\x90\u007f\x98\x1c\x80\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\x9d\x94" + + "\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST\x00MWT\x00MPT\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01TZif" + + "2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x9e\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff" + + "\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xff\xa2e\xfe\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4E\xe0\x90\xff\xff\xff\xff\xa4\x8f\xa6\x80\xff\xff\xff\xffˉ\f\x90" + + "\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\x94\x00\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff\xfa\bv\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff" + + "\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10" + + "\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00" + + "\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00" + + "\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00" + + "\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90" + + "\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00" + + "&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80" + + "\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x00" + + "4R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10" + + "\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\u007f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00" + + "BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x00\x00\x00\x00G-|\x00\x00\x00\x00\x00Gӧ\x10\x00\x00\x00\x00I\r^\x00" + + "\x00\x00\x00\x00I\xb3\x89\x10\x00\x00\x00\x00J\xed@\x00\x00\x00\x00\x00K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\\\x80\x00\x00\x00\x00M|\x87\x90\x00\x00\x00\x00N\xb6>\x80\x00\x00\x00\x00O\\i\x90\x00\x00\x00\x00" + + "P\x96 \x80\x00\x00\x00\x00Q\x8f\xec\x90?\x9b\u007f\x00@oΐA\x84\x9b\x80BO\xb0\x90Cd}\x80D/\x92\x90ED_\x80F\x0ft\x90G$A\x80G\xf8\x91\x10I\x04#\x80I\xd8s\x10J\xe4\x05\x80K" + + "\x9c\xa5\x90L\xd6\\\x80M|\x87\x90N\xb6>\x80O\\i\x90P\x96 \x80Q\x8f\xec\x90\x00\x00\x00\x00?\x9b\u007f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00" + + "\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80\x00\x00\x00\x00G\xf8\x91" + + "\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00\x00\x00\x00K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\\\x80\x00\x00\x00\x00M|\x87\x90\x00\x00\x00\x00N\xb6>\x80\x00\x00\x00" + + "\x00O\\i\x90\x00\x00\x00\x00P\x96 \x80\x00\x00\x00\x00Q\x8f\xc2`?\x9bT\xd0@o\xa4`A\x84qPBO\x86`CdSPD/h`ED5PE\xf3\x9a\xe0G-Q\xd0G\xd3" + + "|\xe0I\r3\xd0I\xb3^\xe0J\xed\x15\xd0K\x9c{`L\xd62PM|]`N\xb6\x14PO\\?`P\x95\xf6PQ\x8f\xc2`\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@o\xa4`\x00\x00\x00\x00A\x84qP\x00\x00\x00\x00BO\x86`\x00\x00\x00\x00CdSP\x00\x00\x00\x00D" + + "/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x9a\xe0\x00\x00\x00\x00G-Q\xd0\x00\x00\x00\x00G\xd3|\xe0\x00\x00\x00\x00I\r3\xd0\x00\x00\x00\x00I\xb3^\xe0\x00\x00\x00\x00J\xed\x15\xd0\x00" + + "\x00\x00\x00K\x9c{`\x00\x00\x00\x00L\xd62P\x00\x00\x00\x00M|]`\x00\x00\x00\x00N\xb6\x14P\x00\x00\x00\x00O\\?`\x00\x00\x00\x00P\x95\xf6P\x00\x00\x00\x00Q4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x9e^R@t\x03\x00\x00t\x03\x00\x00\x11" + + "\x00\x1c\x00America/AraguainaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x004\x00\x00\x00\x03\x00\x00\x00\f\x96\xaat0\xb8\x0fI\xe0\xb8\xfd@\xa0\xb9\xf140\xba\xdet \xda8\xae0\xda\xeb\xfa0" + + "\xdc\x19\xe1\xb0ܹY \xdd\xfb\x150ޛ\xde \xdfݚ0\xe0T3 \xf4\x97\xff\xb0\xf5\x05^ \xf6\xc0d0\xf7\x0e\x1e\xa0\xf8Q,0\xf8\xc7\xc5 \xfa\nҰ\xfa\xa8\xf8\xa0\xfb\xec\x060" + + "\xfc\x8b}\xa0\x1dɎ0\x1exנ\x1f\xa05\xb0 3Ϡ!\x81i0\"\vȠ#X\x10\xb0#\xe2p %7\xf2\xb0%\xd4\xc7 0\x80y01\x1dM\xa02W \xb03\x06j " + + "48T04\xf8\xc1 6 \x1f06\xcfh\xa07\xf6ư8\xb8\x85 9\xdf\xe30:\x8f,\xa0;\xc8\xff\xb0N\xf0\xa0P\x83e0Q 9\xa0\u007f\xff\xff\xff" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\xff\xff\xd2\xd0\x00\x00\xff\xff" + + "\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x004\x00\x00" + + "\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaat0\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb" + + "\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff" + + "\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec" + + "\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\x00\x00" + + "\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x000\x80y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00\x002W \xb0\x00\x00\x00\x003\x06" + + "j \x00\x00\x00\x0048T0\x00\x00\x00\x004\xf8\xc1 \x00\x00\x00\x006 \x1f0\x00\x00\x00\x006\xcfh\xa0\x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00" + + "\x00\x00:\x8f,\xa0\x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00N\xf0\xa0\x00\x00\x00\x00P\x83e0\x00\x00\x00\x00Q 9\xa0\x00\x00\x00\x00\u007f\xff" + + "\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\xff\xff\xd2\xd0\x00\x00" + + "\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPN\xf44M$\b\x00\x00$\b\x00\x00\x15\x00" + + "\x1c\x00America/Cambridge_BayUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00{\x00\x00\x00\v\x00\x00\x00%\xa1\xf2̀ˉ\f\x90\xd2#\xf4p\xd2a\x18\x00\xf7/Zp\xf8(\x85\xf0\x13" + + "id\x10\x14YG\x00\x15IF\x10\x169)\x00\x17)(\x10\x18\"E\x80\x19\t\n\x10\x1a\x02'\x80\x1a\xf2&\x90\x1b\xe2\t\x80\x1c\xd2\b\x90\x1d\xc1\xeb\x80\x1e\xb1\xea\x90\x1f\xa1̀ v\x1d\x10!" + + "\x81\xaf\x80\"U\xff\x10#j\xcc\x00$5\xe1\x10%J\xae\x00&\x15\xc3\x10'*\x90\x00'\xfeߐ)\nr\x00)\xde\xc1\x90*\xeaT\x00+\xbe\xa3\x90,\xd3p\x80-\x9e\x85\x90.\xb3R\x80/" + + "~g\x900\x934\x801g\x84\x102s\x16\x803Gf\x104R\xf8\x805'H\x1062ڀ7\a*\x108\x1b\xf7\x008\xe6\xfe\x009\xfb\xca\xf0:\x04\xe9P:\xc6\xee\x10;ۻ\x00<" + + "\xb0\n\x90=\xbb\x9d\x00>\x8f\xec\x90?\x9b\u007f\x00@oΐA\x84\x9b\x80BO\xb0\x90Cd}\x80D/\x92\x90ED_\x80E\xf3\xc5\x10G-|\x00Gӧ\x10I\r^\x00I\xb3\x89\x10J" + + "\xed@\x00K\x9c\xa5\x90L\xd6\\\x80M|\x87\x90N\xb6>\x80O\\i\x90P\x96 \x80Q\x8f\xec\x90\x00\x00\x00\x00?\x9b\u007f\x00\x00" + + "\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x00\x00\x00\x00G" + + "-|\x00\x00\x00\x00\x00Gӧ\x10\x00\x00\x00\x00I\r^\x00\x00\x00\x00\x00I\xb3\x89\x10\x00\x00\x00\x00J\xed@\x00\x00\x00\x00\x00K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\\\x80\x00\x00\x00\x00M|\x87\x90\x00" + + "\x00\x00\x00N\xb6>\x80\x00\x00\x00\x00O\\i\x90\x00\x00\x00\x00P\x96 \x80\x00\x00\x00\x00Q\x8fހ?\x9b\u007f\x00@o\xc0\x80A\x84\x9b\x80BO\xa2\x80Cd}\x80D/\x84\x80EDQpE\xf3\xb7\x00G-m\xf0Gә" + + "\x00I\rO\xf0I\xb3{\x00J\xed1\xf0K\x9c\x97\x80L\xd6NpM|y\x80N\xb60pO\\[\x80P\x96\x12pQ<=\x80Ru\xf4pS\x1c\x1f\x80TU\xd6pT\xfc\x01\x80V5\xb8" + + "pV\xe5\x1e\x00X\x1e\xd4\xf0X\xc5\x00\x00Y\xfe\xb6\xf0Z\xa4\xe2\x00[ޘ\xf0\\\x84\xc4\x00]\xbez\xf0^d\xa6\x00_\x9e\\\xf0`M\u0080a\x87ypb-\xa4\x80cg[pd\r\x86" + + "\x80eG=pe\xedh\x80g'\x1fpg\xcdJ\x80i\a\x01pi\xad,\x80j\xe6\xe3pk\x96I\x00l\xcf\xff\xf0mv+\x00n\xaf\xe1\xf0oV\r\x00p\x8f\xc3\xf0q5\xef\x00ro\xa5" + + "\xf0s\x15\xd1\x00tO\x87\xf0t\xfe\xed\x80v8\xa4pv\xdeπx\x18\x86px\xbe\xb1\x80y\xf8hpz\x9e\x93\x80{\xd8Jp|~u\x80}\xb8,p~^W\x80\u007f\x98\x0ep\x02\x01\x02" + + "\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\xff\xff\xa4\xec\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\bLMT\x00CDT\x00CST\x00CWT" + + "\x00CPT\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x01\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xba\x00\x00\x00\a\x00" + + "\x00\x00\x14\xff\xff\xff\xffd䰔\xff\xff\xff\xff\x9b\x01\xfb\xe0\xff\xff\xff\xff\x9búP\xff\xff\xff\xff\x9e\xb8\xa1\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\u00a0;\x80\xff\xff\xff\xff\xc3O\x84\xf0\xff" + + "\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xffӈh\x00\xff\xff\xff\xff\xd4S`\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd7" + + "5\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xdb\x00\a\x00\xff\xff\xff\xff\xdb\xc8\\\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff" + + "\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5" + + ")\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff" + + "\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\ue47c\xf0\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf41b\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\bv\x00\xff\xff\xff\xff\xfa" + + "\xf8g\x00\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xfe\x00\x00" + + "\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\b π\x00\x00\x00\x00\t" + + "\x10\xc0\x80\x00\x00\x00\x00\n\x00\xb1\x80\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\x92\x00\x00" + + "\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17" + + ")\x1a\x00\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00" + + "\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%" + + "J\xae\x00\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\x95\x80\x00" + + "\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003" + + "GX\x00\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005':\x00\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xd9\x00\x00" + + "\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9b\u007f\x00\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A" + + "\x84\x9b\x80\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G-m\xf0\x00\x00\x00\x00Gә\x00\x00" + + "\x00\x00\x00I\rO\xf0\x00\x00\x00\x00I\xb3{\x00\x00\x00\x00\x00J\xed1\xf0\x00\x00\x00\x00K\x9c\x97\x80\x00\x00\x00\x00L\xd6Np\x00\x00\x00\x00M|y\x80\x00\x00\x00\x00N\xb60p\x00\x00\x00\x00O" + + "\\[\x80\x00\x00\x00\x00P\x96\x12p\x00\x00\x00\x00Q<=\x80\x00\x00\x00\x00Ru\xf4p\x00\x00\x00\x00S\x1c\x1f\x80\x00\x00\x00\x00TU\xd6p\x00\x00\x00\x00T\xfc\x01\x80\x00\x00\x00\x00V5\xb8p\x00" + + "\x00\x00\x00V\xe5\x1e\x00\x00\x00\x00\x00X\x1e\xd4\xf0\x00\x00\x00\x00X\xc5\x00\x00\x00\x00\x00\x00Y\xfe\xb6\xf0\x00\x00\x00\x00Z\xa4\xe2\x00\x00\x00\x00\x00[ޘ\xf0\x00\x00\x00\x00\\\x84\xc4\x00\x00\x00\x00\x00]" + + "\xbez\xf0\x00\x00\x00\x00^d\xa6\x00\x00\x00\x00\x00_\x9e\\\xf0\x00\x00\x00\x00`M\u0080\x00\x00\x00\x00a\x87yp\x00\x00\x00\x00b-\xa4\x80\x00\x00\x00\x00cg[p\x00\x00\x00\x00d\r\x86\x80\x00" + + "\x00\x00\x00eG=p\x00\x00\x00\x00e\xedh\x80\x00\x00\x00\x00g'\x1fp\x00\x00\x00\x00g\xcdJ\x80\x00\x00\x00\x00i\a\x01p\x00\x00\x00\x00i\xad,\x80\x00\x00\x00\x00j\xe6\xe3p\x00\x00\x00\x00k" + + "\x96I\x00\x00\x00\x00\x00l\xcf\xff\xf0\x00\x00\x00\x00mv+\x00\x00\x00\x00\x00n\xaf\xe1\xf0\x00\x00\x00\x00oV\r\x00\x00\x00\x00\x00p\x8f\xc3\xf0\x00\x00\x00\x00q5\xef\x00\x00\x00\x00\x00ro\xa5\xf0\x00" + + "\x00\x00\x00s\x15\xd1\x00\x00\x00\x00\x00tO\x87\xf0\x00\x00\x00\x00t\xfe\xed\x80\x00\x00\x00\x00v8\xa4p\x00\x00\x00\x00v\xdeπ\x00\x00\x00\x00x\x18\x86p\x00\x00\x00\x00x\xbe\xb1\x80\x00\x00\x00\x00y" + + "\xf8hp\x00\x00\x00\x00z\x9e\x93\x80\x00\x00\x00\x00{\xd8Jp\x00\x00\x00\x00|~u\x80\x00\x00\x00\x00}\xb8,p\x00\x00\x00\x00~^W\x80\x00\x00\x00\x00\u007f\x98\x0ep\x02\x01\x02\x01\x02\x01\x02\x03\x04" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xa4" + + "\xec\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\bLMT\x00CDT\x00CST\x00CWT\x00CPT\x00\x00" + + "\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x01\x00\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP&\xc5=\t8\a\x00\x008" + + "\a\x00\x00\x12\x00\x1c\x00America/Grand_TurkUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\x00\x00\x00\x06\x00\x00\x00\x14\x80\x00\x00\x00\x93\x0f\xb4\xfe\x11\x89e\xf0\x12yH\xe0\x13iG\xf0\x14Y*" + + "\xe0\x15I)\xf0\x169\f\xe0\x17)\v\xf0\x18\")`\x19\b\xed\xf0\x1a\x02\v`\x1a\xf2\np\x1b\xe1\xed`\x1c\xd1\xecp\x1d\xc1\xcf`\x1e\xb1\xcep\x1f\xa1\xb1` v\x00\xf0!\x81\x93`\"U\xe2" + + "\xf0#j\xaf\xe0$5\xc4\xf0%J\x91\xe0&\x15\xa6\xf0'*s\xe0'\xfe\xc3p)\nU\xe0)ޥp*\xea7\xe0+\xbe\x87p,\xd3T`-\x9eip.\xb36`/~Kp0\x93\x18" + + "`1gg\xf02r\xfa`3GI\xf04R\xdc`5'+\xf062\xbe`7\a\r\xf08\x1b\xda\xe08\xe6\xef\xf09\xfb\xbc\xe0:\xc6\xd1\xf0;۞\xe0<\xaf\xeep=\xbb\x80\xe0>\x8f\xd0" + + "p?\x9bb\xe0@o\xb2pA\x84\u007f`BO\x94pCda`D/vpEDC`E\xf3\xa8\xf0G-_\xe0Gӊ\xf0I\rA\xe0I\xb3l\xf0J\xed#\xe0K\x9c\x89pL\xd6@" + + "`M|kpN\xb6\"`O\\MpP\x96\x04`Q\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2" + + "p\x00\x00\x00\x00A\x84\u007f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x00\x00\x00\x00G-_\xe0\x00\x00\x00" + + "\x00Gӊ\xf0\x00\x00\x00\x00I\rA\xe0\x00\x00\x00\x00I\xb3l\xf0\x00\x00\x00\x00J\xed#\xe0\x00\x00\x00\x00K\x9c\x89p\x00\x00\x00\x00L\xd6@`\x00\x00\x00\x00M|kp\x00\x00\x00\x00N\xb6\"" + + "`\x00\x00\x00\x00O\\Mp\x00\x00\x00\x00P\x96\x04`\x00\x00\x00\x00Q\x90\b\xb0?\x9b\x9b @o\xea\xb0A\x84\xb7\xa0BO̰Cd\x99\xa0D/\xae\xb0ED{\xa0E\xf3\xe10G-\x98 G\xd3\xc30" + + "I\rz I\xb3\xa50J\xed\\ K\x9c\xc1\xb0L\xd6x\xa0M|\xa3\xb0N\xb6Z\xa0O\\\x85\xb0P\x96<\xa0Q\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO̰\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0" + + "\x00\x00\x00\x00E\xf3\xe10\x00\x00\x00\x00G-\x98 \x00\x00\x00\x00G\xd3\xc30\x00\x00\x00\x00I\rz \x00\x00\x00\x00I\xb3\xa50\x00\x00\x00\x00J\xed\\ \x00\x00\x00\x00K\x9c\xc1\xb0\x00\x00\x00\x00" + + "L\xd6x\xa0\x00\x00\x00\x00M|\xa3\xb0\x00\x00\x00\x00N\xb6Z\xa0\x00\x00\x00\x00O\\\x85\xb0\x00\x00\x00\x00P\x96<\xa0\x00\x00\x00\x00Q\x90\b\xb0?\x9b\x9b @o\xea\xb0A\x84\xb7\xa0BO̰Cd\x99\xa0D/\xae\xb0ED{" + + "\xa0E\xf3\xe10G-\x98 G\xd3\xc30I\rz I\xb3\xa50J\xed\\ K\x9c\xc1\xb0L\xd6x\xa0M|\xa3\xb0N\xb6Z\xa0O\\\x85\xb0P\x96<\xa0Q\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO̰\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D" + + "/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x00\x00\x00\x00G-\x98 \x00\x00\x00\x00G\xd3\xc30\x00\x00\x00\x00I\rz \x00\x00\x00\x00I\xb3\xa50\x00\x00\x00\x00J\xed\\ \x00" + + "\x00\x00\x00K\x9c\xc1\xb0\x00\x00\x00\x00L\xd6x\xa0\x00\x00\x00\x00M|\xa3\xb0\x00\x00\x00\x00N\xb6Z\xa0\x00\x00\x00\x00O\\\x85\xb0\x00\x00\x00\x00P\x96<\xa0\x00\x00\x00\x00Q\x8f\x9ft?\x9b1\xe4@o\x81tA\x84NdBOctCd0dD/EtED\x12dE\xf3w\xf4G-.\xe4G\xd3Y\xf4I\r\x10\xe4I" + + "\xb3;\xf4J\xec\xf2\xe4K\x9cXtL\xd6\x0fdM|:tN\xb6\rHO\\8XP\x95\xefHQ<\x1aXRu\xd1HS\x1b\xfcXTU\xb3HT\xfb\xdeXV5\x95HV\xe4\xfa\xd8X" + + "\x1e\xb1\xc8X\xc4\xdc\xd8Y\xfe\x93\xc8Z\xa4\xbe\xd8[\xdeu\xc8\\\x84\xa0\xd8]\xbeW\xc8^d\x82\xd8_\x9e9\xc8`M\x9fXa\x87VHb-\x81Xcg8Hd\rcXeG\x1aHe" + + "\xedEXg&\xfcHg\xcd'Xi\x06\xdeHi\xad\tXj\xe6\xc0Hk\x96%\xd8l\xcf\xdc\xc8mv\a\xd8n\xaf\xbe\xc8oU\xe9\xd8p\x8f\xa0\xc8q5\xcb\xd8ro\x82\xc8s\x15\xad\xd8t" + + "Od\xc8t\xfe\xcaXv8\x81HvެXx\x18cHx\xbe\x8eXy\xf8EHz\x9epX{\xd8'H|~RX}\xb8\tH~^4X\u007f\x97\xebH\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x06\x05\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\a\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\xff\xffΔ\x00\x00\xff\xffܤ" + + "\x01\x04\xff\xffΔ\x00\b\xff\xff\xdc\xd8\x01\x04\xff\xff\xce\xc8\x00\b\xff\xff\xdc\xd8\x01\f\xff\xff\xdc\xd8\x01\x10\xff\xff\xea\xe8\x01\x14\xff\xff\xdc\xd8\x01\x04LMT\x00NDT\x00NST\x00NPT\x00" + + "NWT\x00NDDT\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\t\x00\x00\x00\x00\x00" + + "\x00\x00\xef\x00\x00\x00\t\x00\x00\x00\x19\xff\xff\xff\xff^=4\xec\xff\xff\xff\xff\x9c\xcfb\f\xff\xff\xff\xff\x9d\xa4\xe6\xfc\xff\xff\xff\xff\x9e\xb8~\x8c\xff\xff\xff\xff\x9f\xba\xd6|\xff\xff\xff\xff\xa0\xb6\x88\xdc\xff" + + "\xff\xff\xff\xa18\xffL\xff\xff\xff\xff\xa2\x95\x19\\\xff\xff\xff\xff\xa3\x84\xfcL\xff\xff\xff\xff\xa4t\xfb\\\xff\xff\xff\xff\xa5d\xdeL\xff\xff\xff\xff\xa6^\x17\xdc\xff\xff\xff\xff\xa7D\xc0L\xff\xff\xff\xff\xa8" + + "=\xf9\xdc\xff\xff\xff\xff\xa9$\xa2L\xff\xff\xff\xff\xaa\x1d\xdb\xdc\xff\xff\xff\xff\xab\x04\x84L\xff\xff\xff\xff\xab\xfd\xbd\xdc\xff\xff\xff\xff\xac\xe4fL\xff\xff\xff\xff\xadݟ\xdc\xff\xff\xff\xff\xae͂\xcc\xff" + + "\xff\xff\xff\xaf\xbd\x81\xdc\xff\xff\xff\xff\xb0\xadd\xcc\xff\xff\xff\xff\xb1\xa6\x9e\\\xff\xff\xff\xff\xb2\x8dF\xcc\xff\xff\xff\xff\xb3\x86\x80\\\xff\xff\xff\xff\xb4m(\xcc\xff\xff\xff\xff\xb5fb\\\xff\xff\xff\xff\xb6" + + "M\n\xcc\xff\xff\xff\xff\xb7FD\\\xff\xff\xff\xff\xb8,\xec\xcc\xff\xff\xff\xff\xb9&&\\\xff\xff\xff\xff\xba\x16\tL\xff\xff\xff\xff\xbb\x0fB\xdc\xff\xff\xff\xff\xbb\xf5\xebL\xff\xff\xff\xff\xbc\xef$\xdc\xff" + + "\xff\xff\xff\xbd\xd5\xcdL\xff\xff\xff\xff\xbe\x9eMl\xff\xff\xff\xff\xbe\xcf\x06\xa8\xff\xff\xff\xff\xbf\xb5\xaf\x18\xff\xff\xff\xff\xc0\xb818\xff\xff\xff\xff\xc1y\xef\xa8\xff\xff\xff\xff\u0098\x138\xff\xff\xff\xff\xc3" + + "YѨ\xff\xff\xff\xff\xc4w\xf58\xff\xff\xff\xff\xc59\xb3\xa8\xff\xff\xff\xff\xc6a\x11\xb8\xff\xff\xff\xff\xc7\x19\x95\xa8\xff\xff\xff\xff\xc8@\xf3\xb8\xff\xff\xff\xff\xc9\x02\xb2(\xff\xff\xff\xff\xca ո\xff" + + "\xff\xff\xff\xca\xe2\x94(\xff\xff\xff\xff\xcc\x00\xb7\xb8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xe6\xc8\xff\xff\xff\xffӈD\xd8\xff\xff\xff\xff\xd4J\x03H\xff\xff\xff\xff\xd5h&\xd8\xff\xff\xff\xff\xd6" + + ")\xe5H\xff\xff\xff\xff\xd7H\b\xd8\xff\xff\xff\xff\xd8\t\xc7H\xff\xff\xff\xff\xd9'\xea\xd8\xff\xff\xff\xff\xd9\xe9\xa9H\xff\xff\xff\xff\xdb\x11\aX\xff\xff\xff\xff\xdb\xd2\xc5\xc8\xff\xff\xff\xff\xdc\xdetX\xff" + + "\xff\xff\xffݩmH\xff\xff\xff\xff\u07beVX\xff\xff\xff\xff߉OH\xff\xff\xff\xff\xe0\x9e8X\xff\xff\xff\xff\xe1i1H\xff\xff\xff\xff\xe2~\x1aX\xff\xff\xff\xff\xe3I\x13H\xff\xff\xff\xff\xe4" + + "]\xfcX\xff\xff\xff\xff\xe5(\xf5H\xff\xff\xff\xff\xe6G\x18\xd8\xff\xff\xff\xff\xe7\x12\x11\xc8\xff\xff\xff\xff\xe8&\xfa\xd8\xff\xff\xff\xff\xe8\xf1\xf3\xc8\xff\xff\xff\xff\xea\x06\xdc\xd8\xff\xff\xff\xff\xea\xd1\xd5\xc8\xff" + + "\xff\xff\xff\xeb\xe6\xbe\xd8\xff\xff\xff\xff챷\xc8\xff\xff\xff\xff\xedƠ\xd8\xff\xff\xff\xff\ueffeH\xff\xff\xff\xffﯽX\xff\xff\xff\xff\xf0\x9f\xa0H\xff\xff\xff\xff\xf1\x8f\x9fX\xff\xff\xff\xff\xf2" + + "\u007f\x82H\xff\xff\xff\xff\xf3o\x81X\xff\xff\xff\xff\xf4_dH\xff\xff\xff\xff\xf5OcX\xff\xff\xff\xff\xf6?FH\xff\xff\xff\xff\xf7/EX\xff\xff\xff\xff\xf8(b\xc8\xff\xff\xff\xff\xf9\x0f'X\xff" + + "\xff\xff\xff\xfa\bD\xc8\xff\xff\xff\xff\xfa\xf8C\xd8\xff\xff\xff\xff\xfb\xe8&\xc8\xff\xff\xff\xff\xfc\xd8%\xd8\xff\xff\xff\xff\xfd\xc8\b\xc8\xff\xff\xff\xff\xfe\xb8\a\xd8\xff\xff\xff\xff\xff\xa7\xea\xc8\x00\x00\x00\x00\x00" + + "\x97\xe9\xd8\x00\x00\x00\x00\x01\x87\xcc\xc8\x00\x00\x00\x00\x02w\xcb\xd8\x00\x00\x00\x00\x03p\xe9H\x00\x00\x00\x00\x04`\xe8X\x00\x00\x00\x00\x05P\xcbH\x00\x00\x00\x00\x06@\xcaX\x00\x00\x00\x00\a0\xadH\x00" + + "\x00\x00\x00\b \xacX\x00\x00\x00\x00\t\x10\x8fH\x00\x00\x00\x00\n\x00\x8eX\x00\x00\x00\x00\n\xf0qH\x00\x00\x00\x00\v\xe0pX\x00\x00\x00\x00\fٍ\xc8\x00\x00\x00\x00\r\xc0RX\x00\x00\x00\x00\x0e" + + "\xb9o\xc8\x00\x00\x00\x00\x0f\xa9n\xd8\x00\x00\x00\x00\x10\x99Q\xc8\x00\x00\x00\x00\x11\x89P\xd8\x00\x00\x00\x00\x12y3\xc8\x00\x00\x00\x00\x13i2\xd8\x00\x00\x00\x00\x14Y\x15\xc8\x00\x00\x00\x00\x15I\x14\xd8\x00" + + "\x00\x00\x00\x168\xf7\xc8\x00\x00\x00\x00\x17(\xf6\xd8\x00\x00\x00\x00\x18\"\x14H\x00\x00\x00\x00\x19\b\xd8\xd8\x00\x00\x00\x00\x1a\x01\xf6H\x00\x00\x00\x00\x1a\xf1\xf5X\x00\x00\x00\x00\x1b\xe1\xd8H\x00\x00\x00\x00\x1c" + + "\xd1\xd7X\x00\x00\x00\x00\x1d\xc1\xbaH\x00\x00\x00\x00\x1e\xb1\xb9X\x00\x00\x00\x00\x1f\xa1\x9cH\x00\x00\x00\x00 u\xcf\xf4\x00\x00\x00\x00!\x81bd\x00\x00\x00\x00\"U\xb1\xf4\x00\x00\x00\x00#jp\xd4\x00" + + "\x00\x00\x00$5\x93\xf4\x00\x00\x00\x00%J`\xe4\x00\x00\x00\x00&\x15u\xf4\x00\x00\x00\x00'*B\xe4\x00\x00\x00\x00'\xfe\x92t\x00\x00\x00\x00)\n$\xe4\x00\x00\x00\x00)\xdett\x00\x00\x00\x00*" + + "\xea\x06\xe4\x00\x00\x00\x00+\xbeVt\x00\x00\x00\x00,\xd3#d\x00\x00\x00\x00-\x9e8t\x00\x00\x00\x00.\xb3\x05d\x00\x00\x00\x00/~\x1at\x00\x00\x00\x000\x92\xe7d\x00\x00\x00\x001g6\xf4\x00" + + "\x00\x00\x002r\xc9d\x00\x00\x00\x003G\x18\xf4\x00\x00\x00\x004R\xabd\x00\x00\x00\x005&\xfa\xf4\x00\x00\x00\x0062\x8dd\x00\x00\x00\x007\x06\xdc\xf4\x00\x00\x00\x008\x1b\xa9\xe4\x00\x00\x00\x008" + + "\xe6\xbe\xf4\x00\x00\x00\x009\xfb\x8b\xe4\x00\x00\x00\x00:Ơ\xf4\x00\x00\x00\x00;\xdbm\xe4\x00\x00\x00\x00<\xaf\xbdt\x00\x00\x00\x00=\xbbO\xe4\x00\x00\x00\x00>\x8f\x9ft\x00\x00\x00\x00?\x9b1\xe4\x00" + + "\x00\x00\x00@o\x81t\x00\x00\x00\x00A\x84Nd\x00\x00\x00\x00BOct\x00\x00\x00\x00Cd0d\x00\x00\x00\x00D/Et\x00\x00\x00\x00ED\x12d\x00\x00\x00\x00E\xf3w\xf4\x00\x00\x00\x00G" + + "-.\xe4\x00\x00\x00\x00G\xd3Y\xf4\x00\x00\x00\x00I\r\x10\xe4\x00\x00\x00\x00I\xb3;\xf4\x00\x00\x00\x00J\xec\xf2\xe4\x00\x00\x00\x00K\x9cXt\x00\x00\x00\x00L\xd6\x0fd\x00\x00\x00\x00M|:t\x00" + + "\x00\x00\x00N\xb6\rH\x00\x00\x00\x00O\\8X\x00\x00\x00\x00P\x95\xefH\x00\x00\x00\x00Q<\x1aX\x00\x00\x00\x00Ru\xd1H\x00\x00\x00\x00S\x1b\xfcX\x00\x00\x00\x00TU\xb3H\x00\x00\x00\x00T" + + "\xfb\xdeX\x00\x00\x00\x00V5\x95H\x00\x00\x00\x00V\xe4\xfa\xd8\x00\x00\x00\x00X\x1e\xb1\xc8\x00\x00\x00\x00X\xc4\xdc\xd8\x00\x00\x00\x00Y\xfe\x93\xc8\x00\x00\x00\x00Z\xa4\xbe\xd8\x00\x00\x00\x00[\xdeu\xc8\x00" + + "\x00\x00\x00\\\x84\xa0\xd8\x00\x00\x00\x00]\xbeW\xc8\x00\x00\x00\x00^d\x82\xd8\x00\x00\x00\x00_\x9e9\xc8\x00\x00\x00\x00`M\x9fX\x00\x00\x00\x00a\x87VH\x00\x00\x00\x00b-\x81X\x00\x00\x00\x00c" + + "g8H\x00\x00\x00\x00d\rcX\x00\x00\x00\x00eG\x1aH\x00\x00\x00\x00e\xedEX\x00\x00\x00\x00g&\xfcH\x00\x00\x00\x00g\xcd'X\x00\x00\x00\x00i\x06\xdeH\x00\x00\x00\x00i\xad\tX\x00" + + "\x00\x00\x00j\xe6\xc0H\x00\x00\x00\x00k\x96%\xd8\x00\x00\x00\x00l\xcf\xdc\xc8\x00\x00\x00\x00mv\a\xd8\x00\x00\x00\x00n\xaf\xbe\xc8\x00\x00\x00\x00oU\xe9\xd8\x00\x00\x00\x00p\x8f\xa0\xc8\x00\x00\x00\x00q" + + "5\xcb\xd8\x00\x00\x00\x00ro\x82\xc8\x00\x00\x00\x00s\x15\xad\xd8\x00\x00\x00\x00tOd\xc8\x00\x00\x00\x00t\xfe\xcaX\x00\x00\x00\x00v8\x81H\x00\x00\x00\x00vެX\x00\x00\x00\x00x\x18cH\x00" + + "\x00\x00\x00x\xbe\x8eX\x00\x00\x00\x00y\xf8EH\x00\x00\x00\x00z\x9epX\x00\x00\x00\x00{\xd8'H\x00\x00\x00\x00|~RX\x00\x00\x00\x00}\xb8\tH\x00\x00\x00\x00~^4X\x00\x00\x00\x00\u007f" + + "\x97\xebH\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x06\x05\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\a\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\xff\xffΔ\x00\x00\xff\xffܤ\x01\x04\xff\xffΔ\x00\b\xff\xff\xdc\xd8\x01\x04\xff\xff\xce\xc8\x00\b\xff\xff\xdc\xd8\x01\f\xff\xff\xdc\xd8\x01\x10\xff\xff\xea\xe8\x01\x14\xff\xff\xdc\xd8\x01\x04LMT\x00" + + "NDT\x00NST\x00NPT\x00NWT\x00NDDT\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\nNST3:30NDT,M3.2.0,M1" + + "1.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPh\xef\x10-4\t\x00\x004\t\x00\x00\f\x00\x1c\x00America/AtkaUT\t\x00\x03nӧ^nӧ" + + "^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00\x00\t\x00\x00\x00!" + + "\x80\x00\x00\x00ˉD\xd0\xd2#\xf4p\xd2aP@\xfa\xd2U\xb0\xfe\xb8qP\xff\xa8T@\x00\x98SP\x01\x886@\x02x5P\x03qR\xc0\x04aQ\xd0\x05Q4\xc0\x06A3\xd0\a1\x16\xc0" + + "\a\x8dm\xd0\t\x10\xf8\xc0\t\xad\xe9P\n\xf0\xda\xc0\v\xe0\xd9\xd0\f\xd9\xf7@\r\xc0\xbb\xd0\x0e\xb9\xd9@\x0f\xa9\xd8P\x10\x99\xbb@\x11\x89\xbaP\x12y\x9d@\x13i\x9cP\x14Y\u007f@\x15I~P" + + "\x169a@\x17)`P\x18\"}\xc0\x19\tBP\x1a\x02_\xc0\x1a+\" \x1a\xf2P\xc0\x1b\xe23\xb0\x1c\xd22\xc0\x1d\xc2\x15\xb0\x1e\xb2\x14\xc0\x1f\xa1\xf7\xb0 vG@!\x81ٰ\"V)@" + + "#j\xf60$6\v@%J\xd80&\x15\xed@'*\xba0'\xff\t\xc0)\n\x9c0)\xde\xeb\xc0*\xea~0+\xbe\xcd\xc0,Ӛ\xb0-\x9e\xaf\xc0.\xb3|\xb0/~\x91\xc00\x93^\xb0" + + "1g\xae@2s@\xb03G\x90@4S\"\xb05'r@63\x04\xb07\aT@8\x1c!08\xe76@9\xfc\x030:\xc7\x18@;\xdb\xe50<\xb04\xc0=\xbb\xc70>\x90\x16\xc0" + + "?\x9b\xa90@o\xf8\xc0A\x84ŰBO\xda\xc0Cd\xa7\xb0D/\xbc\xc0ED\x89\xb0E\xf3\xef@G-\xa60G\xd3\xd1@I\r\x880I\xb3\xb3@J\xedj0K\x9c\xcf\xc0Lֆ\xb0" + + "M|\xb1\xc0N\xb6h\xb0O\\\x93\xc0P\x96J\xb0Q\x90\x16\xc0\x00\x00\x00\x00?\x9b\xa90\x00\x00\x00\x00@o\xf8\xc0\x00\x00\x00\x00A\x84\xc5" + + "\xb0\x00\x00\x00\x00BO\xda\xc0\x00\x00\x00\x00Cd\xa7\xb0\x00\x00\x00\x00D/\xbc\xc0\x00\x00\x00\x00ED\x89\xb0\x00\x00\x00\x00E\xf3\xef@\x00\x00\x00\x00G-\xa60\x00\x00\x00\x00G\xd3\xd1@\x00\x00\x00" + + "\x00I\r\x880\x00\x00\x00\x00I\xb3\xb3@\x00\x00\x00\x00J\xedj0\x00\x00\x00\x00K\x9c\xcf\xc0\x00\x00\x00\x00Lֆ\xb0\x00\x00\x00\x00M|\xb1\xc0\x00\x00\x00\x00N\xb6h\xb0\x00\x00\x00\x00O\\\x93" + + "\xc0\x00\x00\x00\x00P\x96J\xb0\x00\x00\x00\x00Q\x8f\x980?Z\xad@@oz0Aq\xee@B3\xac\xb0CQ\xd0@D\x13\x8e\xb0E1\xb2@E\xf3" + + "p\xb0G\x1a\xce\xc0G\xd3R\xb0H\xfa\xb0\xc0I\xb34\xb0Jڒ\xc0K\xc1;0L\xa7\xff\xc0M\xa1\x1d0N\x87\xe1\xc0O\x80\xff0Pp\xfe@QNl0RP\xe0@S.N0T0" + + "\xc2@U\x0e00V\x10\xa4@V\xf7L\xb0W\xf0\x86@X\xd7.\xb0Y\xd0h@Z\xb7\x10\xb0[\xb9\x84\xc0\\\x96\xf2\xb0]\x99f\xc0^v\u0530_yH\xc0`_\xf10aY*\xc0b?" + + "\xd30c9\f\xc0d\x1f\xb50e\x18\xee\xc0e\xff\x970g\x02\v@g\xdfy0h\xe1\xed@i\xbf[0j\xc1\xcf@k\xa8w\xb0l\xa1\xb1@m\x88Y\xb0n\x81\x93@oh;\xb0pj" + + "\xaf\xc0qH\x1d\xb0rJ\x91\xc0s'\xff\xb0t*s\xc0u\x11\x1c0v\nU\xc0v\xf0\xfe0w\xea7\xc0x\xd0\xe00y\xca\x19\xc0z\xb0\xc20{\xb36@|\x90\xa40}\x93\x18@~p" + + "\x860\u007fr\xfa@\u007f\xff\xff\xff\x01\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02" + + "\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02" + + "\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x04\xff\xff\xc9\xf0\x00\x00\xff\xff\xc9\xf0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x00\f\xff\xff\xd5\xd0\x01\f\xff\xff\xc7\xc0\x00\bLMT\x00" + + "AMT\x00-04\x00-03\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff" + + "i\x87\x11\x90\xff\xff\xff\xff\xb8\x17\xf5\x90\x00\x00\x00\x00\x05+\xda@\x00\x00\x00\x00\a\xfc\xf0\xb0\x00\x00\x00\x00\n\xcft\xc0\x00\x00\x00\x00\v\x97ʰ\x00\x00\x00\x00\f\xb1\xf9\xc0\x00\x00\x00\x00\rx\xfe0" + + "\x00\x00\x00\x00\x0e\x93-@\x00\x00\x00\x00\x0fZ1\xb0\x00\x00\x00\x00\x10t`\xc0\x00\x00\x00\x00\x11dC\xb0\x00\x00\x00\x00\x12U\x94@\x00\x00\x00\x00\x13FȰ\x00\x00\x00\x00\x148\x19@\x00\x00\x00\x00" + + "\x15'\xfc0\x00\x00\x00\x00\x16\x19L\xc0\x00\x00\x00\x00\x17\t/\xb0\x00\x00\x00\x00\x17\xfa\x80@\x00\x00\x00\x00\x18\xeac0\x00\x00\x00\x00\x19۳\xc0\x00\x00\x00\x00\x1a\xcc\xe80\x00\x00\x00\x00\x1b\xbe8\xc0" + + "\x00\x00\x00\x00\x1c\xae\x1b\xb0\x00\x00\x00\x00\x1d\x9fl@\x00\x00\x00\x00\x1e\x8fO0\x00\x00\x00\x00\x1f\x80\x9f\xc0\x00\x00\x00\x00 p\x82\xb0\x00\x00\x00\x00!a\xd3@\x00\x00\x00\x00\"S\a\xb0\x00\x00\x00\x00" + + "#DX@\x00\x00\x00\x00$4;0\x00\x00\x00\x00%A;@\x00\x00\x00\x00&\x15n\xb0\x00\x00\x00\x00'\x06\xbf@\x00\x00\x00\x00'\xf6\xa20\x00\x00\x00\x00(\xee\x8a@\x00\x00\x00\x00)\xb0H\xb0" + + "\x00\x00\x00\x00*Ͻ\xc0\x00\x00\x00\x00+\xb9\t0\x00\x00\x00\x00,\xab\xab@\x00\x00\x00\x00-p\f\xb0\x00\x00\x00\x00.\x8c\xde\xc0\x00\x00\x00\x00/O\xee\xb0\x00\x00\x00\x000n\x12@\x00\x00\x00\x00" + + "16h0\x00\x00\x00\x002W.\xc0\x00\x00\x00\x003\x0f\xb2\xb0\x00\x00\x00\x0047\x10\xc0\x00\x00\x00\x004\xf8\xcf0\x00\x00\x00\x006\x16\xf2\xc0\x00\x00\x00\x006\xe1\xeb\xb0\x00\x00\x00\x007\xf6\xd4\xc0" + + "\x00\x00\x00\x008\xc1Ͱ\x00\x00\x00\x009ֶ\xc0\x00\x00\x00\x00:\xa1\xaf\xb0\x00\x00\x00\x00;\xbf\xd3@\x00\x00\x00\x00<\xaf\xb60\x00\x00\x00\x00=q\x90\xc0\x00\x00\x00\x00>\x8f\x980\x00\x00\x00\x00" + + "?Z\xad@\x00\x00\x00\x00@oz0\x00\x00\x00\x00Aq\xee@\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CQ\xd0@\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0" + + "\x00\x00\x00\x00G\x1a\xce\xc0\x00\x00\x00\x00G\xd3R\xb0\x00\x00\x00\x00H\xfa\xb0\xc0\x00\x00\x00\x00I\xb34\xb0\x00\x00\x00\x00Jڒ\xc0\x00\x00\x00\x00K\xc1;0\x00\x00\x00\x00L\xa7\xff\xc0\x00\x00\x00\x00" + + "M\xa1\x1d0\x00\x00\x00\x00N\x87\xe1\xc0\x00\x00\x00\x00O\x80\xff0\x00\x00\x00\x00Pp\xfe@\x00\x00\x00\x00QNl0\x00\x00\x00\x00RP\xe0@\x00\x00\x00\x00S.N0\x00\x00\x00\x00T0\xc2@" + + "\x00\x00\x00\x00U\x0e00\x00\x00\x00\x00V\x10\xa4@\x00\x00\x00\x00V\xf7L\xb0\x00\x00\x00\x00W\xf0\x86@\x00\x00\x00\x00X\xd7.\xb0\x00\x00\x00\x00Y\xd0h@\x00\x00\x00\x00Z\xb7\x10\xb0\x00\x00\x00\x00" + + "[\xb9\x84\xc0\x00\x00\x00\x00\\\x96\xf2\xb0\x00\x00\x00\x00]\x99f\xc0\x00\x00\x00\x00^v\u0530\x00\x00\x00\x00_yH\xc0\x00\x00\x00\x00`_\xf10\x00\x00\x00\x00aY*\xc0\x00\x00\x00\x00b?\xd30" + + "\x00\x00\x00\x00c9\f\xc0\x00\x00\x00\x00d\x1f\xb50\x00\x00\x00\x00e\x18\xee\xc0\x00\x00\x00\x00e\xff\x970\x00\x00\x00\x00g\x02\v@\x00\x00\x00\x00g\xdfy0\x00\x00\x00\x00h\xe1\xed@\x00\x00\x00\x00" + + "i\xbf[0\x00\x00\x00\x00j\xc1\xcf@\x00\x00\x00\x00k\xa8w\xb0\x00\x00\x00\x00l\xa1\xb1@\x00\x00\x00\x00m\x88Y\xb0\x00\x00\x00\x00n\x81\x93@\x00\x00\x00\x00oh;\xb0\x00\x00\x00\x00pj\xaf\xc0" + + "\x00\x00\x00\x00qH\x1d\xb0\x00\x00\x00\x00rJ\x91\xc0\x00\x00\x00\x00s'\xff\xb0\x00\x00\x00\x00t*s\xc0\x00\x00\x00\x00u\x11\x1c0\x00\x00\x00\x00v\nU\xc0\x00\x00\x00\x00v\xf0\xfe0\x00\x00\x00\x00" + + "w\xea7\xc0\x00\x00\x00\x00x\xd0\xe00\x00\x00\x00\x00y\xca\x19\xc0\x00\x00\x00\x00z\xb0\xc20\x00\x00\x00\x00{\xb36@\x00\x00\x00\x00|\x90\xa40\x00\x00\x00\x00}\x93\x18@\x00\x00\x00\x00~p\x860" + + "\x00\x00\x00\x00\u007fr\xfa@\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02" + + "\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02" + + "\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x04\xff\xff\xc9\xf0\x00\x00\xff\xff\xc9\xf0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x00\f\xff\xff\xd5\xd0\x01\f\xff\xff\xc7\xc0" + + "\x00\bLMT\x00AMT\x00-04\x00-03\x00\n<-04>4<-03>,M10.1.0/0,M3.4.0/0\nPK\x03\x04\n\x00\x00\x00\x00\x00" + + "\xf5F\x9cP;\xab\xd2\xe0\xa0\x01\x00\x00\xa0\x01\x00\x00\x12\x00\x1c\x00America/HermosilloUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00" + + "\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x06\x00\x00\x00\x14\xa5\xb6\xe8p\xaf\xf2n\xe0\xb6f" + + "V`\xb7C\xd2`\xb8\f6`\xb8\xfd\x86\xf0\xcb\xeaq`ؑ\xb4\xf0\x00\x00p\x801g\x84\x102s\x16\x803Gf\x104R\xf8\x805'H\x1062ڀ\x01\x02\x01\x02\x01\x02\x01\x03\x01\x04" + + "\x01\x04\x01\x04\x01\xff\xff\x97\xf8\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\x8f\x80\x00\f\xff\xff\xab\xa0\x01\x10\xff\xff\x9d\x90\x00\x04LMT\x00MST\x00CST\x00PST\x00MDT" + + "\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n" + + "\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xcb\xeaq`\xff\xff\xff\xffؑ\xb4\xf0\x00\x00\x00\x00\x00\x00p\x80\x00\x00\x00" + + "\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x01\x02\x01\x02\x01\x02\x01\x03\x01\x04\x01\x04\x01\x04\x01" + + "\xff\xff\x97\xf8\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\x8f\x80\x00\f\xff\xff\xab\xa0\x01\x10\xff\xff\x9d\x90\x00\x04LMT\x00MST\x00CST\x00PST\x00MDT\x00\nMST" + + "7\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x95\"R\xd4&\t\x00\x00&\t\x00\x00\x0f\x00\x1c\x00America/TijuanaUT\t\x00\x03nӧ^nӧ^" + + "ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x95\x00\x00\x00\x06\x00\x00\x00\x18\xa5" + + "\xb6\xf6\x80\xa9yOp\xaf\xf2|\xf0\xb6fdp\xb7\x1b\x10\x00\xb8\n\xf2\xf0\xcbꍀ\xd2#\xf4pҙ\xbap\xd7\x1bY\x00ؑ\xb4\xf0\xe2~K\x90\xe3IR\x90\xe4^-\x90\xe5)4\x90\xe6" + + "GJ\x10\xe7\x12Q\x10\xe8',\x10\xe8\xf23\x10\xea\a\x0e\x10\xea\xd2\x15\x10\xeb\xe6\xf0\x10\xec\xb1\xf7\x10\xed\xc6\xd2\x10\xee\x91\xd9\x10\v\u0be0\f\xd9\xcd\x10\r\xc0\x91\xa0\x0e\xb9\xaf\x10\x0f\xa9\xae \x10" + + "\x99\x91\x10\x11\x89\x90 \x12ys\x10\x13ir \x14YU\x10\x15IT \x1697\x10\x17)6 \x18\"S\x90\x19\t\x18 \x1a\x025\x90\x1a\xf24\xa0\x1b\xe2\x17\x90\x1c\xd2\x16\xa0\x1d\xc1\xf9\x90\x1e" + + "\xb1\xf8\xa0\x1f\xa1ې v+ !\x81\xbd\x90\"V\r #j\xda\x10$5\xef %J\xbc\x10&\x15\xd1 '*\x9e\x10'\xfe\xed\xa0)\n\x80\x10)\xdeϠ*\xeab\x10+\xbe\xb1\xa0," + + "\xd3~\x90-\x9e\x93\xa0.\xb3`\x90/~u\xa00\x93B\x901g\x92 2s$\x903Gt 4S\x06\x905'V 62\xe8\x907\a8 8\x1c\x05\x108\xe7\x1a 9\xfb\xe7\x10:" + + "\xc6\xfc ;\xdb\xc9\x10<\xb0\x18\xa0=\xbb\xab\x10>\x8f\xfa\xa0?\x9b\x8d\x10@oܠA\x84\xa9\x90BO\xbe\xa0Cd\x8b\x90D/\xa0\xa0EDm\x90F\x0f\x82\xa0G$O\x90G\xf8\x9f I" + + "\x041\x90I\u0601 J\xe4\x13\x90K\x9c\xb3\xa0L\xd6j\x90M|\x95\xa0N\xb6L\x90O\\w\xa0P\x96.\x90Q\x8f\xfa\xa0" + + "\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00" + + "F\x0f\x82\xa0\x00\x00\x00\x00G$O\x90\x00\x00\x00\x00G\xf8\x9f \x00\x00\x00\x00I\x041\x90\x00\x00\x00\x00I\u0601 \x00\x00\x00\x00J\xe4\x13\x90\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90" + + "\x00\x00\x00\x00M|\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\\w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q\x90\b\xb0?\x9b\x9b @o\xea\xb0A\x84" + + "\xb7\xa0BO̰Cd\x99\xa0D/\xae\xb0ED{\xa0E\xf3\xe10G-\x98 G\xd3\xc30I\rz I\xb3\xa50J\xed\\ K\x9c\xc1\xb0L\xd6x\xa0M|\xa3\xb0N\xb6Z\xa0O\\" + + "\x85\xb0P\x96<\xa0Q\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO̰\x00\x00\x00\x00C" + + "d\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x00\x00\x00\x00G-\x98 \x00\x00\x00\x00G\xd3\xc30\x00\x00\x00\x00I\rz \x00\x00\x00\x00I\xb3\xa50\x00" + + "\x00\x00\x00J\xed\\ \x00\x00\x00\x00K\x9c\xc1\xb0\x00\x00\x00\x00L\xd6x\xa0\x00\x00\x00\x00M|\xa3\xb0\x00\x00\x00\x00N\xb6Z\xa0\x00\x00\x00\x00O\\\x85\xb0\x00\x00\x00\x00P\x96<\xa0\x00\x00\x00\x00Q" + + "0\xfd\xf6\x11(\x00\x96u0\x00\xd8R \x04W\x8a\xb0\x04\xc6:\xa0\a" + + "\x96\x1b\xb0\a\xdfژ\bƟ(\tZN0\t\xdbs \r\x1a\x120\r\u007f\x87\xa0\x0e\xe7\u007f0\x0f_i\xa0\x10\xd9\xd60\x11?K\xa0\x11\x89-\xb0\x131\xa2\xa0!\xc3T0\"'x #" + + "\xa1\xe4\xb0$\x10\x94\xa0%Jg\xb0%\xe7< '!\x0f0'\xd0X\xa0)\n+\xb0)\xb0:\xa0*\xe0\xd30+\x90\x1c\xa0AL\xf60BF/\xc0CH\xa3\xd0D\x13\x9c\xc0E\x1fKPE" + + "\xf3~\xc0G\bg\xd0G\xd3`\xc0H\xe8I\xd0I\xb3B\xc0J\xc8+\xd0K\x9c_@L\xa8\r\xd0M|A@N\x87\xef\xd0O\\#@Pq\fPQ<\x05@RP\xeePS\x1b\xe7@T" + + "0\xd0PT\xfb\xc9@\u007f\xff\xff\xff\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x06\x05\x06\x05\a\x05\a\x05\x06\x05\a\x05\a\x05\b\x06\x05\a\x05\a\x05\a\x05\a" + + "\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\x05\xff\xff\xcbM\x00\x00\xff\xff\xcbM\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xce\xc8" + + "\x00\f\xff\xff\xd5\xd0\x01\x12\xff\xff\xd5\xd0\x00\x12\xff\xff\xdc\xd8\x01\x16\xff\xff\xe3\xe0\x01\x1c\xff\xff\xea\xe8\x01 \xff\xff\xe3\xe0\x01\x1cLMT\x00MMT\x00-04\x00-0330\x00-03\x00" + + "-0230\x00-02\x00-0130\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00W\x00\x00\x00\n\x00\x00\x00&" + + "\xff\xff\xff\xff\x8c4\xe53\xff\xff\xff\xff\xa2\x92\x87\xb3\xff\xff\xff\xff\xa8\xff\xdb@\xff\xff\xff\xff\xa9\xf1\x0f\xb0\xff\xff\xff\xff\xaa\xe2Y8\xff\xff\xff\xff\xab\xd2C0\xff\xff\xff\xff\xacÌ\xb8\xff\xff\xff\xff" + + "\xad\xb3v\xb0\xff\xff\xff\xff\xbb\xf4\xb5\xb8\xff\xff\xff\xff\xbc\xbf\xb5\xb0\xff\xff\xff\xff\xbdԗ\xb8\xff\xff\xff\xff\xbe\x9f\x97\xb0\xff\xff\xff\xff\xbf\xb4y\xb8\xff\xff\xff\xff\xc0\u007fy\xb0\xff\xff\xff\xff\xc1\x94[\xb8" + + "\xff\xff\xff\xff\xc2_[\xb0\xff\xff\xff\xff\xc3}x8\xff\xff\xff\xff\xc4?=\xb0\xff\xff\xff\xff\xc5]Z8\xff\xff\xff\xff\xc6\x1f\x1f\xb0\xff\xff\xff\xff\xc7\x18R8\xff\xff\xff\xff\xc8\b<0\xff\xff\xff\xff" + + "\xc9\x1d\x1e8\xff\xff\xff\xff\xc9\xe8\x1e0\xff\xff\xff\xffʋ\x9f8\xff\xff\xff\xff\xcd\x1e\xc60\xff\xff\xff\xff͕f(\xff\xff\xff\xff\xec\v\x85\xb0\xff\xff\xff\xff\xec\xf25(\xff\xff\xff\xff\xedEJ\xb0" + + "\xff\xff\xff\xff\xed\x85\xd6 \xff\xff\xff\xff\xf7\x13r\xb0\xff\xff\xff\xff\xf7\xfa\x1b \xff\xff\xff\xff\xfc\xfe>0\xff\xff\xff\xff\xfd\xf6\x11(\x00\x00\x00\x00\x00\x96u0\x00\x00\x00\x00\x00\xd8R \x00\x00\x00\x00" + + "\x04W\x8a\xb0\x00\x00\x00\x00\x04\xc6:\xa0\x00\x00\x00\x00\a\x96\x1b\xb0\x00\x00\x00\x00\a\xdfژ\x00\x00\x00\x00\bƟ(\x00\x00\x00\x00\tZN0\x00\x00\x00\x00\t\xdbs \x00\x00\x00\x00\r\x1a\x120" + + "\x00\x00\x00\x00\r\u007f\x87\xa0\x00\x00\x00\x00\x0e\xe7\u007f0\x00\x00\x00\x00\x0f_i\xa0\x00\x00\x00\x00\x10\xd9\xd60\x00\x00\x00\x00\x11?K\xa0\x00\x00\x00\x00\x11\x89-\xb0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00" + + "!\xc3T0\x00\x00\x00\x00\"'x \x00\x00\x00\x00#\xa1\xe4\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%Jg\xb0\x00\x00\x00\x00%\xe7< \x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0" + + "\x00\x00\x00\x00)\n+\xb0\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x90\x1c\xa0\x00\x00\x00\x00AL\xf60\x00\x00\x00\x00BF/\xc0\x00\x00\x00\x00CH\xa3\xd0\x00\x00\x00\x00" + + "D\x13\x9c\xc0\x00\x00\x00\x00E\x1fKP\x00\x00\x00\x00E\xf3~\xc0\x00\x00\x00\x00G\bg\xd0\x00\x00\x00\x00G\xd3`\xc0\x00\x00\x00\x00H\xe8I\xd0\x00\x00\x00\x00I\xb3B\xc0\x00\x00\x00\x00J\xc8+\xd0" + + "\x00\x00\x00\x00K\x9c_@\x00\x00\x00\x00L\xa8\r\xd0\x00\x00\x00\x00M|A@\x00\x00\x00\x00N\x87\xef\xd0\x00\x00\x00\x00O\\#@\x00\x00\x00\x00Pq\fP\x00\x00\x00\x00Q<\x05@\x00\x00\x00\x00" + + "RP\xeeP\x00\x00\x00\x00S\x1b\xe7@\x00\x00\x00\x00T0\xd0P\x00\x00\x00\x00T\xfb\xc9@\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x06\x05\x06\x05\a\x05\a\x05\x06\x05\a\x05\a\x05\b\x06\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05" + + "\a\x05\x05\xff\xff\xcbM\x00\x00\xff\xff\xcbM\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xce\xc8\x00\f\xff\xff\xd5\xd0\x01\x12\xff\xff\xd5\xd0\x00\x12\xff\xff\xdc\xd8\x01\x16\xff\xff\xe3\xe0\x01\x1c\xff\xff\xea\xe8\x01 \xff\xff\xe3" + + "\xe0\x01\x1cLMT\x00MMT\x00-04\x00-0330\x00-03\x00-0230\x00-02\x00-0130\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5" + + "F\x9cPv\x89Z\xa8V\a\x00\x00V\a\x00\x00\x0f\x00\x1c\x00America/GodthabUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00" + + "\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00v\x00\x00\x00\x05\x00\x00\x00\f\x9b\x80h\x00\x13M|P\x143\xfa\x90\x15#" + + "\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#<" + + "E\x10$,6\x10%\x1c'\x10&\f\x18\x10'\x05C\x90'\xf54\x90(\xe5%\x90)\xd5\x16\x90*\xc5\a\x90+\xb4\xf8\x90,\xa4\xe9\x90-\x94ڐ.\x84ː/t\xbc\x900d\xad\x901]" + + "\xd9\x102r\xb4\x103=\xbb\x104R\x96\x105\x1d\x9d\x1062x\x106\xfd\u007f\x108\x1b\x94\x908\xdda\x109\xfbv\x90:\xbdC\x10;\xdbX\x90<\xa6_\x90=\xbb:\x90>\x86A\x90?\x9b" + + "\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e" + + "\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5" + + "\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8" + + "y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e" + + "\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\u007f\xff\xff\xff\x01\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\xff\xffπ\x00\x00\xff\xff\xd5\xd0\x00\x04\xff\xff\xd5\xd0\x00\x04\xff\xff\xe3\xe0\x01\b" + + "\xff\xff\xe3\xe0\x01\bLMT\x00-03\x00-02\x00\x00\x00\x01\x01\x00\x00\x00\x01\x01\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00" + + "\x00\x00\x00v\x00\x00\x00\x05\x00\x00\x00\f\xff\xff\xff\xff\x9b\x80h\x00\x00\x00\x00\x00\x13M|P\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐" + + "\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00" + + "\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10" + + "\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00" + + "I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10" + + "\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00" + + "V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10" + + "\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00" + + "e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90" + + "\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00" + + "s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ" + + "\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x04\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\xff\xffπ\x00\x00" + + "\xff\xff\xd5\xd0\x00\x04\xff\xff\xd5\xd0\x00\x04\xff\xff\xe3\xe0\x01\b\xff\xff\xe3\xe0\x01\bLMT\x00-03\x00-02\x00\x00\x00\x01\x01\x00\x00\x00\x01\x01\x00\n<-03>3<-02>,M" + + "3.5.0/-2,M10.5.0/-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xcf|3(\x94\x00\x00\x00\x94\x00\x00\x00\x12\x00\x1c\x00America/Gu" + + "adeloupeUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\x9373\xac\x01\xff\xff\xc6T\x00\x00\xff\xff\xc7\xc0\x00\x04LMT\x00AST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x9373\xac\x01\xff\xff\xc6T\x00\x00\xff\xff\xc7\xc0\x00\x04LMT\x00AST\x00\nA" + + "ST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xberb\x10\xe8\x02\x00\x00\xe8\x02\x00\x00\x0e\x00\x1c\x00America/MaceioUT\t\x00\x03nӧ^nӧ" + + "^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\x00\x00\x00\x03\x00\x00\x00\f" + + "\x96\xaah|\xb8\x0fI\xe0\xb8\xfd@\xa0\xb9\xf140\xba\xdet \xda8\xae0\xda\xeb\xfa0\xdc\x19\xe1\xb0ܹY \xdd\xfb\x150ޛ\xde \xdfݚ0\xe0T3 \xf4\x97\xff\xb0\xf5\x05^ " + + "\xf6\xc0d0\xf7\x0e\x1e\xa0\xf8Q,0\xf8\xc7\xc5 \xfa\nҰ\xfa\xa8\xf8\xa0\xfb\xec\x060\xfc\x8b}\xa0\x1dɎ0\x1exנ\x1f\xa05\xb0 3Ϡ!\x81i0\"\vȠ#X\x10\xb0" + + "#\xe2p %7\xf2\xb0%\xd4\xc7 0\x80y01\x1dM\xa07\xf6ư8\xb8\x85 9\xdf\xe309\xf2J ;\xc8\xff\xb03\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb2\xde)%.\b" + + "\x00\x00.\b\x00\x00\x13\x00\x1c\x00America/PangnirtungUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZi" + + "f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00z\x00\x00\x00\f\x00\x00\x00)\xa3\xd5R\x80ˈ\xe2`\xd2#\xf4p\xd2`\xed\xd0\xf7/0" + + "@\xf8([\xc0\x13i9\xe0\x14Y\x1c\xd0\x15I\x1b\xe0\x168\xfe\xd0\x17(\xfd\xe0\x18\"\x1bP\x19\b\xdf\xe0\x1a\x01\xfdP\x1a\xf1\xfc`\x1b\xe1\xdfP\x1c\xd1\xde`\x1d\xc1\xc1P\x1e\xb1\xc0`\x1f\xa1\xa3" + + "P u\xf2\xe0!\x81\x85P\"U\xd4\xe0#j\xa1\xd0$5\xb6\xe0%J\x83\xd0&\x15\x98\xe0'*e\xd0'\xfe\xb5`)\nG\xd0)ޗ`*\xea)\xd0+\xbey`,\xd3FP-\x9e[" + + "`.\xb3(P/~=`0\x93\x18`1gg\xf02r\xfa`3GI\xf04R\xdc`5'+\xf062\xbe`7\a\r\xf08\x1b\xda\xe08\xe6\xfe\x009\xfb\xca\xf0:\xc6\xd1\xf0;۞" + + "\xe0<\xaf\xeep=\xbb\x80\xe0>\x8f\xd0p?\x9bb\xe0@o\xb2pA\x84\u007f`BO\x94pCda`D/vpEDC`E\xf3\xa8\xf0G-_\xe0Gӊ\xf0I\rA\xe0I\xb3l" + + "\xf0J\xed#\xe0K\x9c\x89pL\xd6@`M|kpN\xb6\"`O\\MpP\x96\x04`Q\x8f\xd0p\x00\x00\x00\x00" + + "?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\u007f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0" + + "\x00\x00\x00\x00G-_\xe0\x00\x00\x00\x00Gӊ\xf0\x00\x00\x00\x00I\rA\xe0\x00\x00\x00\x00I\xb3l\xf0\x00\x00\x00\x00J\xed#\xe0\x00\x00\x00\x00K\x9c\x89p\x00\x00\x00\x00L\xd6@`\x00\x00\x00\x00" + + "M|kp\x00\x00\x00\x00N\xb6\"`\x00\x00\x00\x00O\\Mp\x00\x00\x00\x00P\x96\x04`\x00\x00\x00\x00QP\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xc8\x1b\x00\x00\xff\xff\xc8\x1b\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xc7\xc0\x00\fLMT\x00BMT\x00ADT\x00AST" + + "\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\xa9y$\xe5\xff\xff\xff\xff\xb8\x85c" + + "\xe5\x00\x00\x00\x00\x0e\x00\xf2\xe0\x00\x00\x00\x00\x0e\x94\x8c\xd0\x00\x00\x00\x00\x0f\x97\x00\xe0\x00\x00\x00\x00\x10tn\xd0\x00\x00\x00\x00\x11v\xe2\xe0\x00\x00\x00\x00\x12TP\xd0\x00\x00\x00\x00\x13_\xff`\x00\x00\x00" + + "\x00\x140>P\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xc8\x1b\x00\x00\xff\xff\xc8\x1b\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xc7\xc0\x00\fLMT\x00BMT\x00ADT\x00AST\x00\nAST4" + + "\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf1\x1ak\xd0\xf0\a\x00\x00\xf0\a\x00\x00\x0f\x00\x1c\x00America/IqaluitUT\t\x00\x03nӧ^nӧ^u" + + "x\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00y\x00\x00\x00\n\x00\x00\x00!\xccl" + + "\xa1\x80\xd2#\xf4p\xd2`\xfb\xe0\xf7/>P\xf8(i\xd0\x13iG\xf0\x14Y*\xe0\x15I)\xf0\x169\f\xe0\x17)\v\xf0\x18\")`\x19\b\xed\xf0\x1a\x02\v`\x1a\xf2\np\x1b\xe1\xed`\x1c\xd1" + + "\xecp\x1d\xc1\xcf`\x1e\xb1\xcep\x1f\xa1\xb1` v\x00\xf0!\x81\x93`\"U\xe2\xf0#j\xaf\xe0$5\xc4\xf0%J\x91\xe0&\x15\xa6\xf0'*s\xe0'\xfe\xc3p)\nU\xe0)ޥp*\xea" + + "7\xe0+\xbe\x87p,\xd3T`-\x9eip.\xb36`/~Kp0\x93\x18`1gg\xf02r\xfa`3GI\xf04R\xdc`5'+\xf062\xbe`7\a\r\xf08\x1b\xda\xe08\xe6" + + "\xfe\x009\xfb\xca\xf0:\xc6\xd1\xf0;۞\xe0<\xaf\xeep=\xbb\x80\xe0>\x8f\xd0p?\x9bb\xe0@o\xb2pA\x84\u007f`BO\x94pCda`D/vpEDC`E\xf3\xa8\xf0G-" + + "_\xe0Gӊ\xf0I\rA\xe0I\xb3l\xf0J\xed#\xe0K\x9c\x89pL\xd6@`M|kpN\xb6\"`O\\MpP\x96\x04`QP\xff\xff\xff\xff\xf8(i\xd0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0" + + "\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00" + + "\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0" + + "\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00" + + ",\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0" + + "\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00" + + ":\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\u007f`" + + "\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x00\x00\x00\x00G-_\xe0\x00\x00\x00\x00Gӊ\xf0\x00\x00\x00\x00" + + "I\rA\xe0\x00\x00\x00\x00I\xb3l\xf0\x00\x00\x00\x00J\xed#\xe0\x00\x00\x00\x00K\x9c\x89p\x00\x00\x00\x00L\xd6@`\x00\x00\x00\x00M|kp\x00\x00\x00\x00N\xb6\"`\x00\x00\x00\x00O\\Mp" + + "\x00\x00\x00\x00P\x96\x04`\x00\x00\x00\x00Q\x8f\xde" + + "\x80?\x9bp\xf0@o\xc0\x80A\x84\x8dpBO\xa2\x80CdopD/\x84\x80EDQpE\xf3\xb7\x00G-m\xf0Gә\x00I\rO\xf0I\xb3{\x00J\xed1\xf0K\x9c\x97\x80L\xd6N" + + "pM|y\x80N\xb60pO\\[\x80P\x96\x12pQ<=\x80Ru\xf4pS\x1c\x1f\x80TU\xd6pT\xfc\x01\x80V5\xb8pV\xe5\x1e\x00X\x1e\xd4\xf0X\xc5\x00\x00Y\xfe\xb6\xf0Z\xa4\xe2" + + "\x00[ޘ\xf0\\\x84\xc4\x00]\xbez\xf0^d\xa6\x00_\x9e\\\xf0`M\u0080a\x87ypb-\xa4\x80cg[pd\r\x86\x80eG=pe\xedh\x80g'\x1fpg\xcdJ\x80i\a\x01" + + "pi\xad,\x80j\xe6\xe3pk\x96I\x00l\xcf\xff\xf0mv+\x00n\xaf\xe1\xf0oV\r\x00p\x8f\xc3\xf0q5\xef\x00ro\xa5\xf0s\x15\xd1\x00tO\x87\xf0t\xfe\xed\x80v8\xa4pv\xde\xcf" + + "\x80x\x18\x86px\xbe\xb1\x80y\xf8hpz\x9e\x93\x80{\xd8Jp|~u\x80}\xb8,p~^W\x80\u007f\x98\x0ep\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x05\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\xff\xff\xad\xdd\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xab\xa0\x00\bLMT\x00CDT\x00CST\x00CWT\x00CP" + + "T\x00EST\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x01\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x8f\x00\x00\x00\a" + + "\x00\x00\x00\x18\xff\xff\xff\xffawIc\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p" + + "\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\bg\xf0\xff\xff\xff\xff\xfe\xb8+\x00\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00" + + "\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80" + + "\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00" + + "\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp" + + "\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00" + + "#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80" + + "\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x00" + + "1gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0" + + "\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00" + + "?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00" + + "\x00\x00\x00\x00G-m\xf0\x00\x00\x00\x00Gә\x00\x00\x00\x00\x00I\rO\xf0\x00\x00\x00\x00I\xb3{\x00\x00\x00\x00\x00J\xed1\xf0\x00\x00\x00\x00K\x9c\x97\x80\x00\x00\x00\x00L\xd6Np\x00\x00\x00\x00" + + "M|y\x80\x00\x00\x00\x00N\xb60p\x00\x00\x00\x00O\\[\x80\x00\x00\x00\x00P\x96\x12p\x00\x00\x00\x00Q<=\x80\x00\x00\x00\x00Ru\xf4p\x00\x00\x00\x00S\x1c\x1f\x80\x00\x00\x00\x00TU\xd6p" + + "\x00\x00\x00\x00T\xfc\x01\x80\x00\x00\x00\x00V5\xb8p\x00\x00\x00\x00V\xe5\x1e\x00\x00\x00\x00\x00X\x1e\xd4\xf0\x00\x00\x00\x00X\xc5\x00\x00\x00\x00\x00\x00Y\xfe\xb6\xf0\x00\x00\x00\x00Z\xa4\xe2\x00\x00\x00\x00\x00" + + "[ޘ\xf0\x00\x00\x00\x00\\\x84\xc4\x00\x00\x00\x00\x00]\xbez\xf0\x00\x00\x00\x00^d\xa6\x00\x00\x00\x00\x00_\x9e\\\xf0\x00\x00\x00\x00`M\u0080\x00\x00\x00\x00a\x87yp\x00\x00\x00\x00b-\xa4\x80" + + "\x00\x00\x00\x00cg[p\x00\x00\x00\x00d\r\x86\x80\x00\x00\x00\x00eG=p\x00\x00\x00\x00e\xedh\x80\x00\x00\x00\x00g'\x1fp\x00\x00\x00\x00g\xcdJ\x80\x00\x00\x00\x00i\a\x01p\x00\x00\x00\x00" + + "i\xad,\x80\x00\x00\x00\x00j\xe6\xe3p\x00\x00\x00\x00k\x96I\x00\x00\x00\x00\x00l\xcf\xff\xf0\x00\x00\x00\x00mv+\x00\x00\x00\x00\x00n\xaf\xe1\xf0\x00\x00\x00\x00oV\r\x00\x00\x00\x00\x00p\x8f\xc3\xf0" + + "\x00\x00\x00\x00q5\xef\x00\x00\x00\x00\x00ro\xa5\xf0\x00\x00\x00\x00s\x15\xd1\x00\x00\x00\x00\x00tO\x87\xf0\x00\x00\x00\x00t\xfe\xed\x80\x00\x00\x00\x00v8\xa4p\x00\x00\x00\x00v\xdeπ\x00\x00\x00\x00" + + "x\x18\x86p\x00\x00\x00\x00x\xbe\xb1\x80\x00\x00\x00\x00y\xf8hp\x00\x00\x00\x00z\x9e\x93\x80\x00\x00\x00\x00{\xd8Jp\x00\x00\x00\x00|~u\x80\x00\x00\x00\x00}\xb8,p\x00\x00\x00\x00~^W\x80" + + "\x00\x00\x00\x00\u007f\x98\x0ep\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x05\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xad\xdd\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01" + + "\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xab\xa0\x00\bLMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x01\x00\x00\nCST6CDT," + + "M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x97\xa99\xc2\xe8\x00\x00\x00\xe8\x00\x00\x00\x12\x00\x1c\x00America/Martini" + + "queUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x11\x80\x00\x00\x00\x91\xa3\xc8D\x13Mn@\x144\x16\xb0\x01\x02\x03\x02\xff\xffƼ\x00\x00\xff\xffƼ\x00\x04\xff\xff\xc7\xc0\x00\t\xff\xff\xd5\xd0\x01\rL" + + "MT\x00FFMT\x00AST\x00ADT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x11" + + "\xff\xff\xff\xffi\x87\x14\xc4\xff\xff\xff\xff\x91\xa3\xc8D\x00\x00\x00\x00\x13Mn@\x00\x00\x00\x00\x144\x16\xb0\x01\x02\x03\x02\xff\xffƼ\x00\x00\xff\xffƼ\x00\x04\xff\xff\xc7\xc0\x00\t\xff\xff\xd5\xd0\x01\r" + + "LMT\x00FFMT\x00AST\x00ADT\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPM\x16R\xd50\x06\x00\x000\x06\x00\x00\x13\x00\x1c\x00America" + + "/Mexico_CityUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\x00\x00\x00\x05\x00\x00\x00\x14\xa5\xb6\xe8p\xaf\xf2n\xe0\xb6fV`\xb7C\xd2`\xb8\f6`\xb8\xfd\x86\xf0\xc5ް`Ɨ4P\xc9U\xf1\xe0" + + "\xc9\xea\xddP\xcf\x02\xc6\xe0ϷVPڙ\x15\xe0\xdbv\x83\xd01gv\x002s\bp3GX\x004R\xeap5':\x0062\xccp7\a\x1c\x008\x1b\xe8\xf08\xe6\xfe\x009\xfb\xca\xf0" + + ":\xf5\x04\x80;\xb6\xc2\xf0<\xaf\xfc\x80=\xbb\x8e\xf0>\x8fހ?\x9bp\xf0@o\xc0\x80A\x84\x8dpBO\xa2\x80CdopD/\x84\x80EDQpF\x0ff\x80G$3pG\xf8\x83\x00" + + "I\x04\x15pI\xd8e\x00J\xe3\xf7pK\xb8G\x00L\xcd\x13\xf0M\x98)\x00N\xac\xf5\xf0Ox\v\x00P\x8c\xd7\xf0Qa'\x80Rl\xb9\xf0SA\t\x80TL\x9b\xf0U \xeb\x80V,}\xf0" + + "W\x00̀X\x15\x9apXீY\xf5|pZ\xc0\x91\x80[\xd5^p\\\xa9\xae\x00]\xb5@p^\x89\x90\x00_\x95\"p`ir\x00a~>\xf0bIT\x00c^ \xf0d)6\x00" + + "e>\x02\xf0f\x12R\x80g\x1d\xe4\xf0g\xf24\x80h\xfd\xc6\xf0i\xd2\x16\x80jݨ\xf0k\xb1\xf8\x80l\xc6\xc5pm\x91ڀn\xa6\xa7poq\xbc\x80p\x86\x89pqZ\xd9\x00rfkp" + + "s:\xbb\x00tFMpu\x1a\x9d\x00v/i\xf0v\xfa\u007f\x00x\x0fK\xf0x\xdaa\x00y\xef-\xf0z\xbaC\x00{\xcf\x0f\xf0|\xa3_\x80}\xae\xf1\xf0~\x83A\x80\u007f\x8e\xd3\xf0\x01\x02\x01\x02" + + "\x01\x02\x03\x02\x03\x02\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\xff\xff\xa3\f\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff" + + "\xb9\xb0\x01\x10LMT\x00MST\x00CST\x00CDT\x00CWT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b" + + "\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff" + + "\xc5ް`\xff\xff\xff\xffƗ4P\xff\xff\xff\xff\xc9U\xf1\xe0\xff\xff\xff\xff\xc9\xea\xddP\xff\xff\xff\xff\xcf\x02\xc6\xe0\xff\xff\xff\xffϷVP\xff\xff\xff\xffڙ\x15\xe0\xff\xff\xff\xff\xdbv\x83\xd0" + + "\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x00" + + "8\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ" + + "\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00" + + "F\x0ff\x80\x00\x00\x00\x00G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00K\xb8G\x00\x00\x00\x00\x00L\xcd\x13\xf0" + + "\x00\x00\x00\x00M\x98)\x00\x00\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00Ox\v\x00\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00Rl\xb9\xf0\x00\x00\x00\x00SA\t\x80\x00\x00\x00\x00" + + "TL\x9b\xf0\x00\x00\x00\x00U \xeb\x80\x00\x00\x00\x00V,}\xf0\x00\x00\x00\x00W\x00̀\x00\x00\x00\x00X\x15\x9ap\x00\x00\x00\x00Xீ\x00\x00\x00\x00Y\xf5|p\x00\x00\x00\x00Z\xc0\x91\x80" + + "\x00\x00\x00\x00[\xd5^p\x00\x00\x00\x00\\\xa9\xae\x00\x00\x00\x00\x00]\xb5@p\x00\x00\x00\x00^\x89\x90\x00\x00\x00\x00\x00_\x95\"p\x00\x00\x00\x00`ir\x00\x00\x00\x00\x00a~>\xf0\x00\x00\x00\x00" + + "bIT\x00\x00\x00\x00\x00c^ \xf0\x00\x00\x00\x00d)6\x00\x00\x00\x00\x00e>\x02\xf0\x00\x00\x00\x00f\x12R\x80\x00\x00\x00\x00g\x1d\xe4\xf0\x00\x00\x00\x00g\xf24\x80\x00\x00\x00\x00h\xfd\xc6\xf0" + + "\x00\x00\x00\x00i\xd2\x16\x80\x00\x00\x00\x00jݨ\xf0\x00\x00\x00\x00k\xb1\xf8\x80\x00\x00\x00\x00l\xc6\xc5p\x00\x00\x00\x00m\x91ڀ\x00\x00\x00\x00n\xa6\xa7p\x00\x00\x00\x00oq\xbc\x80\x00\x00\x00\x00" + + "p\x86\x89p\x00\x00\x00\x00qZ\xd9\x00\x00\x00\x00\x00rfkp\x00\x00\x00\x00s:\xbb\x00\x00\x00\x00\x00tFMp\x00\x00\x00\x00u\x1a\x9d\x00\x00\x00\x00\x00v/i\xf0\x00\x00\x00\x00v\xfa\u007f\x00" + + "\x00\x00\x00\x00x\x0fK\xf0\x00\x00\x00\x00x\xdaa\x00\x00\x00\x00\x00y\xef-\xf0\x00\x00\x00\x00z\xbaC\x00\x00\x00\x00\x00{\xcf\x0f\xf0\x00\x00\x00\x00|\xa3_\x80\x00\x00\x00\x00}\xae\xf1\xf0\x00\x00\x00\x00" + + "~\x83A\x80\x00\x00\x00\x00\u007f\x8e\xd3\xf0\x01\x02\x01\x02\x01\x02\x03\x02\x03\x02\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\xff\xff\xa3\f\x00\x00\xff\xff\x9d\x90" + + "\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10LMT\x00MST\x00CST\x00CDT\x00CWT\x00\nCST6CDT,M4.1.0,M10." + + "5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPyn\x92m0\x02\x00\x000\x02\x00\x00\x15\x00\x1c\x00America/Swift_CurrentUT\t\x00\x03" + + "nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x17\x00" + + "\x00\x00\x06\x00\x00\x00\x18\x86\xfd\x96\x18\x9e\xb8\xaf\x90\x9f\xbb\a\x80ˉ\f\x90\xd2#\xf4p\xd2a\x18\x00\xd3v\x01\x10\xd4So\x00\xd5U\xe3\x10\xd6 \xdc\x00\xd75\xc5\x10\xd8\x00\xbe\x00\xd9\x15\xa7\x10\xd9" + + "\xe0\xa0\x00\xe8',\x10\xe9\x17\x0f\x00\xeb\xe6\xf0\x10\xec\xd6\xd3\x00\xed\xc6\xd2\x10\xee\x91\xcb\x00\xef\xaf\xee\x90\xf0q\xad\x00\x04a\x19\x90\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x05\xff\xff\x9a\xe8\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xab\xa0\x00\x14LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CS" + + "T\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff" + + "\xff\xff\x86\xfd\x96\x18\xff\xff\xff\xff\x9e\xb8\xaf\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xd3v\x01\x10\xff\xff\xff\xff\xd4S" + + "o\x00\xff\xff\xff\xff\xd5U\xe3\x10\xff\xff\xff\xff\xd6 \xdc\x00\xff\xff\xff\xff\xd75\xc5\x10\xff\xff\xff\xff\xd8\x00\xbe\x00\xff\xff\xff\xff\xd9\x15\xa7\x10\xff\xff\xff\xff\xd9\xe0\xa0\x00\xff\xff\xff\xff\xe8',\x10\xff\xff" + + "\xff\xff\xe9\x17\x0f\x00\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xd6\xd3\x00\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xcb\x00\xff\xff\xff\xff\xef\xaf\xee\x90\xff\xff\xff\xff\xf0q\xad\x00\x00\x00\x00\x00\x04a" + + "\x19\x90\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\xff\xff\x9a\xe8\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xab\xa0\x00" + + "\x14LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CST\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00\nCST6\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x854\x86" + + "\x9d\x82\x06\x00\x00\x82\x06\x00\x00\x10\x00\x1c\x00America/MiquelonUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZi" + + "f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00i\x00\x00\x00\x04\x00\x00\x00\x10\x91\xb68\xa8\x13nc\xc0 u\xe4\xd0!\x81w@\"U\xc6" + + "\xd0#j\x93\xc0$5\xa8\xd0%Ju\xc0&\x15\x8a\xd0'*W\xc0'\xfe\xa7P)\n9\xc0)މP*\xea\x1b\xc0+\xbekP,\xd38@-\x9eMP.\xb3\x1a@/~/P0\x92\xfc" + + "@1gK\xd02r\xde@3G-\xd04R\xc0@5'\x0f\xd062\xa2@7\x06\xf1\xd08\x1b\xbe\xc08\xe6\xd3\xd09\xfb\xa0\xc0:Ƶ\xd0;ۂ\xc0<\xaf\xd2P=\xbbd\xc0>\x8f\xb4" + + "P?\x9bF\xc0@o\x96PA\x84c@BOxPCdE@D/ZPED'@E\xf3\x8c\xd0G-C\xc0G\xd3n\xd0I\r%\xc0I\xb3P\xd0J\xed\a\xc0K\x9cmPL\xd6$" + + "@M|OPN\xb6\x06@O\\1PP\x95\xe8@Q<\x13PRu\xca@S\x1b\xf5PTU\xac@T\xfb\xd7PV5\x8e@V\xe4\xf3\xd0X\x1e\xaa\xc0X\xc4\xd5\xd0Y\xfe\x8c\xc0Z\xa4\xb7" + + "\xd0[\xden\xc0\\\x84\x99\xd0]\xbeP\xc0^d{\xd0_\x9e2\xc0`M\x98Pa\x87O@b-zPcg1@d\r\\PeG\x13@e\xed>Pg&\xf5@g\xcd Pi\x06\xd7" + + "@i\xad\x02Pj\xe6\xb9@k\x96\x1e\xd0l\xcf\xd5\xc0mv\x00\xd0n\xaf\xb7\xc0oU\xe2\xd0p\x8f\x99\xc0q5\xc4\xd0ro{\xc0s\x15\xa6\xd0tO]\xc0t\xfe\xc3Pv8z@vޥ" + + "Px\x18\\@x\xbe\x87Py\xf8>@z\x9eiP{\xd8 @|~KP}\xb8\x02@~^-P\u007f\x97\xe4@\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\xff\xff\xcbX\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x00\b\xff\xff\xe3\xe0\x01\fLMT\x00AST\x00-0" + + "3\x00-02\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00i\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x91\xb68\xa8\x00\x00" + + "\x00\x00\x13nc\xc0\x00\x00\x00\x00 u\xe4\xd0\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"U\xc6\xd0\x00\x00\x00\x00#j\x93\xc0\x00\x00\x00\x00$5\xa8\xd0\x00\x00\x00\x00%Ju\xc0\x00\x00\x00\x00&\x15" + + "\x8a\xd0\x00\x00\x00\x00'*W\xc0\x00\x00\x00\x00'\xfe\xa7P\x00\x00\x00\x00)\n9\xc0\x00\x00\x00\x00)މP\x00\x00\x00\x00*\xea\x1b\xc0\x00\x00\x00\x00+\xbekP\x00\x00\x00\x00,\xd38@\x00\x00" + + "\x00\x00-\x9eMP\x00\x00\x00\x00.\xb3\x1a@\x00\x00\x00\x00/~/P\x00\x00\x00\x000\x92\xfc@\x00\x00\x00\x001gK\xd0\x00\x00\x00\x002r\xde@\x00\x00\x00\x003G-\xd0\x00\x00\x00\x004R" + + "\xc0@\x00\x00\x00\x005'\x0f\xd0\x00\x00\x00\x0062\xa2@\x00\x00\x00\x007\x06\xf1\xd0\x00\x00\x00\x008\x1b\xbe\xc0\x00\x00\x00\x008\xe6\xd3\xd0\x00\x00\x00\x009\xfb\xa0\xc0\x00\x00\x00\x00:Ƶ\xd0\x00\x00" + + "\x00\x00;ۂ\xc0\x00\x00\x00\x00<\xaf\xd2P\x00\x00\x00\x00=\xbbd\xc0\x00\x00\x00\x00>\x8f\xb4P\x00\x00\x00\x00?\x9bF\xc0\x00\x00\x00\x00@o\x96P\x00\x00\x00\x00A\x84c@\x00\x00\x00\x00BO" + + "xP\x00\x00\x00\x00CdE@\x00\x00\x00\x00D/ZP\x00\x00\x00\x00ED'@\x00\x00\x00\x00E\xf3\x8c\xd0\x00\x00\x00\x00G-C\xc0\x00\x00\x00\x00G\xd3n\xd0\x00\x00\x00\x00I\r%\xc0\x00\x00" + + "\x00\x00I\xb3P\xd0\x00\x00\x00\x00J\xed\a\xc0\x00\x00\x00\x00K\x9cmP\x00\x00\x00\x00L\xd6$@\x00\x00\x00\x00M|OP\x00\x00\x00\x00N\xb6\x06@\x00\x00\x00\x00O\\1P\x00\x00\x00\x00P\x95" + + "\xe8@\x00\x00\x00\x00Q<\x13P\x00\x00\x00\x00Ru\xca@\x00\x00\x00\x00S\x1b\xf5P\x00\x00\x00\x00TU\xac@\x00\x00\x00\x00T\xfb\xd7P\x00\x00\x00\x00V5\x8e@\x00\x00\x00\x00V\xe4\xf3\xd0\x00\x00" + + "\x00\x00X\x1e\xaa\xc0\x00\x00\x00\x00X\xc4\xd5\xd0\x00\x00\x00\x00Y\xfe\x8c\xc0\x00\x00\x00\x00Z\xa4\xb7\xd0\x00\x00\x00\x00[\xden\xc0\x00\x00\x00\x00\\\x84\x99\xd0\x00\x00\x00\x00]\xbeP\xc0\x00\x00\x00\x00^d" + + "{\xd0\x00\x00\x00\x00_\x9e2\xc0\x00\x00\x00\x00`M\x98P\x00\x00\x00\x00a\x87O@\x00\x00\x00\x00b-zP\x00\x00\x00\x00cg1@\x00\x00\x00\x00d\r\\P\x00\x00\x00\x00eG\x13@\x00\x00" + + "\x00\x00e\xed>P\x00\x00\x00\x00g&\xf5@\x00\x00\x00\x00g\xcd P\x00\x00\x00\x00i\x06\xd7@\x00\x00\x00\x00i\xad\x02P\x00\x00\x00\x00j\xe6\xb9@\x00\x00\x00\x00k\x96\x1e\xd0\x00\x00\x00\x00l\xcf" + + "\xd5\xc0\x00\x00\x00\x00mv\x00\xd0\x00\x00\x00\x00n\xaf\xb7\xc0\x00\x00\x00\x00oU\xe2\xd0\x00\x00\x00\x00p\x8f\x99\xc0\x00\x00\x00\x00q5\xc4\xd0\x00\x00\x00\x00ro{\xc0\x00\x00\x00\x00s\x15\xa6\xd0\x00\x00" + + "\x00\x00tO]\xc0\x00\x00\x00\x00t\xfe\xc3P\x00\x00\x00\x00v8z@\x00\x00\x00\x00vޥP\x00\x00\x00\x00x\x18\\@\x00\x00\x00\x00x\xbe\x87P\x00\x00\x00\x00y\xf8>@\x00\x00\x00\x00z\x9e" + + "iP\x00\x00\x00\x00{\xd8 @\x00\x00\x00\x00|~KP\x00\x00\x00\x00}\xb8\x02@\x00\x00\x00\x00~^-P\x00\x00\x00\x00\u007f\x97\xe4@\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\xff\xff\xcbX\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x00\b\xff\xff\xe3\xe0\x01\fL" + + "MT\x00AST\x00-03\x00-02\x00\n<-03>3<-02>,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP#\x16\x92" + + "r\xba\x00\x00\x00\xba\x00\x00\x00\x0f\x00\x1c\x00America/CuracaoUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif" + + "2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x0e\x93\x1e.#\xf6\x98\xecH\x01\x02\xff\xff\xbf]\x00\x00\xff\xff\xc0\xb8" + + "\x00\x04\xff\xff\xc7\xc0\x00\nLMT\x00-0430\x00AST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00" + + "\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xff\x93\x1e.#\xff\xff\xff\xff\xf6\x98\xecH\x01\x02\xff\xff\xbf]\x00\x00\xff\xff\xc0\xb8\x00\x04\xff\xff\xc7\xc0\x00\nLMT\x00-0430\x00AST\x00\nAST" + + "4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb2\xeb-;\x1a\x04\x00\x00\x1a\x04\x00\x00\x14\x00\x1c\x00America/Dawson_CreekUT\t\x00\x03nӧ" + + "^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00:\x00\x00\x00\x06" + + "\x00\x00\x00\x18\x80\x00\x00\x00\x9e\xb8\xbd\xa0\x9f\xbb\x15\x90ˉ\x1a\xa0\xd2#\xf4p\xd2a&\x10\xd5U\xf1 \xd6 \xea\x10\xd75\xd3 \xd8\x00\xcc\x10\xd9\x15\xb5 \xd9\xe0\xae\x10\xda\xfeѠ\xdb\xc0\x90\x10" + + "\xdc\u07b3\xa0ݩ\xac\x90\u07be\x95\xa0߉\x8e\x90\xe0\x9ew\xa0\xe1ip\x90\xe2~Y\xa0\xe3IR\x90\xe4^;\xa0\xe5)4\x90\xe6GX \xe7\x12Q\x10\xe8': \xe8\xf23\x10\xea\a\x1c " + + "\xea\xd2\x15\x10\xeb\xe6\xfe \xec\xb1\xf7\x10\xed\xc6\xe0 \xee\x91\xd9\x10\xef\xaf\xfc\xa0\xf0q\xbb\x10\xf1\x8fޠ\xf2\u007f\xc1\x90\xf3o\xc0\xa0\xf4_\xa3\x90\xf5O\xa2\xa0\xf6?\x85\x90\xf7/\x84\xa0\xf8(\xa2\x10" + + "\xf9\x0ff\xa0\xfa\b\x84\x10\xfa\xf8\x83 \xfb\xe8f\x10\xfc\xd8e \xfd\xc8H\x10\xfe\xb8G \xff\xa8*\x10\x00\x98) \x01\x88\f\x10\x02x\v \x03q(\x90\x04a'\xa0\x05\x01\xf0\x90\x02\x01\x02\x03" + + "\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x05\xff\xff\x8fH\x00\x00" + + "\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x00\x14LMT\x00PDT\x00PST\x00PWT\x00PPT\x00MST\x00\x00\x00\x00\x00\x01\x00" + + "\x00\x00\x00\x00\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00:\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^=t8\xff\xff" + + "\xff\xff\x9e\xb8\xbd\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xd5U\xf1 \xff\xff\xff\xff\xd6 \xea\x10\xff\xff\xff\xff\xd75" + + "\xd3 \xff\xff\xff\xff\xd8\x00\xcc\x10\xff\xff\xff\xff\xd9\x15\xb5 \xff\xff\xff\xff\xd9\xe0\xae\x10\xff\xff\xff\xff\xda\xfeѠ\xff\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdc\u07b3\xa0\xff\xff\xff\xffݩ\xac\x90\xff\xff" + + "\xff\xff\u07be\x95\xa0\xff\xff\xff\xff߉\x8e\x90\xff\xff\xff\xff\xe0\x9ew\xa0\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~Y\xa0\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^;\xa0\xff\xff\xff\xff\xe5)" + + "4\x90\xff\xff\xff\xff\xe6GX \xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8': \xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x1c \xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xfe \xff\xff" + + "\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xe0 \xff\xff\xff\xff\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xfc\xa0\xff\xff\xff\xff\xf0q\xbb\x10\xff\xff\xff\xff\xf1\x8fޠ\xff\xff\xff\xff\xf2\u007f\xc1\x90\xff\xff\xff\xff\xf3o" + + "\xc0\xa0\xff\xff\xff\xff\xf4_\xa3\x90\xff\xff\xff\xff\xf5O\xa2\xa0\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/\x84\xa0\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0ff\xa0\xff\xff\xff\xff\xfa\b\x84\x10\xff\xff" + + "\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88" + + "\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05\x01\xf0\x90\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x05\xff\xff\x8fH\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90" + + "\x01\x10\xff\xff\x9d\x90\x00\x14LMT\x00PDT\x00PST\x00PWT\x00PPT\x00MST\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00\nMST7\nPK\x03\x04\n\x00\x00\x00\x00\x00" + + "\xf5F\x9cP\x1a\xdb?\x854\x04\x00\x004\x04\x00\x00\x0f\x00\x1c\x00America/MendozaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14" + + "\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06\x00\x00\x00\x14\x80\x00\x00\x00\xa2\x92\x8f0\xb6{R@\xb7" + + "\x1aɰ\xb8\x1e\x8f@\xb8\xd4p0\xba\x17}\xc0\xba\xb5\xa3\xb0\xbb\xf8\xb1@\xbc\x96\xd70\xbd\xd9\xe4\xc0\xbex\n\xb0\xbf\xbb\x18@\xc0Z\x8f\xb0\xc1\x9d\x9d@\xc2;\xc30\xc3~\xd0\xc0\xc4\x1c\xf6\xb0\xc5" + + "`\x04@\xc5\xfe*0\xc7A7\xc0\xc7\xe0\xaf0ȁ\x94@\xcaM\xa1\xb0\xca\xee\x86\xc0\xceM\xff0ΰ\xed\xc0\xd3)5\xb0\xd4Cd\xc0\xf4=\b0\xf4\x9f\xf6\xc0\xf5\x05l0\xf62\x10@\xf6" + + "柰\xf8\x13C\xc0\xf8\xc7\xd30\xf9\xf4w@\xfa\xd36\xb0\xfb\xc35\xc0\xfc\xbcS0\xfd\xacR@\xfe\x9c50\xff\x8c4@\a\xa3J\xb0\b$o\xa0#\x94\xb5\xb0$\x10\x94\xa0%7\xf2\xb0%" + + "\xf0v\xa0'\x194@'\xcdð(\xfag\xc0)\xb0H\xb0*\xe0\xe1@+\x99W 7\xf6ư8\xbf*\xb0@\xb0\x13\xb0AV>\xc0Gw\t\xb0G\xdc\u007f \u007f\xff\xff\xff\x01\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x03\x02\x04\x05\x03\x05\x02\x05\x04\x05\x05\xff\xff\xbf" + + "|\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00TZif2\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb2\x04\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R" + + "@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff" + + "\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6" + + "\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff" + + "\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10" + + "@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff" + + "\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2" + + "\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'\x194@\x00\x00\x00\x00'\xcdð\x00\x00\x00\x00(\xfag\xc0\x00\x00\x00\x00)\xb0H\xb0\x00\x00\x00\x00*\xe0\xe1@\x00\x00\x00\x00+\x99W \x00\x00\x00" + + "\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xb0\x13\xb0\x00\x00\x00\x00AV>\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\u007f \x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x03\x02\x04\x05\x03\x05\x02\x05\x04\x05\x05\xff\xff\xbf|\x00" + + "\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nP" + + "K\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPh\xef\x10-4\t\x00\x004\t\x00\x00\f\x00\x1c\x00America/AdakUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04" + + "\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00\x00\t\x00\x00\x00!\x80\x00\x00\x00ˉD" + + "\xd0\xd2#\xf4p\xd2aP@\xfa\xd2U\xb0\xfe\xb8qP\xff\xa8T@\x00\x98SP\x01\x886@\x02x5P\x03qR\xc0\x04aQ\xd0\x05Q4\xc0\x06A3\xd0\a1\x16\xc0\a\x8dm\xd0\t\x10\xf8" + + "\xc0\t\xad\xe9P\n\xf0\xda\xc0\v\xe0\xd9\xd0\f\xd9\xf7@\r\xc0\xbb\xd0\x0e\xb9\xd9@\x0f\xa9\xd8P\x10\x99\xbb@\x11\x89\xbaP\x12y\x9d@\x13i\x9cP\x14Y\u007f@\x15I~P\x169a@\x17)`" + + "P\x18\"}\xc0\x19\tBP\x1a\x02_\xc0\x1a+\" \x1a\xf2P\xc0\x1b\xe23\xb0\x1c\xd22\xc0\x1d\xc2\x15\xb0\x1e\xb2\x14\xc0\x1f\xa1\xf7\xb0 vG@!\x81ٰ\"V)@#j\xf60$6\v" + + "@%J\xd80&\x15\xed@'*\xba0'\xff\t\xc0)\n\x9c0)\xde\xeb\xc0*\xea~0+\xbe\xcd\xc0,Ӛ\xb0-\x9e\xaf\xc0.\xb3|\xb0/~\x91\xc00\x93^\xb01g\xae@2s@" + + "\xb03G\x90@4S\"\xb05'r@63\x04\xb07\aT@8\x1c!08\xe76@9\xfc\x030:\xc7\x18@;\xdb\xe50<\xb04\xc0=\xbb\xc70>\x90\x16\xc0?\x9b\xa90@o\xf8" + + "\xc0A\x84ŰBO\xda\xc0Cd\xa7\xb0D/\xbc\xc0ED\x89\xb0E\xf3\xef@G-\xa60G\xd3\xd1@I\r\x880I\xb3\xb3@J\xedj0K\x9c\xcf\xc0Lֆ\xb0M|\xb1\xc0N\xb6h" + + "\xb0O\\\x93\xc0P\x96J\xb0Q\x90\x16\xc0\x00\x00\x00\x00?\x9b\xa90\x00\x00\x00\x00@o\xf8\xc0\x00\x00\x00\x00A\x84Ű\x00\x00\x00\x00BO" + + "\xda\xc0\x00\x00\x00\x00Cd\xa7\xb0\x00\x00\x00\x00D/\xbc\xc0\x00\x00\x00\x00ED\x89\xb0\x00\x00\x00\x00E\xf3\xef@\x00\x00\x00\x00G-\xa60\x00\x00\x00\x00G\xd3\xd1@\x00\x00\x00\x00I\r\x880\x00\x00" + + "\x00\x00I\xb3\xb3@\x00\x00\x00\x00J\xedj0\x00\x00\x00\x00K\x9c\xcf\xc0\x00\x00\x00\x00Lֆ\xb0\x00\x00\x00\x00M|\xb1\xc0\x00\x00\x00\x00N\xb6h\xb0\x00\x00\x00\x00O\\\x93\xc0\x00\x00\x00\x00P\x96" + + "J\xb0\x00\x00\x00\x00Q\x8f\xd0p?\x9bb\xe0@o\xb2pA\x84\u007f`BO\x94pCda`D/vpEDC`E\xf3\xa8\xf0G-_\xe0Gӊ\xf0I\rA\xe0I\xb3l\xf0J\xed#\xe0K\x9c" + + "\x89pL\xd6@`M|kpN\xb6\"`O\\MpP\x96\x04`Q\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\u007f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00" + + "\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x00\x00\x00\x00G-_\xe0\x00\x00\x00\x00Gӊ\xf0\x00\x00\x00\x00I\rA\xe0\x00\x00\x00\x00I\xb3l\xf0\x00\x00\x00\x00J\xed#" + + "\xe0\x00\x00\x00\x00K\x9c\x89p\x00\x00\x00\x00L\xd6@`\x00\x00\x00\x00M|kp\x00\x00\x00\x00N\xb6\"`\x00\x00\x00\x00O\\Mp\x00\x00\x00\x00P\x96\x04`\x00\x00\x00\x00Q\x8f\xfa\xa0?\x9b\x8d\x10@oܠA\x84\xa9\x90BO\xbe\xa0Cd\x8b\x90D/" + + "\xa0\xa0EDm\x90E\xf3\xd3 G-\x8a\x10Gӵ I\rl\x10I\xb3\x97 J\xedN\x10K\x9c\xb3\xa0L\xd6j\x90M|\x95\xa0N\xb6L\x90O\\w\xa0P\x96.\x90Q\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00" + + "\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x00\x00\x00\x00G-\x8a\x10\x00\x00\x00\x00Gӵ \x00\x00\x00\x00I\rl\x10\x00\x00\x00\x00I\xb3\x97" + + " \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00M|\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\\w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00" + + "\x00Q\x90\b\xb0?\x9b\x9b @o\xea\xb0A\x84\xb7\xa0BO̰Cd\x99\xa0D/\xae\xb0ED{\xa0E\xf3\xe10G-\x98 G\xd3\xc30I\rz I\xb3\xa50J\xed\\" + + " K\x9c\xc1\xb0L\xd6x\xa0M|\xa3\xb0N\xb6Z\xa0O\\\x85\xb0P\x96<\xa0Q\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO" + + "̰\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x00\x00\x00\x00G-\x98 \x00\x00\x00\x00G\xd3\xc30\x00\x00\x00\x00I\rz \x00\x00" + + "\x00\x00I\xb3\xa50\x00\x00\x00\x00J\xed\\ \x00\x00\x00\x00K\x9c\xc1\xb0\x00\x00\x00\x00L\xd6x\xa0\x00\x00\x00\x00M|\xa3\xb0\x00\x00\x00\x00N\xb6Z\xa0\x00\x00\x00\x00O\\\x85\xb0\x00\x00\x00\x00P\x96" + + "<\xa0\x00\x00\x00\x00Q@\x1ep\xfc\xb0\x1f\x8f @ \u007f\x030!o\x02@\"9\xfb0#N\xe4@$\x19\xdd0%8\x00\xc0" + + "%\xf9\xbf0&\xf2\xf8\xc0'١0(\xf7\xc4\xc0)½\xb0*צ\xc0+\xa2\x9f\xb0,\xb7\x88\xc0-\x82\x81\xb0.\x97j\xc0/bc\xb00\x80\x87@1BE\xb02`i@3=\xd70" + + "4@K@5\vD06\r\xb8@7\x06հ8\x00\x0f@8\xcb\b09\xe9+\xc0:\xaa\xea0;\xc9\r\xc0<\x8a\xcc0=\xa8\xef\xc0>j\xae0?\x88\xd1\xc0@SʰAh\xb3\xc0" + + "B3\xac\xb0CH\x95\xc0D\x13\x8e\xb0E1\xb2@E\xf3p\xb0G\x11\x94@G\xef\x020H\xf1v@I\xbco0J\xd1X@K\xb8\x00\xb0L\xb1:@M\xc6\a0NP\x82\xc0O\x9c\xae\xb0" + + "PB\xd9\xc0Q|\x90\xb0R+\xf6@S\\r\xb0T\v\xd8@W7\xe60W\xaf\xec\xc0XC\x86\xb0\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04\x01\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x04\x04\x00" + + "\x00\x00\x00\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xe3\xe0\x01\f\xff\xff\xd5\xd0\x00\b\xff\xff\xd5\xd0\x01\b\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x00\b-00\x00-04\x00-03\x00-" + + "02\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x01\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00S\x00\x00\x00\b\x00" + + "\x00\x00\x10\xff\xff\xff\xff\xf6\x98\xad\x00\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff" + + "\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00\x170\xbc\xb0\x00\x00\x00\x00\x18" + + "\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00" + + "\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \u007f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"9\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%" + + "\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'١0\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)½\xb0\x00\x00\x00\x00*צ\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00" + + "\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004" + + "@K@\x00\x00\x00\x005\vD0\x00\x00\x00\x006\r\xb8@\x00\x00\x00\x007\x06հ\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\b0\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00" + + "\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@Sʰ\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B" + + "3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00" + + "\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\a0\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00P" + + "B\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T\v\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00XC\x86\xb0\x00" + + "\x00\x00\x00\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04\x01\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x04\x04\x00\x00\x00\x00\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xe3\xe0\x01\f\xff\xff\xd5\xd0\x00\b" + + "\xff\xff\xd5\xd0\x01\b\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x00\b-00\x00-04\x00-03\x00-02\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x01\x01\x00\n<-03>3\nPK" + + "\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa2\xa45\xb7)\x01\x00\x00)\x01\x00\x00\x10\x00\x1c\x00Antarctica/DavisUT\t\x00\x03nӧ^nӧ^ux\v" + + "\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x04\x00\x00\x00\f\xe7\x9c@\x00" + + "\xf6G\xdf\x10\xfeG\xab\x00J\xda\x140K\x97\xfa@N\xa9\xaa0OC\xf7\xc0\u007f\xff\xff\xff\x01\x00\x01\x02\x03\x02\x03\x03\x00\x00\x00\x00\x00\x00\x00\x00bp\x00\x04\x00\x00FP\x00\b\x00\x00bp\x00\x04" + + "-00\x00+07\x00+05\x00\x00\x00\x00\x01\x00\x00\x00\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x04" + + "\x00\x00\x00\f\xff\xff\xff\xff\xe7\x9c@\x00\xff\xff\xff\xff\xf6G\xdf\x10\xff\xff\xff\xff\xfeG\xab\x00\x00\x00\x00\x00J\xda\x140\x00\x00\x00\x00K\x97\xfa@\x00\x00\x00\x00N\xa9\xaa0\x00\x00\x00\x00OC\xf7\xc0" + + "\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x00\x01\x02\x03\x02\x03\x03\x00\x00\x00\x00\x00\x00\x00\x00bp\x00\x04\x00\x00FP\x00\b\x00\x00bp\x00\x04-00\x00+07\x00+05\x00\x00\x00\x00\x01\x00\x00\x00\x01" + + "\n<+07>-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x91h\x16Ƥ\x00\x00\x00\xa4\x00\x00\x00\x12\x00\x1c\x00Antarctica/RotheraUT\t" + + "\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x02\x00\x00\x00\x02\x00\x00\x00\b\r\x02-\x00\u007f\xff\xff\xff\x01\x01\x00\x00\x00\x00\x00\x00\xff\xff\xd5\xd0\x00\x04-00\x00-03\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\x00\x00\x00\x00\r\x02-\x00\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x00\x00\x00\x00\x00\xff\xff\xd5\xd0\x00\x04-00\x00-03" + + "\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP[\xcbΟ\xa5\x00\x00\x00\xa5\x00\x00\x00\x11\x00\x1c\x00Antarctica/VostokUT\t\x00" + + "\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02" + + "\x00\x00\x00\x02\x00\x00\x00\b\xe9X\x89\x80\u007f\xff\xff\xff\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00T`\x00\x04-00\x00+06\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xe9X\x89\x80\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00T`\x00\x04-00\x00+06\x00" + + "\n<+06>-6\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP0\xa4\x84ԥ\x00\x00\x00\xa5\x00\x00\x00\x10\x00\x1c\x00Antarctica/SyowaUT\t\x00\x03" + + "nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + + "\x00\x00\x02\x00\x00\x00\b\xe7\xb1X\x00\u007f\xff\xff\xff\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00*0\x00\x04-00\x00+03\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xe7\xb1X\x00\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00*0\x00\x04-00\x00+03\x00\n" + + "<+03>-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP,(\xa1q\xc2\x00\x00\x00\xc2\x00\x00\x00\x19\x00\x1c\x00Antarctica/DumontDUrvi" + + "lleUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\bԼv\x80\xde4``\xe7<\x02\x80\u007f\xff\xff\xff\x01\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xa0\x00\x04-00\x00+10\x00TZif2" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xffԼv\x80\xff\xff\xff\xff\xde4``\xff\xff\xff\xff\xe7" + + "<\x02\x80\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xa0\x00\x04-00\x00+10\x00\n<+10>-10\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP0" + + ">8\xb8\x85\t\x00\x00\x85\t\x00\x00\x12\x00\x1c\x00Antarctica/McMurdoUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00" + + "\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x9c\x00\x00\x00\a\x00\x00\x00\x13\x80\x00\x00\x00\xb0\xb4\xb2\xe8\xb1Q\x87X\xb2x\xe5" + + "h\xb3C\xe5`\xb4X\xc7h\xb5#\xc7`\xb68\xa9h\xb7\x03\xa9`\xb8\x18\x8bh\xb8\xec\xc5\xe0\xb9\xf8mh\xba̧\xe0\xbb\xd8Oh\xbc\xe3\xe8\u0f6e\xf6\xe8\xbe\xc3\xca࿎\xd8\xe8\xc0\xa3\xac" + + "\xe0\xc1n\xba\xe8\u0083\x8e\xe0\xc3N\x9c\xe8\xc4cp\xe0\xc5.~\xe8\xc6L\x8d`\xc7\x0e`\xe8\xc8,o`\xc8\xf7}h\xd2ښ@\t\x18\xfd\xe0\t\xac\xa5\xe0\n\xef\xa5`\v\x9e\xfc\xe0\f\xd8\xc1" + + "\xe0\r~\xde\xe0\x0e\xb8\xa3\xe0\x0f^\xc0\xe0\x10\x98\x85\xe0\x11>\xa2\xe0\x12xg\xe0\x13\x1e\x84\xe0\x14XI\xe0\x14\xfef\xe0\x168+\xe0\x16\xe7\x83`\x18!H`\x18\xc7e`\x1a\x01*`\x1a\xa7G" + + "`\x1b\xe1\f`\x1c\x87)`\x1d\xc0\xee`\x1eg\v`\x1f\xa0\xd0` F\xed`!\x80\xb2`\"0\t\xe0#i\xce\xe0$\x0f\xeb\xe0%.\x01`&\x02B\xe0'\r\xe3`'\xe2$\xe0(\xed\xc5" + + "`)\xc2\x06\xe0*ͧ`+\xab#`,\xad\x89`-\x8b\x05`.\x8dk`/j\xe7`0mM`1J\xc9`2Vi\xe03*\xab`46K\xe05\n\x8d`6\x16-\xe06\xf3\xa9" + + "\xe07\xf6\x0f\xe08Ӌ\xe09\xd5\xf1\xe0:\xb3m\xe0;\xbf\x0e`<\x93O\xe0=\x9e\xf0`>s1\xe0?~\xd2`@\\N`A^\xb4`B<0`C>\x96`D\x1c\x12`E\x1ex" + + "`E\xfb\xf4`F\xfeZ`G\xf7\x85\xe0H\xde<`I\xd7g\xe0J\xbe\x1e`K\xb7I\xe0L\x9e\x00`M\x97+\xe0N}\xe2`Ow\r\xe0Pf\xfe\xe0Q`*`RF\xe0\xe0S@\f" + + "`T&\xc2\xe0U\x1f\xee`V\x06\xa4\xe0V\xff\xd0`W\xe6\x86\xe0X߲`Y\xc6h\xe0Z\xbf\x94`[\xaf\x85`\\\xa8\xb0\xe0]\x8fg`^\x88\x92\xe0_oI``ht\xe0aO+" + + "`bHV\xe0c/\r`d(8\xe0e\x0e\xef`f\x11U`f\xf8\v\xe0g\xf17`h\xd7\xed\xe0i\xd1\x19`j\xb7\xcf\xe0k\xb0\xfb`l\x97\xb1\xe0m\x90\xdd`nw\x93\xe0op\xbf" + + "`p`\xb0`qY\xdb\xe0r@\x92`s9\xbd\xe0t t`u\x19\x9f\xe0v\x00V`v\xf9\x81\xe0w\xe08`x\xd9c\xe0y\xc0\x1a`z\xb9E\xe0{\xa96\xe0|\xa2b`}\x89\x18" + + "\xe0~\x82D`\u007fh\xfa\xe0\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x06\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x00\x00\xa3\xd8\x00\x00\x00\x00\xaf\xc8\x01\x04\x00\x00\xa1" + + "\xb8\x00\t\x00\x00\xa8\xc0\x01\x04\x00\x00\xb6\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04\x00\x00\xa8\xc0\x00\x04LMT\x00NZST\x00NZMT\x00NZDT\x00\x00\x00\x00\x00\x01\x01\x00TZif2\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x9c\x00\x00\x00\a\x00\x00\x00\x13\xff\xff\xff\xffA\xb7L\xa8\xff\xff\xff\xff\xb0\xb4\xb2\xe8\xff\xff\xff\xff\xb1Q\x87" + + "X\xff\xff\xff\xff\xb2x\xe5h\xff\xff\xff\xff\xb3C\xe5`\xff\xff\xff\xff\xb4X\xc7h\xff\xff\xff\xff\xb5#\xc7`\xff\xff\xff\xff\xb68\xa9h\xff\xff\xff\xff\xb7\x03\xa9`\xff\xff\xff\xff\xb8\x18\x8bh\xff\xff\xff" + + "\xff\xb8\xec\xc5\xe0\xff\xff\xff\xff\xb9\xf8mh\xff\xff\xff\xff\xba̧\xe0\xff\xff\xff\xff\xbb\xd8Oh\xff\xff\xff\xff\xbc\xe3\xe8\xe0\xff\xff\xff\xff\xbd\xae\xf6\xe8\xff\xff\xff\xff\xbe\xc3\xca\xe0\xff\xff\xff\xff\xbf\x8e\xd8" + + "\xe8\xff\xff\xff\xff\xc0\xa3\xac\xe0\xff\xff\xff\xff\xc1n\xba\xe8\xff\xff\xff\xff\u0083\x8e\xe0\xff\xff\xff\xff\xc3N\x9c\xe8\xff\xff\xff\xff\xc4cp\xe0\xff\xff\xff\xff\xc5.~\xe8\xff\xff\xff\xff\xc6L\x8d`\xff\xff\xff" + + "\xff\xc7\x0e`\xe8\xff\xff\xff\xff\xc8,o`\xff\xff\xff\xff\xc8\xf7}h\xff\xff\xff\xff\xd2ښ@\x00\x00\x00\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v\x9e\xfc" + + "\xe0\x00\x00\x00\x00\f\xd8\xc1\xe0\x00\x00\x00\x00\r~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00" + + "\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*" + + "`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\f`\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00" + + "\x00!\x80\xb2`\x00\x00\x00\x00\"0\t\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'\xe2$" + + "\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*ͧ`\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00" + + "\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x006\x16-" + + "\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008Ӌ\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00" + + "\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\\N`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12" + + "`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x00\x00\x00\x00G\xf7\x85\xe0\x00\x00\x00\x00H\xde<`\x00\x00\x00\x00I\xd7g\xe0\x00\x00\x00\x00J\xbe\x1e`\x00\x00\x00" + + "\x00K\xb7I\xe0\x00\x00\x00\x00L\x9e\x00`\x00\x00\x00\x00M\x97+\xe0\x00\x00\x00\x00N}\xe2`\x00\x00\x00\x00Ow\r\xe0\x00\x00\x00\x00Pf\xfe\xe0\x00\x00\x00\x00Q`*`\x00\x00\x00\x00RF\xe0" + + "\xe0\x00\x00\x00\x00S@\f`\x00\x00\x00\x00T&\xc2\xe0\x00\x00\x00\x00U\x1f\xee`\x00\x00\x00\x00V\x06\xa4\xe0\x00\x00\x00\x00V\xff\xd0`\x00\x00\x00\x00W\xe6\x86\xe0\x00\x00\x00\x00X߲`\x00\x00\x00" + + "\x00Y\xc6h\xe0\x00\x00\x00\x00Z\xbf\x94`\x00\x00\x00\x00[\xaf\x85`\x00\x00\x00\x00\\\xa8\xb0\xe0\x00\x00\x00\x00]\x8fg`\x00\x00\x00\x00^\x88\x92\xe0\x00\x00\x00\x00_oI`\x00\x00\x00\x00`ht" + + "\xe0\x00\x00\x00\x00aO+`\x00\x00\x00\x00bHV\xe0\x00\x00\x00\x00c/\r`\x00\x00\x00\x00d(8\xe0\x00\x00\x00\x00e\x0e\xef`\x00\x00\x00\x00f\x11U`\x00\x00\x00\x00f\xf8\v\xe0\x00\x00\x00" + + "\x00g\xf17`\x00\x00\x00\x00h\xd7\xed\xe0\x00\x00\x00\x00i\xd1\x19`\x00\x00\x00\x00j\xb7\xcf\xe0\x00\x00\x00\x00k\xb0\xfb`\x00\x00\x00\x00l\x97\xb1\xe0\x00\x00\x00\x00m\x90\xdd`\x00\x00\x00\x00nw\x93" + + "\xe0\x00\x00\x00\x00op\xbf`\x00\x00\x00\x00p`\xb0`\x00\x00\x00\x00qY\xdb\xe0\x00\x00\x00\x00r@\x92`\x00\x00\x00\x00s9\xbd\xe0\x00\x00\x00\x00t t`\x00\x00\x00\x00u\x19\x9f\xe0\x00\x00\x00" + + "\x00v\x00V`\x00\x00\x00\x00v\xf9\x81\xe0\x00\x00\x00\x00w\xe08`\x00\x00\x00\x00x\xd9c\xe0\x00\x00\x00\x00y\xc0\x1a`\x00\x00\x00\x00z\xb9E\xe0\x00\x00\x00\x00{\xa96\xe0\x00\x00\x00\x00|\xa2b" + + "`\x00\x00\x00\x00}\x89\x18\xe0\x00\x00\x00\x00~\x82D`\x00\x00\x00\x00\u007fh\xfa\xe0\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x06\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x00\x00\xa3\xd8\x00\x00\x00\x00\xaf\xc8\x01\x04\x00\x00\xa1\xb8\x00\t\x00\x00\xa8\xc0\x01\x04\x00\x00\xb6\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04\x00\x00\xa8\xc0\x00\x04LMT\x00NZST\x00NZMT\x00NZD" + + "T\x00\x00\x00\x00\x00\x01\x01\x00\nNZST-12NZDT,M9.5.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x93\xbc>\a\xf0\x05\x00\x00" + + "\xf0\x05\x00\x00\x14\x00\x1c\x00Antarctica/MacquarieUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif" + + "2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\\\x00\x00\x00\a\x00\x00\x00\x12\x80\x00\x00\x00\x9b\xd5x\x80\x9c\xbc 𠇴`\xd7\fh\x00" + + "\xfb\u008d\x00\xfc\xb2~\x00\xfd\xc7Y\x00\xfev\xb0\x80\xff\xa7;\x00\x00V\x92\x80\x01\x87\x1d\x00\x02?\xaf\x00\x03p9\x80\x04\r\x1c\x00\x05P\x1b\x80\x05\xf68\x80\a/\xfd\x80\a\xd6\x1a\x80\t\x0f߀" + + "\t\xb5\xfc\x80\n\xef\xc1\x80\v\x9f\x19\x00\f\xd8\xde\x00\r~\xfb\x00\x0e\xb8\xc0\x00\x0f^\xdd\x00\x10\x98\xa2\x00\x11>\xbf\x00\x12x\x84\x00\x13\x1e\xa1\x00\x14Xf\x00\x14\xfe\x83\x00\x168H\x00\x17\x03O\x00" + + "\x18!d\x80\x18\xe31\x00\x1a\x01F\x80\x1a\xa7c\x80\x1b\xe1(\x80\x1c\x87E\x80\x1d\xc1\n\x80\x1eg'\x80\x1f\x97\xb2\x00 Y~\x80!\x80\u0380\"B\x9b\x00#i\xeb\x00$\"}\x00%I\xcd\x00" + + "&\x02_\x00')\xaf\x00'\xf4\xb6\x00(\xed\xe1\x80)Ԙ\x00*\xcdÀ+\xb4z\x00,\xad\xa5\x80-\x94\\\x00.\x8d\x87\x80/t>\x000mi\x801]Z\x802V\x86\x003=<\x80" + + "46h\x005\x1d\x1e\x806\x16J\x006\xfd\x00\x807\xf6,\x008\xdc\xe2\x809\xa7\xe9\x80:\xbcĀ;\xbf*\x80<\xa5\xe1\x00=\x9f\f\x80>\x85\xc3\x00?~\xee\x80@e\xa5\x00A^Ѐ" + + "BE\x87\x00C>\xb2\x80D.\xa3\x80E\x1e\x94\x80F\x05K\x00G\a\xb1\x00G\xf7\xa2\x00H\xe7\x93\x00Iׄ\x00J\xc7u\x00K\xb7f\x00\u007f\xff\xff\xff\x01\x02\x01\x03\x01\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\x06\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\x9a\xb0\x01\t\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xb0\x01\t\x00\x00\x8c\xa0\x00\x04\x00\x00\x9a\xb0" + + "\x00\x0e-00\x00AEST\x00AEDT\x00+11\x00\x00\x00\x00\x01\x01\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x00\x00" + + "\x00\x00\\\x00\x00\x00\a\x00\x00\x00\x12\xff\xff\xff\xff|\x05\x16\x00\xff\xff\xff\xff\x9b\xd5x\x80\xff\xff\xff\xff\x9c\xbc \xf0\xff\xff\xff\xff\xa0\x87\xb4`\xff\xff\xff\xff\xd7\fh\x00\xff\xff\xff\xff\xfb\u008d\x00\xff" + + "\xff\xff\xff\xfc\xb2~\x00\xff\xff\xff\xff\xfd\xc7Y\x00\xff\xff\xff\xff\xfev\xb0\x80\xff\xff\xff\xff\xff\xa7;\x00\x00\x00\x00\x00\x00V\x92\x80\x00\x00\x00\x00\x01\x87\x1d\x00\x00\x00\x00\x00\x02?\xaf\x00\x00\x00\x00\x00\x03" + + "p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00" + + "\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11" + + ">\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x03O\x00\x00\x00\x00\x00\x18!d\x80\x00" + + "\x00\x00\x00\x18\xe31\x00\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1eg'\x80\x00\x00\x00\x00\x1f" + + "\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00" + + "\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xed\xe1\x80\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*\xcdÀ\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xad\xa5\x80\x00\x00\x00\x00-" + + "\x94\\\x00\x00\x00\x00\x00.\x8d\x87\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000mi\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002V\x86\x00\x00\x00\x00\x003=<\x80\x00\x00\x00\x0046h\x00\x00" + + "\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\x16J\x00\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x007\xf6,\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;" + + "\xbf*\x80\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\x9f\f\x80\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?~\xee\x80\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A^Ѐ\x00\x00\x00\x00BE\x87\x00\x00" + + "\x00\x00\x00C>\xb2\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00E\x1e\x94\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G\a\xb1\x00\x00\x00\x00\x00G\xf7\xa2\x00\x00\x00\x00\x00H\xe7\x93\x00\x00\x00\x00\x00I" + + "ׄ\x00\x00\x00\x00\x00J\xc7u\x00\x00\x00\x00\x00K\xb7f\x00\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x01\x03\x01\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\x06\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\x9a\xb0\x01\t\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xb0\x01\t\x00\x00\x8c\xa0\x00\x04\x00\x00\x9a\xb0\x00\x0e-00\x00AEST\x00AEDT\x00+11\x00\x00" + + "\x00\x00\x01\x01\x01\x00\n<+11>-11\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP0>8\xb8\x85\t\x00\x00\x85\t\x00\x00\x15\x00\x1c\x00Antarctica/Sou" + + "th_PoleUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x9c\x00\x00\x00\a\x00\x00\x00\x13\x80\x00\x00\x00\xb0\xb4\xb2\xe8\xb1Q\x87X\xb2x\xe5h\xb3C\xe5`\xb4X\xc7h\xb5#\xc7`\xb68\xa9h\xb7\x03\xa9`\xb8\x18\x8bh\xb8" + + "\xec\xc5\xe0\xb9\xf8mh\xba̧\xe0\xbb\xd8Oh\xbc\xe3\xe8\u0f6e\xf6\xe8\xbe\xc3\xca࿎\xd8\xe8\xc0\xa3\xac\xe0\xc1n\xba\xe8\u0083\x8e\xe0\xc3N\x9c\xe8\xc4cp\xe0\xc5.~\xe8\xc6L\x8d`\xc7" + + "\x0e`\xe8\xc8,o`\xc8\xf7}h\xd2ښ@\t\x18\xfd\xe0\t\xac\xa5\xe0\n\xef\xa5`\v\x9e\xfc\xe0\f\xd8\xc1\xe0\r~\xde\xe0\x0e\xb8\xa3\xe0\x0f^\xc0\xe0\x10\x98\x85\xe0\x11>\xa2\xe0\x12xg\xe0\x13" + + "\x1e\x84\xe0\x14XI\xe0\x14\xfef\xe0\x168+\xe0\x16\xe7\x83`\x18!H`\x18\xc7e`\x1a\x01*`\x1a\xa7G`\x1b\xe1\f`\x1c\x87)`\x1d\xc0\xee`\x1eg\v`\x1f\xa0\xd0` F\xed`!" + + "\x80\xb2`\"0\t\xe0#i\xce\xe0$\x0f\xeb\xe0%.\x01`&\x02B\xe0'\r\xe3`'\xe2$\xe0(\xed\xc5`)\xc2\x06\xe0*ͧ`+\xab#`,\xad\x89`-\x8b\x05`.\x8dk`/" + + "j\xe7`0mM`1J\xc9`2Vi\xe03*\xab`46K\xe05\n\x8d`6\x16-\xe06\xf3\xa9\xe07\xf6\x0f\xe08Ӌ\xe09\xd5\xf1\xe0:\xb3m\xe0;\xbf\x0e`<\x93O\xe0=" + + "\x9e\xf0`>s1\xe0?~\xd2`@\\N`A^\xb4`B<0`C>\x96`D\x1c\x12`E\x1ex`E\xfb\xf4`F\xfeZ`G\xf7\x85\xe0H\xde<`I\xd7g\xe0J\xbe\x1e`K" + + "\xb7I\xe0L\x9e\x00`M\x97+\xe0N}\xe2`Ow\r\xe0Pf\xfe\xe0Q`*`RF\xe0\xe0S@\f`T&\xc2\xe0U\x1f\xee`V\x06\xa4\xe0V\xff\xd0`W\xe6\x86\xe0X߲`Y" + + "\xc6h\xe0Z\xbf\x94`[\xaf\x85`\\\xa8\xb0\xe0]\x8fg`^\x88\x92\xe0_oI``ht\xe0aO+`bHV\xe0c/\r`d(8\xe0e\x0e\xef`f\x11U`f\xf8\v\xe0g" + + "\xf17`h\xd7\xed\xe0i\xd1\x19`j\xb7\xcf\xe0k\xb0\xfb`l\x97\xb1\xe0m\x90\xdd`nw\x93\xe0op\xbf`p`\xb0`qY\xdb\xe0r@\x92`s9\xbd\xe0t t`u\x19\x9f\xe0v" + + "\x00V`v\xf9\x81\xe0w\xe08`x\xd9c\xe0y\xc0\x1a`z\xb9E\xe0{\xa96\xe0|\xa2b`}\x89\x18\xe0~\x82D`\u007fh\xfa\xe0\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x06\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x00\x00\xa3\xd8\x00\x00\x00\x00\xaf\xc8\x01\x04\x00\x00\xa1\xb8\x00\t\x00\x00\xa8\xc0\x01\x04\x00\x00\xb6\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04\x00\x00\xa8\xc0\x00" + + "\x04LMT\x00NZST\x00NZMT\x00NZDT\x00\x00\x00\x00\x00\x01\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x00\x00" + + "\x00\x00\x9c\x00\x00\x00\a\x00\x00\x00\x13\xff\xff\xff\xffA\xb7L\xa8\xff\xff\xff\xff\xb0\xb4\xb2\xe8\xff\xff\xff\xff\xb1Q\x87X\xff\xff\xff\xff\xb2x\xe5h\xff\xff\xff\xff\xb3C\xe5`\xff\xff\xff\xff\xb4X\xc7h\xff" + + "\xff\xff\xff\xb5#\xc7`\xff\xff\xff\xff\xb68\xa9h\xff\xff\xff\xff\xb7\x03\xa9`\xff\xff\xff\xff\xb8\x18\x8bh\xff\xff\xff\xff\xb8\xec\xc5\xe0\xff\xff\xff\xff\xb9\xf8mh\xff\xff\xff\xff\xba̧\xe0\xff\xff\xff\xff\xbb" + + "\xd8Oh\xff\xff\xff\xff\xbc\xe3\xe8\xe0\xff\xff\xff\xff\xbd\xae\xf6\xe8\xff\xff\xff\xff\xbe\xc3\xca\xe0\xff\xff\xff\xff\xbf\x8e\xd8\xe8\xff\xff\xff\xff\xc0\xa3\xac\xe0\xff\xff\xff\xff\xc1n\xba\xe8\xff\xff\xff\xff\u0083\x8e\xe0\xff" + + "\xff\xff\xff\xc3N\x9c\xe8\xff\xff\xff\xff\xc4cp\xe0\xff\xff\xff\xff\xc5.~\xe8\xff\xff\xff\xff\xc6L\x8d`\xff\xff\xff\xff\xc7\x0e`\xe8\xff\xff\xff\xff\xc8,o`\xff\xff\xff\xff\xc8\xf7}h\xff\xff\xff\xff\xd2" + + "ښ@\x00\x00\x00\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v\x9e\xfc\xe0\x00\x00\x00\x00\f\xd8\xc1\xe0\x00\x00\x00\x00\r~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00" + + "\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x16" + + "8+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\f`\x00\x00\x00\x00\x1c\x87)`\x00" + + "\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\"0\t\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$" + + "\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*ͧ`\x00" + + "\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002" + + "Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008Ӌ\xe0\x00" + + "\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@" + + "\\N`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x00" + + "\x00\x00\x00G\xf7\x85\xe0\x00\x00\x00\x00H\xde<`\x00\x00\x00\x00I\xd7g\xe0\x00\x00\x00\x00J\xbe\x1e`\x00\x00\x00\x00K\xb7I\xe0\x00\x00\x00\x00L\x9e\x00`\x00\x00\x00\x00M\x97+\xe0\x00\x00\x00\x00N" + + "}\xe2`\x00\x00\x00\x00Ow\r\xe0\x00\x00\x00\x00Pf\xfe\xe0\x00\x00\x00\x00Q`*`\x00\x00\x00\x00RF\xe0\xe0\x00\x00\x00\x00S@\f`\x00\x00\x00\x00T&\xc2\xe0\x00\x00\x00\x00U\x1f\xee`\x00" + + "\x00\x00\x00V\x06\xa4\xe0\x00\x00\x00\x00V\xff\xd0`\x00\x00\x00\x00W\xe6\x86\xe0\x00\x00\x00\x00X߲`\x00\x00\x00\x00Y\xc6h\xe0\x00\x00\x00\x00Z\xbf\x94`\x00\x00\x00\x00[\xaf\x85`\x00\x00\x00\x00\\" + + "\xa8\xb0\xe0\x00\x00\x00\x00]\x8fg`\x00\x00\x00\x00^\x88\x92\xe0\x00\x00\x00\x00_oI`\x00\x00\x00\x00`ht\xe0\x00\x00\x00\x00aO+`\x00\x00\x00\x00bHV\xe0\x00\x00\x00\x00c/\r`\x00" + + "\x00\x00\x00d(8\xe0\x00\x00\x00\x00e\x0e\xef`\x00\x00\x00\x00f\x11U`\x00\x00\x00\x00f\xf8\v\xe0\x00\x00\x00\x00g\xf17`\x00\x00\x00\x00h\xd7\xed\xe0\x00\x00\x00\x00i\xd1\x19`\x00\x00\x00\x00j" + + "\xb7\xcf\xe0\x00\x00\x00\x00k\xb0\xfb`\x00\x00\x00\x00l\x97\xb1\xe0\x00\x00\x00\x00m\x90\xdd`\x00\x00\x00\x00nw\x93\xe0\x00\x00\x00\x00op\xbf`\x00\x00\x00\x00p`\xb0`\x00\x00\x00\x00qY\xdb\xe0\x00" + + "\x00\x00\x00r@\x92`\x00\x00\x00\x00s9\xbd\xe0\x00\x00\x00\x00t t`\x00\x00\x00\x00u\x19\x9f\xe0\x00\x00\x00\x00v\x00V`\x00\x00\x00\x00v\xf9\x81\xe0\x00\x00\x00\x00w\xe08`\x00\x00\x00\x00x" + + "\xd9c\xe0\x00\x00\x00\x00y\xc0\x1a`\x00\x00\x00\x00z\xb9E\xe0\x00\x00\x00\x00{\xa96\xe0\x00\x00\x00\x00|\xa2b`\x00\x00\x00\x00}\x89\x18\xe0\x00\x00\x00\x00~\x82D`\x00\x00\x00\x00\u007fh\xfa\xe0\x02" + + "\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x06\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x00\x00\xa3\xd8\x00\x00\x00\x00\xaf\xc8\x01\x04\x00\x00\xa1\xb8\x00\t\x00\x00\xa8\xc0\x01\x04\x00" + + "\x00\xb6\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04\x00\x00\xa8\xc0\x00\x04LMT\x00NZST\x00NZMT\x00NZDT\x00\x00\x00\x00\x00\x01\x01\x00\nNZST-12NZDT,M9.5" + + ".0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xba\x9c\x04Z\x8a\x04\x00\x00\x8a\x04\x00\x00\x10\x00\x1c\x00Antarctica/TrollUT" + + "\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + + "\x00D\x00\x00\x00\x04\x00\x00\x00\fB\rG\x00BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L\xcc" + + "\xbf\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6" + + "\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfd" + + "r\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0" + + "\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\u007f\xff\xff\xff\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x00\x00\x00\x00\x00\x00\x00\x00\x1c " + + "\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x00\x00\x00\b-00\x00+02\x00+00\x00\x00\x01\x01\x00\x00\x01\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00" + + "\x00\x04\x00\x00\x00\x00\x00\x00\x00D\x00\x00\x00\x04\x00\x00\x00\f\x00\x00\x00\x00B\rG\x00\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00" + + "\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L\xcc" + + "\xbf\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00" + + "\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6" + + "\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00" + + "\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfd" + + "r\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00" + + "\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0" + + "\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00" + + "\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x00\x00\x00\x00\u007f\xff\xff\xff\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x00\x00\x00\x00\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x00\x00\x00\b-00\x00+0" + + "2\x00+00\x00\x00\x01\x01\x00\x00\x01\x01\x00\n<+00>0<+02>-2,M3.5.0/1,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F" + + "\x9cPYl '\xc7\x00\x00\x00\xc7\x00\x00\x00\x11\x00\x1c\x00Antarctica/MawsonUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14" + + "\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\f\xe2 2\x80J\xda\"@\u007f\xff\xff\xff\x01" + + "\x02\x02\x00\x00\x00\x00\x00\x00\x00\x00T`\x00\x04\x00\x00FP\x00\b-00\x00+06\x00+05\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xe2 2\x80\x00\x00\x00\x00J\xda\"@\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x02\x00\x00\x00\x00\x00\x00\x00\x00T`\x00\x04\x00\x00FP\x00" + + "\b-00\x00+06\x00+05\x00\n<+05>-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x8c\xa1\xe8G)\x01\x00\x00)\x01\x00\x00\x10\x00\x1c\x00Antarcti" + + "ca/CaseyUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04" + + "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x04\x00\x00\x00\f\xfe\x1èJ\xda\x06 K\x8f\xca\xf0N\xa9\x9c OC͐X\n;\x80Z\xa4\x0f\x10\u007f\xff\xff\xff\x01\x02\x01\x02\x03\x02\x01\x01" + + "\x00\x00\x00\x00\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x9a\xb0\x00\b\x00\x00p\x80\x00\x04-00\x00+08\x00+11\x00\x00\x00\x00\x01\x00\x00\x00\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\xfe\x1è\x00\x00\x00\x00J\xda\x06 \x00\x00\x00\x00K\x8f\xca\xf0\x00\x00\x00\x00N\xa9\x9c " + + "\x00\x00\x00\x00OC͐\x00\x00\x00\x00X\n;\x80\x00\x00\x00\x00Z\xa4\x0f\x10\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x01\x02\x03\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x9a\xb0\x00\b\x00\x00" + + "p\x80\x00\x04-00\x00+08\x00+11\x00\x00\x00\x00\x01\x00\x00\x00\x01\n<+08>-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a" + + "\x00\x1c\x00Arctic/UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa7\x99\x04[\xb4\b\x00\x00" + + "\xb4\b\x00\x00\x13\x00\x1c\x00Arctic/LongyearbyenUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x8d\x00\x00\x00\a\x00\x00\x00\r\x80\x00\x00\x00\x9b'\xe3\x00\x9b\xd4{`ȷM`\xcc\xe7K\x10\xcd" + + "\xa9\x17\x90\u03a2C\x10ϒ4\x10Ђ%\x10\xd1r\x16\x10\xd2b\a\x10\xeb\xaf \x90\xec\xa8L\x10\xed\x98=\x10\xee\x88.\x10\xefx\x1f\x10\xf0h\x10\x10\xf1X\x01\x10\xf2G\xf2\x10\xf37\xe3\x10\xf4" + + "'\xd4\x10\xf5\x17\xc5\x10\xf6\x10\xf0\x90\xf7/\x06\x10\xf7\xf0Ґ\x13MD\x10\x143\xfa\x90\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c" + + "\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG" + + "#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U" + + "\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c" + + "]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10q" + + "Q<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f" + + "\x8e\u007f\x90\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\n\x14\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x1c \x01\x04" + + "\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00" + + "\a\x00\x00\x00\x00\x00\x00\x00\x8d\x00\x00\x00\a\x00\x00\x00\r\xff\xff\xff\xffr\xee$l\xff\xff\xff\xff\x9b'\xe3\x00\xff\xff\xff\xff\x9b\xd4{`\xff\xff\xff\xffȷM`\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff" + + "\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2b\a\x10\xff\xff\xff\xff\xeb\xaf \x90\xff\xff\xff\xff\xec\xa8L" + + "\x10\xff\xff\xff\xff\xed\x98=\x10\xff\xff\xff\xff\xee\x88.\x10\xff\xff\xff\xff\xefx\x1f\x10\xff\xff\xff\xff\xf0h\x10\x10\xff\xff\xff\xff\xf1X\x01\x10\xff\xff\xff\xff\xf2G\xf2\x10\xff\xff\xff\xff\xf37\xe3\x10\xff\xff\xff" + + "\xff\xf4'\xd4\x10\xff\xff\xff\xff\xf5\x17\xc5\x10\xff\xff\xff\xff\xf6\x10\xf0\x90\xff\xff\xff\xff\xf7/\x06\x10\xff\xff\xff\xff\xf7\xf0Ґ\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb" + + "\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00" + + "\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c" + + "\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00" + + "\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c" + + "\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00" + + "\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n" + + "\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00" + + "\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y" + + "\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00" + + "\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7" + + "\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00" + + "\x00\u007f\x8e\u007f\x90\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\n\x14\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x1c " + + "\x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M10.5.0" + + "/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x1c\x00Asia/UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00" + + "\x00\x04\x14\x00\x00\x00PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP=\x13q\x1aO\x02\x00\x00O\x02\x00\x00\r\x00\x1c\x00Asia/DushanbeUT\t\x00\x03nӧ^n\xd3" + + "\xa7^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\b\x00\x00\x00" + + "\x10\xaa\x19\x83\x80\xb5\xa3\xef0\x15'}\xa0\x16\x18\xb2\x10\x17\b\xb1 \x17\xf9\xe5\x90\x18\xe9\xe4\xa0\x19\xdb\x19\x10\x1a\xcci\xa0\x1b\xbcv\xc0\x1c\xacg\xc0\x1d\x9cX\xc0\x1e\x8cI\xc0\x1f|:\xc0 l+" + + "\xc0!\\\x1c\xc0\"L\r\xc0#;\xfe\xc0$+\xef\xc0%\x1b\xe0\xc0&\v\xd1\xc0'\x04\xfd@'\xf4\xee@(ʏP\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x06\a\a\x00\x00@\x80\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\b\x00\x00T`\x00\f\x00\x00T`\x00\f\x00\x00bp\x01\b\x00\x00T`\x01\f\x00\x00FP\x00\x04LMT\x00+0" + + "5\x00+07\x00+06\x00\x00\x00\x00\x00\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\b\x00\x00" + + "\x00\x10\xff\xff\xff\xff\xaa\x19\x83\x80\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00\x00\x00\x00\x18\xe9\xe4\xa0\x00\x00" + + "\x00\x00\x19\xdb\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f|:\xc0\x00\x00\x00\x00 l" + + "+\xc0\x00\x00\x00\x00!\\\x1c\xc0\x00\x00\x00\x00\"L\r\xc0\x00\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\v\xd1\xc0\x00\x00\x00\x00'\x04\xfd@\x00\x00" + + "\x00\x00'\xf4\xee@\x00\x00\x00\x00(ʏP\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\a\x00\x00@\x80\x00\x00\x00\x00FP\x00\x04\x00" + + "\x00bp\x01\b\x00\x00T`\x00\f\x00\x00T`\x00\f\x00\x00bp\x01\b\x00\x00T`\x01\f\x00\x00FP\x00\x04LMT\x00+05\x00+07\x00+06\x00\x00\x00\x00\x00\x01\x01\x01\x01\n" + + "<+05>-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xad\xfeuz\xf3\x03\x00\x00\xf3\x03\x00\x00\r\x00\x1c\x00Asia/QostanayUT\t\x00\x03nӧ^" + + "nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x004\x00\x00\x00\v\x00" + + "\x00\x00\x10\xaa\x19\x88\\\xb5\xa3\xfd@\x15'\x8b\xb0\x16\x18\xc0 \x17\b\xb1 \x17\xf9\xf3\xa0\x18\xe9\xf2\xb0\x19\xdb' \x1a\xccw\xb0\x1b\xbc\x84\xd0\x1c\xacu\xd0\x1d\x9cf\xd0\x1e\x8cW\xd0\x1f|H\xd0 " + + "l9\xd0!\\*\xd0\"L\x1b\xd0#<\f\xd0$+\xfd\xd0%\x1b\xee\xd0&\v\xdf\xd0'\x05\vP'\xf4\xfcP(\xe4\xfb`)x\xa3`)\xd4\xdeP*\xc4\xcfP+\xb4\xc0P,\xa4\xb1P-" + + "\x94\xa2P.\x84\x93P/t\x84P0duP1]\xa0\xd02r{\xd03=\x82\xd04R]\xd05\x1dd\xd062?\xd06\xfdF\xd08\x1b\\P8\xdd(\xd09\xfb>P:\xbd\n\xd0;" + + "\xdb P<\xa6'P=\xbb\x02P>\x86\tP?\x9a\xe4P@e\xebPA\x84\x00\xd0\u007f\xff\xff\xff\x01\x02\x03\x04\x03\x02\x03\x02\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\b\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\t\t\x00\x00;\xa4\x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00T`\x00\f\x00\x00FP\x00\b\x00" + + "\x00T`\x01\f\x00\x00FP\x01\b\x00\x008@\x00\x04\x00\x00T`\x00\f\x00\x00T`\x01\fLMT\x00+04\x00+05\x00+06\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01TZif" + + "2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x004\x00\x00\x00\v\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x88\\\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00" + + "\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0" + + "\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00" + + "#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`" + + "\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84P\x00\x00\x00\x00" + + "0duP\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\x82\xd0\x00\x00\x00\x004R]\xd0\x00\x00\x00\x005\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00\x006\xfdF\xd0" + + "\x00\x00\x00\x008\x1b\\P\x00\x00\x00\x008\xdd(\xd0\x00\x00\x00\x009\xfb>P\x00\x00\x00\x00:\xbd\n\xd0\x00\x00\x00\x00;\xdb P\x00\x00\x00\x00<\xa6'P\x00\x00\x00\x00=\xbb\x02P\x00\x00\x00\x00" + + ">\x86\tP\x00\x00\x00\x00?\x9a\xe4P\x00\x00\x00\x00@e\xebP\x00\x00\x00\x00A\x84\x00\xd0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x04\x03\x02\x03\x02\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\b" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\t\t\x00\x00;\xa4\x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00T`\x00\f\x00\x00" + + "FP\x00\b\x00\x00T`\x01\f\x00\x00FP\x01\b\x00\x008@\x00\x04\x00\x00T`\x00\f\x00\x00T`\x01\fLMT\x00+04\x00+05\x00+06\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01" + + "\x01\n<+06>-6\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x88括\x1d\x01\x00\x00\x1d\x01\x00\x00\r\x00\x1c\x00Asia/CalcuttaUT\t\x00\x03n\xd3" + + "\xa7^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00" + + "\x04\x00\x00\x00\x12\x80\x00\x00\x00\x87\x9d\xbc\xba\xcaی(\xcc\x05q\x18̕2\xa8\xd2t\x12\x98\x01\x02\x03\x02\x03\x02\x00\x00R\xd8\x00\x00\x00\x00KF\x00\x04\x00\x00MX\x00\b\x00\x00[h\x01\fL" + + "MT\x00MMT\x00IST\x00+0630\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x05\x00\x00\x00" + + "\x16\xff\xff\xff\xff&\xba\x18(\xff\xff\xff\xffC\xe7\xeb0\xff\xff\xff\xff\x87\x9d\xbc\xba\xff\xff\xff\xff\xcaی(\xff\xff\xff\xff\xcc\x05q\x18\xff\xff\xff\xff̕2\xa8\xff\xff\xff\xff\xd2t\x12\x98\x01\x02\x03" + + "\x04\x03\x04\x03\x00\x00R\xd8\x00\x00\x00\x00R\xd0\x00\x04\x00\x00KF\x00\b\x00\x00MX\x00\f\x00\x00[h\x01\x10LMT\x00HMT\x00MMT\x00IST\x00+0630\x00\nIST" + + "-5:30\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPw:\xb4ե\x00\x00\x00\xa5\x00\x00\x00\v\x00\x1c\x00Asia/UrumqiUT\t\x00\x03nӧ^nӧ^" + + "ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xb0" + + "\xfe\xbad\u007f\xff\xff\xff\x01\x01\x00\x00R\x1c\x00\x00\x00\x00T`\x00\x04LMT\x00+06\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xb0\xfe\xbad\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x00R\x1c\x00\x00\x00\x00T`\x00\x04LMT\x00+06\x00\n<+06>-6\n" + + "PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xd2\xc25G{\x01\x00\x00{\x01\x00\x00\f\x00\x1c\x00Asia/KarachiUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01" + + "\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x06\x00\x00\x00\x1d\x89~\xfc\xa4̕" + + "2\xa8\xd2t\x12\x98ݨ\xe0\xa8\x02O\xab0<\xafE\xb0=\x9f(\xa0HA\xa00I\vG\xa0I\xe4\xdd0J\xec{ \x01\x02\x01\x03\x05\x04\x05\x04\x05\x04\x05\x00\x00>\xdc\x00\x00\x00\x00MX\x00" + + "\x04\x00\x00[h\x01\n\x00\x00FP\x00\x10\x00\x00T`\x01\x14\x00\x00FP\x00\x19LMT\x00+0530\x00+0630\x00+05\x00PKST\x00PKT\x00TZif2\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x06\x00\x00\x00\x1d\xff\xff\xff\xff\x89~\xfc\xa4\xff\xff\xff\xff̕2\xa8\xff\xff\xff\xff\xd2t" + + "\x12\x98\xff\xff\xff\xffݨ\xe0\xa8\x00\x00\x00\x00\x02O\xab0\x00\x00\x00\x00<\xafE\xb0\x00\x00\x00\x00=\x9f(\xa0\x00\x00\x00\x00HA\xa00\x00\x00\x00\x00I\vG\xa0\x00\x00\x00\x00I\xe4\xdd0\x00\x00" + + "\x00\x00J\xec{ \x01\x02\x01\x03\x05\x04\x05\x04\x05\x04\x05\x00\x00>\xdc\x00\x00\x00\x00MX\x00\x04\x00\x00[h\x01\n\x00\x00FP\x00\x10\x00\x00T`\x01\x14\x00\x00FP\x00\x19LMT\x00+05" + + "30\x00+0630\x00+05\x00PKST\x00PKT\x00\nPKT-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x9c\xd9\xefd\xf7\x04\x00\x00\xf7\x04\x00\x00\r\x00\x1c\x00A" + + "sia/KhandygaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00D\x00\x00\x00\r\x00\x00\x00\x14\xa1\xdb\xe4뵣\xc5\x00\x15'Sp\x16\x18\x87\xe0\x17\b\x86\xf0\x17\xf9\xbb`\x18\xe9\xbap\x19\xda\xee\xe0\x1a\xcc?p" + + "\x1b\xbcL\x90\x1c\xac=\x90\x1d\x9c.\x90\x1e\x8c\x1f\x90\x1f|\x10\x90 l\x01\x90![\xf2\x90\"K\xe3\x90#;Ԑ$+Ő%\x1b\xb6\x90&\v\xa7\x90'\x04\xd3\x10'\xf4\xc4\x10(\xe4\xc3 " + + ")xk )Ԧ\x10*ė\x10+\xb4\x88\x10,\xa4y\x10-\x94j\x10.\x84[\x10/tL\x100d=\x101]h\x902rC\x903=J\x904R%\x905\x1d,\x9062\a\x90" + + "6\xfd\x0e\x908\x1b$\x108\xdc\xf0\x909\xfb\x06\x10:\xbcҐ;\xda\xe8\x10<\xa5\xef\x10=\xba\xca\x10>\x85\xd1\x10?\x9a\xac\x10?\xf2\xe4p@e\xa5\x00A\x83\xba\x80BE\x87\x00Cc\x9c\x80" + + "D%i\x00EC~\x80F\x05K\x00G#`\x80G\xeeg\x80I\x03B\x80I\xceI\x80J\xe3$\x80K\xae+\x80L\xccA\x00M\x8e\r\x80Nn\x02PTK\xc9\x00\u007f\xff\xff\xff\x01\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\n\b\t\b\t\b\t\b\t\b\t\b\t\b\t" + + "\v\t\x04\x04\x00\x00\u007f\x15\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\f\x00\x00~\x90\x00\f\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x01\f\x00\x00p\x80\x00\x04\x00\x00\x9a\xb0\x01\x10\x00\x00" + + "\x8c\xa0\x00\b\x00\x00\x8c\xa0\x00\b\x00\x00\x9a\xb0\x00\x10\x00\x00~\x90\x00\fLMT\x00+08\x00+10\x00+09\x00+11\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x00\x01\x01TZif2" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00D\x00\x00\x00\r\x00\x00\x00\x14\xff\xff\xff\xff\xa1\xdb\xe4\xeb\xff\xff\xff\xff\xb5\xa3\xc5\x00\x00\x00\x00\x00\x15" + + "'Sp\x00\x00\x00\x00\x16\x18\x87\xe0\x00\x00\x00\x00\x17\b\x86\xf0\x00\x00\x00\x00\x17\xf9\xbb`\x00\x00\x00\x00\x18\xe9\xbap\x00\x00\x00\x00\x19\xda\xee\xe0\x00\x00\x00\x00\x1a\xcc?p\x00\x00\x00\x00\x1b\xbcL\x90\x00" + + "\x00\x00\x00\x1c\xac=\x90\x00\x00\x00\x00\x1d\x9c.\x90\x00\x00\x00\x00\x1e\x8c\x1f\x90\x00\x00\x00\x00\x1f|\x10\x90\x00\x00\x00\x00 l\x01\x90\x00\x00\x00\x00![\xf2\x90\x00\x00\x00\x00\"K\xe3\x90\x00\x00\x00\x00#" + + ";Ԑ\x00\x00\x00\x00$+Ő\x00\x00\x00\x00%\x1b\xb6\x90\x00\x00\x00\x00&\v\xa7\x90\x00\x00\x00\x00'\x04\xd3\x10\x00\x00\x00\x00'\xf4\xc4\x10\x00\x00\x00\x00(\xe4\xc3 \x00\x00\x00\x00)xk \x00" + + "\x00\x00\x00)Ԧ\x10\x00\x00\x00\x00*ė\x10\x00\x00\x00\x00+\xb4\x88\x10\x00\x00\x00\x00,\xa4y\x10\x00\x00\x00\x00-\x94j\x10\x00\x00\x00\x00.\x84[\x10\x00\x00\x00\x00/tL\x10\x00\x00\x00\x000" + + "d=\x10\x00\x00\x00\x001]h\x90\x00\x00\x00\x002rC\x90\x00\x00\x00\x003=J\x90\x00\x00\x00\x004R%\x90\x00\x00\x00\x005\x1d,\x90\x00\x00\x00\x0062\a\x90\x00\x00\x00\x006\xfd\x0e\x90\x00" + + "\x00\x00\x008\x1b$\x10\x00\x00\x00\x008\xdc\xf0\x90\x00\x00\x00\x009\xfb\x06\x10\x00\x00\x00\x00:\xbcҐ\x00\x00\x00\x00;\xda\xe8\x10\x00\x00\x00\x00<\xa5\xef\x10\x00\x00\x00\x00=\xba\xca\x10\x00\x00\x00\x00>" + + "\x85\xd1\x10\x00\x00\x00\x00?\x9a\xac\x10\x00\x00\x00\x00?\xf2\xe4p\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D%i\x00\x00" + + "\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xeeg\x80\x00\x00\x00\x00I\x03B\x80\x00\x00\x00\x00I\xceI\x80\x00\x00\x00\x00J\xe3$\x80\x00\x00\x00\x00K" + + "\xae+\x80\x00\x00\x00\x00L\xccA\x00\x00\x00\x00\x00M\x8e\r\x80\x00\x00\x00\x00Nn\x02P\x00\x00\x00\x00TK\xc9\x00\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\n\b\t\b\t\b\t\b\t\b\t\b\t\b\t\v\t\x04\x04\x00\x00\u007f\x15\x00\x00\x00\x00p" + + "\x80\x00\x04\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\f\x00\x00~\x90\x00\f\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x01\f\x00\x00p\x80\x00\x04\x00\x00\x9a\xb0\x01\x10\x00\x00\x8c\xa0\x00\b\x00\x00\x8c\xa0\x00\b\x00\x00\x9a" + + "\xb0\x00\x10\x00\x00~\x90\x00\fLMT\x00+08\x00+10\x00+09\x00+11\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x00\x01\x01\n<+09>-9\nPK\x03\x04\n\x00\x00\x00\x00" + + "\x00\xf5F\x9cP\xbc?y\x93\xcb\x00\x00\x00\xcb\x00\x00\x00\v\x00\x1c\x00Asia/ThimbuUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00" + + "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x0e\xd5\xe6\x15t!aM\xa8\u007f\xff\xff\xff\x01\x02\x02\x00" + + "\x00T\f\x00\x00\x00\x00MX\x00\x04\x00\x00T`\x00\nLMT\x00+0530\x00+06\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xff\xd5\xe6\x15t\x00\x00\x00\x00!aM\xa8\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x02\x00\x00T\f\x00\x00\x00\x00MX\x00\x04\x00\x00T`\x00\n" + + "LMT\x00+0530\x00+06\x00\n<+06>-6\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xbc?y\x93\xcb\x00\x00\x00\xcb\x00\x00\x00\f\x00\x1c\x00Asia/Th" + + "imphuUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x0e\xd5\xe6\x15t!aM\xa8\u007f\xff\xff\xff\x01\x02\x02\x00\x00T\f\x00\x00\x00\x00MX\x00\x04\x00\x00T`\x00\nLMT\x00+0530\x00" + + "+06\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xff\xd5\xe6\x15t\x00\x00\x00\x00" + + "!aM\xa8\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x02\x00\x00T\f\x00\x00\x00\x00MX\x00\x04\x00\x00T`\x00\nLMT\x00+0530\x00+06\x00\n<+06>-6\nPK\x03\x04" + + "\n\x00\x00\x00\x00\x00\xf5F\x9cP\x9cAu*\xb8\x04\x00\x00\xb8\x04\x00\x00\x10\x00\x1c\x00Asia/VladivostokUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01" + + "\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\v\x00\x00\x00\x10\xa7YG]\xb5\xa3" + + "\xb6\xf0\x15'E`\x16\x18y\xd0\x17\bx\xe0\x17\xf9\xadP\x18\xe9\xac`\x19\xda\xe0\xd0\x1a\xcc1`\x1b\xbc>\x80\x1c\xac/\x80\x1d\x9c \x80\x1e\x8c\x11\x80\x1f|\x02\x80 k\xf3\x80![\xe4\x80\"K" + + "Հ#;ƀ$+\xb7\x80%\x1b\xa8\x80&\v\x99\x80'\x04\xc5\x00'\xf4\xb6\x00(\xe4\xb5\x10)x]\x10)Ԙ\x00*ĉ\x00+\xb4z\x00,\xa4k\x00-\x94\\\x00.\x84M\x00/t" + + ">\x000d/\x001]Z\x802r5\x803=<\x804R\x17\x805\x1d\x1e\x8061\xf9\x806\xfd\x00\x808\x1b\x16\x008\xdc\xe2\x809\xfa\xf8\x00:\xbcĀ;\xda\xda\x00<\xa5\xe1\x00=\xba" + + "\xbc\x00>\x85\xc3\x00?\x9a\x9e\x00@e\xa5\x00A\x83\xba\x80BE\x87\x00Cc\x9c\x80D%i\x00EC~\x80F\x05K\x00G#`\x80G\xeeg\x80I\x03B\x80I\xceI\x80J\xe3$\x80K\xae" + + "+\x80L\xccA\x00M\x8e\r\x80TK\xba\xf0\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\b\x04\x04\x00\x00{\xa3\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x9a\xb0\x01\b\x00\x00\x8c\xa0\x00\f\x00\x00\x8c\xa0\x00\f\x00\x00\x9a\xb0\x01\b" + + "\x00\x00\x8c\xa0\x01\f\x00\x00~\x90\x00\x04\x00\x00\x9a\xb0\x00\b\x00\x00\x9a\xb0\x01\b\x00\x00\x8c\xa0\x00\fLMT\x00+09\x00+11\x00+10\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01TZi" + + "f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\v\x00\x00\x00\x10\xff\xff\xff\xff\xa7YG]\xff\xff\xff\xff\xb5\xa3\xb6\xf0\x00\x00\x00" + + "\x00\x15'E`\x00\x00\x00\x00\x16\x18y\xd0\x00\x00\x00\x00\x17\bx\xe0\x00\x00\x00\x00\x17\xf9\xadP\x00\x00\x00\x00\x18\xe9\xac`\x00\x00\x00\x00\x19\xda\xe0\xd0\x00\x00\x00\x00\x1a\xcc1`\x00\x00\x00\x00\x1b\xbc>" + + "\x80\x00\x00\x00\x00\x1c\xac/\x80\x00\x00\x00\x00\x1d\x9c \x80\x00\x00\x00\x00\x1e\x8c\x11\x80\x00\x00\x00\x00\x1f|\x02\x80\x00\x00\x00\x00 k\xf3\x80\x00\x00\x00\x00![\xe4\x80\x00\x00\x00\x00\"KՀ\x00\x00\x00" + + "\x00#;ƀ\x00\x00\x00\x00$+\xb7\x80\x00\x00\x00\x00%\x1b\xa8\x80\x00\x00\x00\x00&\v\x99\x80\x00\x00\x00\x00'\x04\xc5\x00\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xe4\xb5\x10\x00\x00\x00\x00)x]" + + "\x10\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*ĉ\x00\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xa4k\x00\x00\x00\x00\x00-\x94\\\x00\x00\x00\x00\x00.\x84M\x00\x00\x00\x00\x00/t>\x00\x00\x00\x00" + + "\x000d/\x00\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00" + + "\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xfa\xf8\x00\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00" + + "\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D%i\x00\x00\x00\x00\x00EC~" + + "\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xeeg\x80\x00\x00\x00\x00I\x03B\x80\x00\x00\x00\x00I\xceI\x80\x00\x00\x00\x00J\xe3$\x80\x00\x00\x00\x00K\xae+\x80\x00\x00\x00" + + "\x00L\xccA\x00\x00\x00\x00\x00M\x8e\r\x80\x00\x00\x00\x00TK\xba\xf0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\b\x04\x04\x00\x00{\xa3\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x9a\xb0\x01\b\x00\x00\x8c\xa0\x00\f\x00" + + "\x00\x8c\xa0\x00\f\x00\x00\x9a\xb0\x01\b\x00\x00\x8c\xa0\x01\f\x00\x00~\x90\x00\x04\x00\x00\x9a\xb0\x00\b\x00\x00\x9a\xb0\x01\b\x00\x00\x8c\xa0\x00\fLMT\x00+09\x00+11\x00+10\x00\x00\x00\x00" + + "\x00\x01\x01\x01\x01\x01\x01\x01\n<+10>-10\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x90\xc4\xe3*\xc7\x00\x00\x00\xc7\x00\x00\x00\x0e\x00\x1c\x00Asia/Vientia" + + "neUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\f\x80\x00\x00\x00\xa2jg\xc4\u007f\xff\xff\xff\x01\x02\x02\x00\x00^<\x00\x00\x00\x00^<\x00\x04\x00\x00bp\x00\bLMT\x00BMT\x00+07\x00T" + + "Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffV\xb6\x85\xc4\xff\xff\xff\xff\xa2jg\xc4\x00" + + "\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x02\x00\x00^<\x00\x00\x00\x00^<\x00\x04\x00\x00bp\x00\bLMT\x00BMT\x00+07\x00\n<+07>-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5" + + "F\x9cPy\x84\xe1i1\x02\x00\x001\x02\x00\x00\r\x00\x1c\x00Asia/ShanghaiUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00" + + "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x03\x00\x00\x00\f\x80\x00\x00\x00\xa0\x97\xa2\x80\xa1y\x04\xf0\xc8Y^\x80" + + "\xc9\t\xf9p\xc9ӽ\x00\xcb\x05\x8a\xf0\xcb|@\x00\xd2;>\xf0Ӌ{\x80\xd4B\xad\xf0\xd5E\"\x00\xd6L\xbf\xf0\xd7<\xbf\x00\xd8\x06fp\xd9\x1d\xf2\x80\xd9A|\xf0\x1e\xbaR \x1fi\x9b\x90" + + " ~\x84\xa0!I}\x90\"g\xa1 #)_\x90$G\x83 %\x12|\x10&'e &\xf2^\x10(\aG (\xd2@\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\bLMT\x00CDT\x00CST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff~6C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff\xff\xa1y\x04\xf0\xff\xff\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9" + + "\t\xf9p\xff\xff\xff\xff\xc9ӽ\x00\xff\xff\xff\xff\xcb\x05\x8a\xf0\xff\xff\xff\xff\xcb|@\x00\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xffӋ{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff" + + "\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00\x00\x1e\xbaR \x00\x00\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 " + + "~\x84\xa0\x00\x00\x00\x00!I}\x90\x00\x00\x00\x00\"g\xa1 \x00\x00\x00\x00#)_\x90\x00\x00\x00\x00$G\x83 \x00\x00\x00\x00%\x12|\x10\x00\x00\x00\x00&'e \x00\x00\x00\x00&\xf2^\x10\x00" + + "\x00\x00\x00(\aG \x00\x00\x00\x00(\xd2@\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80" + + "\x00\bLMT\x00CDT\x00CST\x00\nCST-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xbd*B/{\x03\x00\x00{\x03\x00\x00\x0f\x00\x1c\x00Asia/Ulan" + + "_BatorUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\x04\x00\x00\x00\x10\x86\xd3\xeeL\x0f\vܐ\x18\xe9Ȁ\x19\xda\xfc\xf0\x1a\xccM\x80\x1b\xbc0p\x1c\xac/\x80\x1d\x9c\x12p\x1e\x8c\x11\x80\x1f{\xf4p k" + + "\xf3\x80![\xd6p\"KՀ#;\xb8p$+\xb7\x80%\x1b\x9ap&\v\x99\x80'\x04\xb6\xf0'\xf4\xb6\x00(\xe4\x98\xf0)Ԙ\x00*\xc4z\xf0+\xb4z\x00,\xa4\\\xf0-\x94\\\x00.\x84" + + ">\xf0/t>\x000d \xf01]Z\x802M=p3=<\x804-\x1fp5\x1d\x1e\x806\r\x01p:鳠;\xb4\xac\x90<\xa4\xab\xa0=\x94\x8e\x90>\x84\x8d\xa0?tp\x90@d" + + "o\xa0ATR\x90BDQ\xa0C44\x90D$3\xa0E\x1dQ\x10U\x15\x9a\xa0V\x05apV\xf5|\xa0W\xe5Cp\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x03\x00\x00d4\x00\x00\x00\x00bp\x00\x04\x00\x00~\x90\x01\b\x00\x00p\x80\x00\fLMT" + + "\x00+07\x00+09\x00+08\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff" + + "\xff\x86\xd3\xeeL\x00\x00\x00\x00\x0f\vܐ\x00\x00\x00\x00\x18\xe9Ȁ\x00\x00\x00\x00\x19\xda\xfc\xf0\x00\x00\x00\x00\x1a\xccM\x80\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac/\x80\x00\x00\x00\x00\x1d\x9c\x12" + + "p\x00\x00\x00\x00\x1e\x8c\x11\x80\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xf3\x80\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\"KՀ\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xb7\x80\x00\x00\x00" + + "\x00%\x1b\x9ap\x00\x00\x00\x00&\v\x99\x80\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xe4\x98\xf0\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4z" + + "\x00\x00\x00\x00\x00,\xa4\\\xf0\x00\x00\x00\x00-\x94\\\x00\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002M=p\x00\x00\x00" + + "\x003=<\x80\x00\x00\x00\x004-\x1fp\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\r\x01p\x00\x00\x00\x00:鳠\x00\x00\x00\x00;\xb4\xac\x90\x00\x00\x00\x00<\xa4\xab\xa0\x00\x00\x00\x00=\x94\x8e" + + "\x90\x00\x00\x00\x00>\x84\x8d\xa0\x00\x00\x00\x00?tp\x90\x00\x00\x00\x00@do\xa0\x00\x00\x00\x00ATR\x90\x00\x00\x00\x00BDQ\xa0\x00\x00\x00\x00C44\x90\x00\x00\x00\x00D$3\xa0\x00\x00\x00" + + "\x00E\x1dQ\x10\x00\x00\x00\x00U\x15\x9a\xa0\x00\x00\x00\x00V\x05ap\x00\x00\x00\x00V\xf5|\xa0\x00\x00\x00\x00W\xe5Cp\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x03\x00\x00d4\x00\x00\x00\x00bp\x00\x04\x00\x00~\x90\x01\b\x00\x00p\x80\x00\f" + + "LMT\x00+07\x00+09\x00+08\x00\n<+08>-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPs\x92<\x8f\xa5\x00\x00\x00\xa5\x00\x00\x00\t\x00\x1c\x00Asia/" + + "AdenUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xd5\x1b6\xb4\u007f\xff\xff\xff\x01\x01\x00\x00+\xcc\x00\x00\x00\x00*0\x00\x04LMT\x00+03\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xd5\x1b6\xb4\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x00+\xcc\x00\x00\x00\x00*0\x00\x04" + + "LMT\x00+03\x00\n<+03>-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x8e\"\x05\x94\xa5\x00\x00\x00\xa5\x00\x00\x00\v\x00\x1c\x00Asia/MuscatUT" + + "\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xa1\xf2\x99\xa8\u007f\xff\xff\xff\x01\x01\x00\x003\xd8\x00\x00\x00\x008@\x00\x04LMT\x00+04\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xa1\xf2\x99\xa8\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x003\xd8\x00\x00\x00\x008@\x00\x04LMT\x00+0" + + "4\x00\n<+04>-4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xd7\x1e>W\xf6\b\x00\x00\xf6\b\x00\x00\r\x00\x1c\x00Asia/DamascusUT\t\x00\x03n" + + "ӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x97\x00\x00" + + "\x00\x03\x00\x00\x00\r\xa1\xf2\xabx\xa2\x81/\x80\xa3^\x9dp\xa4a\x11\x80\xa5>\u007fp\xa6@\xf3\x80\xa7\x1eap\xa8 Հ\xa9\a}\xf0\xf1\x8fR\x00\xf2[\x9cp\xf3s(\x80\xf4;~p\xf5U" + + "\xad\x80\xf6\x1fT\xf0\xf76\xe1\x00\xf7\xff6\xf0\xf9\x0e\xda\x00\xf9\xe1\xbb\xf0\xfa\xf9H\x00\xfb\xc2\xefp\xfc\xdb\xcd\x00\xfd\xa5tp\xfe\xbd\x00\x80\xff\x86\xa7\xf0\x00\x9e4\x00\x01g\xdbp\x02\u007fg\x80\x03I" + + "\x0e\xf0\x04a\xec\x80\x05+\x93\xf0\x06C \x00\a\f\xc7p\b$S\x80\b\xed\xfa\xf0\n\x05\x87\x00\n\xcf.p\v\xe8\f\x00\f\xb1\xb3p\r\xc9?\x80\x0ekY\xf0\x0f\xaas\x00\x10L\x8dp\x18\xf4" + + "\xc5\x00\x19\xdbmp\x1a\xd7J\x00\x1b\xbd\xf2p\x1eU#\x00\x1f\x8a\xe5p Gz\x00!\x89\x19\xf0\"\xe2`41hP5\x1e\xc4`6\x12\x9b\xd07\x02" + + "\x9a\xe07\xf3\xcfP8\xe5\x1f\xe09\xd6TP:\xc6S`;\xb7\x87\xd0<\xa7\x86\xe0=\x98\xbbP>\x88\xba`?y\xee\xd0@k?`A\\s\xd0BLr\xe0C=\xa7PD-\xa6`E\x12" + + "\xfdPF\f6\xe0G*>PG\xf5S`I\vq\xd0I\xcb\xfa\xe0J\xea\x02PK\xb5\x17`L\xc9\xe4PM\x94\xf9`N\xa9\xc6POt\xdb`P\x89\xa8PQT\xbd`Ri\x8aPS4" + + "\x9f`TR\xa6\xd0U\x14\x81`V2\x88\xd0V\xf4c`X\x12j\xd0X\xdd\u007f\xe0Y\xf2L\xd0Z\xbda\xe0[\xd2.\xd0\\\x9dC\xe0]\xb2\x10\xd0^}%\xe0_\x9b-P`]\a\xe0a{" + + "\x0fPb<\xe9\xe0cZ\xf1Pd&\x06`e:\xd3Pf\x05\xe8`g\x1a\xb5Pg\xe5\xca`i\x03\xd1\xd0iŬ`j\xe3\xb3\xd0k\xa5\x8e`lÕ\xd0m\x8e\xaa\xe0n\xa3w\xd0on" + + "\x8c\xe0p\x83Y\xd0qNn\xe0rc;\xd0s.P\xe0tLXPu\x0e2\xe0v,:Pv\xee\x14\xe0x\f\x1cPx\xd71`y\xeb\xfePz\xb7\x13`{\xcb\xe0P|\x96\xf5`}\xb4" + + "\xfc\xd0~v\xd7`\u007f\x94\xde\xd0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\"\b\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\tL" + + "MT\x00EEST\x00EET\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x97\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff" + + "\xa1\xf2\xabx\xff\xff\xff\xff\xa2\x81/\x80\xff\xff\xff\xff\xa3^\x9dp\xff\xff\xff\xff\xa4a\x11\x80\xff\xff\xff\xff\xa5>\u007fp\xff\xff\xff\xff\xa6@\xf3\x80\xff\xff\xff\xff\xa7\x1eap\xff\xff\xff\xff\xa8 Հ" + + "\xff\xff\xff\xff\xa9\a}\xf0\xff\xff\xff\xff\xf1\x8fR\x00\xff\xff\xff\xff\xf2[\x9cp\xff\xff\xff\xff\xf3s(\x80\xff\xff\xff\xff\xf4;~p\xff\xff\xff\xff\xf5U\xad\x80\xff\xff\xff\xff\xf6\x1fT\xf0\xff\xff\xff\xff" + + "\xf76\xe1\x00\xff\xff\xff\xff\xf7\xff6\xf0\xff\xff\xff\xff\xf9\x0e\xda\x00\xff\xff\xff\xff\xf9\xe1\xbb\xf0\xff\xff\xff\xff\xfa\xf9H\x00\xff\xff\xff\xff\xfb\xc2\xefp\xff\xff\xff\xff\xfc\xdb\xcd\x00\xff\xff\xff\xff\xfd\xa5tp" + + "\xff\xff\xff\xff\xfe\xbd\x00\x80\xff\xff\xff\xff\xff\x86\xa7\xf0\x00\x00\x00\x00\x00\x9e4\x00\x00\x00\x00\x00\x01g\xdbp\x00\x00\x00\x00\x02\u007fg\x80\x00\x00\x00\x00\x03I\x0e\xf0\x00\x00\x00\x00\x04a\xec\x80\x00\x00\x00\x00" + + "\x05+\x93\xf0\x00\x00\x00\x00\x06C \x00\x00\x00\x00\x00\a\f\xc7p\x00\x00\x00\x00\b$S\x80\x00\x00\x00\x00\b\xed\xfa\xf0\x00\x00\x00\x00\n\x05\x87\x00\x00\x00\x00\x00\n\xcf.p\x00\x00\x00\x00\v\xe8\f\x00" + + "\x00\x00\x00\x00\f\xb1\xb3p\x00\x00\x00\x00\r\xc9?\x80\x00\x00\x00\x00\x0ekY\xf0\x00\x00\x00\x00\x0f\xaas\x00\x00\x00\x00\x00\x10L\x8dp\x00\x00\x00\x00\x18\xf4\xc5\x00\x00\x00\x00\x00\x19\xdbmp\x00\x00\x00\x00" + + "\x1a\xd7J\x00\x00\x00\x00\x00\x1b\xbd\xf2p\x00\x00\x00\x00\x1eU#\x00\x00\x00\x00\x00\x1f\x8a\xe5p\x00\x00\x00\x00 Gz\x00\x00\x00\x00\x00!\x89\x19\xf0\x00\x00\x00\x00\"\xe2`\x00\x00\x00\x0041hP\x00\x00\x00\x005\x1e\xc4`\x00\x00\x00\x006\x12\x9b\xd0\x00\x00\x00\x007\x02\x9a\xe0\x00\x00\x00\x007\xf3\xcfP\x00\x00\x00\x00" + + "8\xe5\x1f\xe0\x00\x00\x00\x009\xd6TP\x00\x00\x00\x00:\xc6S`\x00\x00\x00\x00;\xb7\x87\xd0\x00\x00\x00\x00<\xa7\x86\xe0\x00\x00\x00\x00=\x98\xbbP\x00\x00\x00\x00>\x88\xba`\x00\x00\x00\x00?y\xee\xd0" + + "\x00\x00\x00\x00@k?`\x00\x00\x00\x00A\\s\xd0\x00\x00\x00\x00BLr\xe0\x00\x00\x00\x00C=\xa7P\x00\x00\x00\x00D-\xa6`\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00F\f6\xe0\x00\x00\x00\x00" + + "G*>P\x00\x00\x00\x00G\xf5S`\x00\x00\x00\x00I\vq\xd0\x00\x00\x00\x00I\xcb\xfa\xe0\x00\x00\x00\x00J\xea\x02P\x00\x00\x00\x00K\xb5\x17`\x00\x00\x00\x00L\xc9\xe4P\x00\x00\x00\x00M\x94\xf9`" + + "\x00\x00\x00\x00N\xa9\xc6P\x00\x00\x00\x00Ot\xdb`\x00\x00\x00\x00P\x89\xa8P\x00\x00\x00\x00QT\xbd`\x00\x00\x00\x00Ri\x8aP\x00\x00\x00\x00S4\x9f`\x00\x00\x00\x00TR\xa6\xd0\x00\x00\x00\x00" + + "U\x14\x81`\x00\x00\x00\x00V2\x88\xd0\x00\x00\x00\x00V\xf4c`\x00\x00\x00\x00X\x12j\xd0\x00\x00\x00\x00X\xdd\u007f\xe0\x00\x00\x00\x00Y\xf2L\xd0\x00\x00\x00\x00Z\xbda\xe0\x00\x00\x00\x00[\xd2.\xd0" + + "\x00\x00\x00\x00\\\x9dC\xe0\x00\x00\x00\x00]\xb2\x10\xd0\x00\x00\x00\x00^}%\xe0\x00\x00\x00\x00_\x9b-P\x00\x00\x00\x00`]\a\xe0\x00\x00\x00\x00a{\x0fP\x00\x00\x00\x00b<\xe9\xe0\x00\x00\x00\x00" + + "cZ\xf1P\x00\x00\x00\x00d&\x06`\x00\x00\x00\x00e:\xd3P\x00\x00\x00\x00f\x05\xe8`\x00\x00\x00\x00g\x1a\xb5P\x00\x00\x00\x00g\xe5\xca`\x00\x00\x00\x00i\x03\xd1\xd0\x00\x00\x00\x00iŬ`" + + "\x00\x00\x00\x00j\xe3\xb3\xd0\x00\x00\x00\x00k\xa5\x8e`\x00\x00\x00\x00lÕ\xd0\x00\x00\x00\x00m\x8e\xaa\xe0\x00\x00\x00\x00n\xa3w\xd0\x00\x00\x00\x00on\x8c\xe0\x00\x00\x00\x00p\x83Y\xd0\x00\x00\x00\x00" + + "qNn\xe0\x00\x00\x00\x00rc;\xd0\x00\x00\x00\x00s.P\xe0\x00\x00\x00\x00tLXP\x00\x00\x00\x00u\x0e2\xe0\x00\x00\x00\x00v,:P\x00\x00\x00\x00v\xee\x14\xe0\x00\x00\x00\x00x\f\x1cP" + + "\x00\x00\x00\x00x\xd71`\x00\x00\x00\x00y\xeb\xfeP\x00\x00\x00\x00z\xb7\x13`\x00\x00\x00\x00{\xcb\xe0P\x00\x00\x00\x00|\x96\xf5`\x00\x00\x00\x00}\xb4\xfc\xd0\x00\x00\x00\x00~v\xd7`\x00\x00\x00\x00" + + "\u007f\x94\xde\xd0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\"\b\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\tLMT\x00EES" + + "T\x00EET\x00\nEET-2EEST,M3.5.5/0,M10.5.5/0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfe\x1c\xdd\x02\xf0\b\x00\x00\xf0\b" + + "\x00\x00\x0e\x00\x1c\x00Asia/JerusalemUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\x00\x00\x00\x06\x00\x00\x00\x15\x80\x00\x00\x00\x9e0E\x88\xc8Y\xb2\xe0\xcc\xe5\xc1Pͬ\xfe\x00\xce\xc6\xf4\xd0Ϗf\xe0" + + "Щy\xd0ф`\xe0Ҋ\xc9p\xd3e\xb0\x80\xd4k\xe0\xd0\xd7Z\x14`\xd7\xdf\x1f\xc0\xd8/\xb5p\xd9\x1eF\xe0\xda\x10\xe8\xf0\xda\xeb\xb3\xe0۴4\x00ܹ \xe0\xdd\xe0\x8d\x00\u07b4\u0380" + + "ߤ\xbf\x80\xe0\x8bv\x00\xe1V}\x00\xe2\xbeJ`\xe364\xd0\xe4\x9c\xf7\x00\xe5\x16\x16\xd0\xe6t\xd3\xe0\xe7\x11Ҁ\xe8'\xff\x00\xe8\xe8O\xd0\b|\x8b\xe0\b\xfd\xb0\xd0\t\xf6\xea`\n\xa63\xd0" + + "\x13\xe8\xaa\xe0\x14 \t\xe0\x1a\xf9t\xe0\x1b\x8d\x1c\xe0\x1c\xbe\xf8\xe0\x1d\x89\xf1\xd0\x1e\xcc\xff`\x1f`\x99P \x82\xb1`!I\xb5\xd0\"^\x9e\xe0# ]P$Z0`%\x00?P&\v\xed\xe0" + + "&\xd6\xe6\xd0'\xeb\xcf\xe0(\xc0\x03P)\xd4\xec`*\xa9\x1f\xd0+\xbbe\xe0,\x89\x01\xd0-\x9bG\xe0._\xa9P/{)\xe00H\xc5\xd01H\x96\xe02\x83\x82p?|\x9f\xe0@s6pAP\xa4`BL\x8f\x00" + + "CHOpD,q\x00E\x1e\xf6\xf0F\fS\x00F\xecc\xf0G\xec5\x00H\xe7\xf5pI\xcc\x17\x00J\xbe\x9c\xf0K\xab\xf9\x00L\x8c\t\xf0M\x95\x15\x80N\x87\x9bpOt\xf7\x80P^B\xf0" + + "QTـRlIpS4\xbb\x80TL+pU\x14\x9d\x80V,\rpV\xf4\u007f\x80X\x15)\xf0X\xd4a\x80Y\xf5\v\xf0Z\xb4C\x80[\xd4\xed\xf0\\\x9d`\x00]\xb4\xcf\xf0^}B\x00" + + "_\x94\xb1\xf0`]$\x00a}\xcepb=\x06\x00c]\xb0pd\x1c\xe8\x00e=\x92pf\x06\x04\x80g\x1dtpg\xe5\xe6\x80h\xfdVpi\xc5Ȁj\xdd8pk\xa5\xaa\x80l\xc6T\xf0" + + "m\x85\x8c\x80n\xa66\xf0oen\x80p\x86\x18\xf0qN\x8b\x00re\xfa\xf0s.m\x00tE\xdc\xf0u\x0eO\x00v.\xf9pv\xee1\x00x\x0e\xdbpx\xce\x13\x00y\xee\xbdpz\xad\xf5\x00" + + "{Οp|\x97\x11\x80}\xae\x81p~v\xf3\x80\u007f\x8ecp\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00!\x06\x00\x00\x00\x00 \xf8\x00\x04\x00" + + "\x00*0\x01\b\x00\x00\x1c \x00\f\x00\x008@\x01\x10\x00\x00*0\x01\bLMT\x00JMT\x00IDT\x00IST\x00IDDT\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\x00\x00\x00\x06\x00\x00\x00\x15\xff\xff\xff\xffV\xb6\xc2\xfa\xff\xff\xff\xff\x9e0E\x88\xff\xff\xff\xff\xc8Y\xb2\xe0\xff\xff\xff\xff\xcc\xe5\xc1P" + + "\xff\xff\xff\xffͬ\xfe\x00\xff\xff\xff\xff\xce\xc6\xf4\xd0\xff\xff\xff\xffϏf\xe0\xff\xff\xff\xffЩy\xd0\xff\xff\xff\xffф`\xe0\xff\xff\xff\xffҊ\xc9p\xff\xff\xff\xff\xd3e\xb0\x80\xff\xff\xff\xff" + + "\xd4k\xe0\xd0\xff\xff\xff\xff\xd7Z\x14`\xff\xff\xff\xff\xd7\xdf\x1f\xc0\xff\xff\xff\xff\xd8/\xb5p\xff\xff\xff\xff\xd9\x1eF\xe0\xff\xff\xff\xff\xda\x10\xe8\xf0\xff\xff\xff\xff\xda\xeb\xb3\xe0\xff\xff\xff\xff۴4\x00" + + "\xff\xff\xff\xffܹ \xe0\xff\xff\xff\xff\xdd\xe0\x8d\x00\xff\xff\xff\xff\u07b4\u0380\xff\xff\xff\xffߤ\xbf\x80\xff\xff\xff\xff\xe0\x8bv\x00\xff\xff\xff\xff\xe1V}\x00\xff\xff\xff\xff\xe2\xbeJ`\xff\xff\xff\xff" + + "\xe364\xd0\xff\xff\xff\xff\xe4\x9c\xf7\x00\xff\xff\xff\xff\xe5\x16\x16\xd0\xff\xff\xff\xff\xe6t\xd3\xe0\xff\xff\xff\xff\xe7\x11Ҁ\xff\xff\xff\xff\xe8'\xff\x00\xff\xff\xff\xff\xe8\xe8O\xd0\x00\x00\x00\x00\b|\x8b\xe0" + + "\x00\x00\x00\x00\b\xfd\xb0\xd0\x00\x00\x00\x00\t\xf6\xea`\x00\x00\x00\x00\n\xa63\xd0\x00\x00\x00\x00\x13\xe8\xaa\xe0\x00\x00\x00\x00\x14 \t\xe0\x00\x00\x00\x00\x1a\xf9t\xe0\x00\x00\x00\x00\x1b\x8d\x1c\xe0\x00\x00\x00\x00" + + "\x1c\xbe\xf8\xe0\x00\x00\x00\x00\x1d\x89\xf1\xd0\x00\x00\x00\x00\x1e\xcc\xff`\x00\x00\x00\x00\x1f`\x99P\x00\x00\x00\x00 \x82\xb1`\x00\x00\x00\x00!I\xb5\xd0\x00\x00\x00\x00\"^\x9e\xe0\x00\x00\x00\x00# ]P" + + "\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00&\xd6\xe6\xd0\x00\x00\x00\x00'\xeb\xcf\xe0\x00\x00\x00\x00(\xc0\x03P\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00" + + "*\xa9\x1f\xd0\x00\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00,\x89\x01\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00._\xa9P\x00\x00\x00\x00/{)\xe0\x00\x00\x00\x000H\xc5\xd0\x00\x00\x00\x001H\x96\xe0" + + "\x00\x00\x00\x002\x83\x82p\x00\x00\x00\x00?|\x9f\xe0" + + "\x00\x00\x00\x00@s6p\x00\x00\x00\x00AP\xa4`\x00\x00\x00\x00BL\x8f\x00\x00\x00\x00\x00CHOp\x00\x00\x00\x00D,q\x00\x00\x00\x00\x00E\x1e\xf6\xf0\x00\x00\x00\x00F\fS\x00\x00\x00\x00\x00" + + "F\xecc\xf0\x00\x00\x00\x00G\xec5\x00\x00\x00\x00\x00H\xe7\xf5p\x00\x00\x00\x00I\xcc\x17\x00\x00\x00\x00\x00J\xbe\x9c\xf0\x00\x00\x00\x00K\xab\xf9\x00\x00\x00\x00\x00L\x8c\t\xf0\x00\x00\x00\x00M\x95\x15\x80" + + "\x00\x00\x00\x00N\x87\x9bp\x00\x00\x00\x00Ot\xf7\x80\x00\x00\x00\x00P^B\xf0\x00\x00\x00\x00QTـ\x00\x00\x00\x00RlIp\x00\x00\x00\x00S4\xbb\x80\x00\x00\x00\x00TL+p\x00\x00\x00\x00" + + "U\x14\x9d\x80\x00\x00\x00\x00V,\rp\x00\x00\x00\x00V\xf4\u007f\x80\x00\x00\x00\x00X\x15)\xf0\x00\x00\x00\x00X\xd4a\x80\x00\x00\x00\x00Y\xf5\v\xf0\x00\x00\x00\x00Z\xb4C\x80\x00\x00\x00\x00[\xd4\xed\xf0" + + "\x00\x00\x00\x00\\\x9d`\x00\x00\x00\x00\x00]\xb4\xcf\xf0\x00\x00\x00\x00^}B\x00\x00\x00\x00\x00_\x94\xb1\xf0\x00\x00\x00\x00`]$\x00\x00\x00\x00\x00a}\xcep\x00\x00\x00\x00b=\x06\x00\x00\x00\x00\x00" + + "c]\xb0p\x00\x00\x00\x00d\x1c\xe8\x00\x00\x00\x00\x00e=\x92p\x00\x00\x00\x00f\x06\x04\x80\x00\x00\x00\x00g\x1dtp\x00\x00\x00\x00g\xe5\xe6\x80\x00\x00\x00\x00h\xfdVp\x00\x00\x00\x00i\xc5Ȁ" + + "\x00\x00\x00\x00j\xdd8p\x00\x00\x00\x00k\xa5\xaa\x80\x00\x00\x00\x00l\xc6T\xf0\x00\x00\x00\x00m\x85\x8c\x80\x00\x00\x00\x00n\xa66\xf0\x00\x00\x00\x00oen\x80\x00\x00\x00\x00p\x86\x18\xf0\x00\x00\x00\x00" + + "qN\x8b\x00\x00\x00\x00\x00re\xfa\xf0\x00\x00\x00\x00s.m\x00\x00\x00\x00\x00tE\xdc\xf0\x00\x00\x00\x00u\x0eO\x00\x00\x00\x00\x00v.\xf9p\x00\x00\x00\x00v\xee1\x00\x00\x00\x00\x00x\x0e\xdbp" + + "\x00\x00\x00\x00x\xce\x13\x00\x00\x00\x00\x00y\xee\xbdp\x00\x00\x00\x00z\xad\xf5\x00\x00\x00\x00\x00{Οp\x00\x00\x00\x00|\x97\x11\x80\x00\x00\x00\x00}\xae\x81p\x00\x00\x00\x00~v\xf3\x80\x00\x00\x00\x00" + + "\u007f\x8ecp\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00!\x06\x00\x00\x00\x00 \xf8\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\f\x00\x008@\x01" + + "\x10\x00\x00*0\x01\bLMT\x00JMT\x00IDT\x00IST\x00IDDT\x00\nIST-2IDT,M3.4.4/26,M10.5.0\nPK\x03\x04" + + "\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe3\x97\x04\xe9\xcb\x00\x00\x00\xcb\x00\x00\x00\v\x00\x1c\x00Asia/BruneiUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00" + + "\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x0e\xad\x8a\x02D\xbagG\x88\u007f\xff\xff" + + "\xff\x01\x02\x02\x00\x00k\xbc\x00\x00\x00\x00ix\x00\x04\x00\x00p\x80\x00\nLMT\x00+0730\x00+08\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xff\xad\x8a\x02D\xff\xff\xff\xff\xbagG\x88\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x02\x00\x00k\xbc\x00\x00\x00\x00ix\x00\x04\x00" + + "\x00p\x80\x00\nLMT\x00+0730\x00+08\x00\n<+08>-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xbd*B/{\x03\x00\x00{\x03\x00\x00\x10\x00\x1c\x00As" + + "ia/UlaanbaatarUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\x04\x00\x00\x00\x10\x86\xd3\xeeL\x0f\vܐ\x18\xe9Ȁ\x19\xda\xfc\xf0\x1a\xccM\x80\x1b\xbc0p\x1c\xac/\x80\x1d\x9c\x12p\x1e\x8c" + + "\x11\x80\x1f{\xf4p k\xf3\x80![\xd6p\"KՀ#;\xb8p$+\xb7\x80%\x1b\x9ap&\v\x99\x80'\x04\xb6\xf0'\xf4\xb6\x00(\xe4\x98\xf0)Ԙ\x00*\xc4z\xf0+\xb4z\x00,\xa4" + + "\\\xf0-\x94\\\x00.\x84>\xf0/t>\x000d \xf01]Z\x802M=p3=<\x804-\x1fp5\x1d\x1e\x806\r\x01p:鳠;\xb4\xac\x90<\xa4\xab\xa0=\x94\x8e\x90>\x84" + + "\x8d\xa0?tp\x90@do\xa0ATR\x90BDQ\xa0C44\x90D$3\xa0E\x1dQ\x10U\x15\x9a\xa0V\x05apV\xf5|\xa0W\xe5Cp\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x03\x00\x00d4\x00\x00\x00\x00bp\x00\x04\x00\x00~\x90\x01\b\x00" + + "\x00p\x80\x00\fLMT\x00+07\x00+09\x00+08\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00" + + "\x04\x00\x00\x00\x10\xff\xff\xff\xff\x86\xd3\xeeL\x00\x00\x00\x00\x0f\vܐ\x00\x00\x00\x00\x18\xe9Ȁ\x00\x00\x00\x00\x19\xda\xfc\xf0\x00\x00\x00\x00\x1a\xccM\x80\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac/" + + "\x80\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x11\x80\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xf3\x80\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\"KՀ\x00\x00\x00\x00#;\xb8p\x00\x00\x00" + + "\x00$+\xb7\x80\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\v\x99\x80\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xe4\x98\xf0\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*\xc4z" + + "\xf0\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xa4\\\xf0\x00\x00\x00\x00-\x94\\\x00\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Z\x80\x00\x00\x00" + + "\x002M=p\x00\x00\x00\x003=<\x80\x00\x00\x00\x004-\x1fp\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\r\x01p\x00\x00\x00\x00:鳠\x00\x00\x00\x00;\xb4\xac\x90\x00\x00\x00\x00<\xa4\xab" + + "\xa0\x00\x00\x00\x00=\x94\x8e\x90\x00\x00\x00\x00>\x84\x8d\xa0\x00\x00\x00\x00?tp\x90\x00\x00\x00\x00@do\xa0\x00\x00\x00\x00ATR\x90\x00\x00\x00\x00BDQ\xa0\x00\x00\x00\x00C44\x90\x00\x00\x00" + + "\x00D$3\xa0\x00\x00\x00\x00E\x1dQ\x10\x00\x00\x00\x00U\x15\x9a\xa0\x00\x00\x00\x00V\x05ap\x00\x00\x00\x00V\xf5|\xa0\x00\x00\x00\x00W\xe5Cp\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x03\x00\x00d4\x00\x00\x00\x00bp\x00\x04\x00\x00~\x90" + + "\x01\b\x00\x00p\x80\x00\fLMT\x00+07\x00+09\x00+08\x00\n<+08>-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa0Qf\xd1=\a\x00\x00=\a\x00\x00\n" + + "\x00\x1c\x00Asia/AmmanUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00u\x00\x00\x00\x05\x00\x00\x00\r\xb6\xa3\xd6\xd0\x06ry\xe0\a\f\xabP\b$7`\b\xed\xde\xd0\n\x05j\xe0\n\xcf\x12P\v\xe7\xef\xe0\f\xdau" + + "\xd0\r\xc9#`\x0e\x92\xca\xd0\x0f\xa9\x05`\x10r\xac\xd0\x1c\xad\xd5`\x1d\x9f\t\xd0\x1e\x92\xfd`\x1f\x82\xe0P r\xdf`!b\xc2P\"R\xc1`#K\xde\xd0$d\xbc`%+\xc0\xd0&7o" + + "`'\v\xa2\xd0(\vs\xe0(\xe2JP)\xe4\xbe`*\xcbf\xd0+\xbbe\xe0,\xabH\xd0-\x9bG\xe0.x\xb5\xd0/\x84d`0X\xa5\xe01dF`2A\xc2`3D(`4!\xa4" + + "`5$\n`6\x01\x86`7z\x93`7\xea\xa2\xe08\xe2|\xe09ӿ`:\xc2^\xe0;\xb3\xa1`<\xa3\x92`=\x93\x83`>\x83t`?\x98O`@cV`An\xf6\xe0BLr" + + "\xe0C\x83t`\x00\x00\x00\x00?\x98O`\x00\x00\x00\x00@cV`\x00\x00\x00\x00An\xf6\xe0\x00\x00\x00\x00BLr\xe0\x00\x00\x00\x00C<" + + "c\xe0\x00\x00\x00\x00D,T\xe0\x00\x00\x00\x00EA/\xe0\x00\x00\x00\x00F\f6\xe0\x00\x00\x00\x00G!\x11\xe0\x00\x00\x00\x00G\xec\x18\xe0\x00\x00\x00\x00I\n.`\x00\x00\x00\x00I\xcb\xfa\xe0\x00\x00" + + "\x00\x00J\xea\x10`\x00\x00\x00\x00K\xab\xdc\xe0\x00\x00\x00\x00L\xc9\xf2`\x00\x00\x00\x00M\x94\xf9`\x00\x00\x00\x00N\xa9\xd4`\x00\x00\x00\x00Ot\xdb`\x00\x00\x00\x00R\xb3^P\x00\x00\x00\x00S4" + + "\x9f`\x00\x00\x00\x00TR\xb4\xe0\x00\x00\x00\x00U\x14\x81`\x00\x00\x00\x00V2\x96\xe0\x00\x00\x00\x00V\xfd\x9d\xe0\x00\x00\x00\x00X\x12x\xe0\x00\x00\x00\x00X\xdd\u007f\xe0\x00\x00\x00\x00Y\xf2Z\xe0\x00\x00" + + "\x00\x00Z\xbda\xe0\x00\x00\x00\x00[\xd2<\xe0\x00\x00\x00\x00\\\x9dC\xe0\x00\x00\x00\x00]\xb2\x1e\xe0\x00\x00\x00\x00^}%\xe0\x00\x00\x00\x00_\x9b;`\x00\x00\x00\x00`]\a\xe0\x00\x00\x00\x00a{" + + "\x1d`\x00\x00\x00\x00bF$`\x00\x00\x00\x00cZ\xff`\x00\x00\x00\x00d&\x06`\x00\x00\x00\x00e:\xe1`\x00\x00\x00\x00f\x05\xe8`\x00\x00\x00\x00g\x1a\xc3`\x00\x00\x00\x00g\xe5\xca`\x00\x00" + + "\x00\x00i\x03\xdf\xe0\x00\x00\x00\x00iŬ`\x00\x00\x00\x00j\xe3\xc1\xe0\x00\x00\x00\x00k\xa5\x8e`\x00\x00\x00\x00lã\xe0\x00\x00\x00\x00m\x8e\xaa\xe0\x00\x00\x00\x00n\xa3\x85\xe0\x00\x00\x00\x00on" + + "\x8c\xe0\x00\x00\x00\x00p\x83g\xe0\x00\x00\x00\x00qNn\xe0\x00\x00\x00\x00rcI\xe0\x00\x00\x00\x00s.P\xe0\x00\x00\x00\x00tLf`\x00\x00\x00\x00u\x0e2\xe0\x00\x00\x00\x00v,H`\x00\x00" + + "\x00\x00v\xf7O`\x00\x00\x00\x00x\f*`\x00\x00\x00\x00x\xd71`\x00\x00\x00\x00y\xec\f`\x00\x00\x00\x00z\xb7\x13`\x00\x00\x00\x00{\xcb\xee`\x00\x00\x00\x00|\x96\xf5`\x00\x00\x00\x00}\xb5" + + "\n\xe0\x00\x00\x00\x00~v\xd7`\x00\x00\x00\x00\u007f\x94\xec\xe0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x04" + + "\x03\x04\x03\x04\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01" + + "\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x00\x00!\xb0\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00\x1c \x00\t\x00\x00*0\x01\x04LMT\x00EEST\x00EET\x00\x00\x00" + + "\x00\x01\x01\nEET-2EEST,M3.5.4/24,M10.5.5/1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x92\xa4\x05+\xe3\x01\x00\x00\xe3\x01\x00\x00" + + "\f\x00\x1c\x00Asia/KuchingUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x06\x00\x00\x00\x18\xad\x8a\x06\x90\xbagG\x88\xbf{'\x80\xbf\xf3\x1bP\xc1]\xac\x80\xc1ՠP\xc3>\xe0\x00ö\xd3\xd0" + + "\xc5 \x13\x80Ř\aP\xc7\x01G\x00\xc7y:\xd0\xc8\xe3\xcc\x00\xc9[\xbf\xd0\xca\xc4\xff\x80\xcb<\xf3PˑX\x00\xd2Hm\xf0\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x04\x03\x03\x00\x00gp\x00\x00\x00\x00ix\x00\x04\x00\x00u0\x01\n\x00\x00p\x80\x00\x10\x00\x00~\x90\x00\x14\x00\x00p\x80\x00\x10LMT\x00+0730\x00+0820\x00+08\x00+" + + "09\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\xad\x8a\x06\x90\xff\xff\xff\xff\xba" + + "gG\x88\xff\xff\xff\xff\xbf{'\x80\xff\xff\xff\xff\xbf\xf3\x1bP\xff\xff\xff\xff\xc1]\xac\x80\xff\xff\xff\xff\xc1ՠP\xff\xff\xff\xff\xc3>\xe0\x00\xff\xff\xff\xffö\xd3\xd0\xff\xff\xff\xff\xc5 \x13\x80\xff" + + "\xff\xff\xffŘ\aP\xff\xff\xff\xff\xc7\x01G\x00\xff\xff\xff\xff\xc7y:\xd0\xff\xff\xff\xff\xc8\xe3\xcc\x00\xff\xff\xff\xff\xc9[\xbf\xd0\xff\xff\xff\xff\xca\xc4\xff\x80\xff\xff\xff\xff\xcb<\xf3P\xff\xff\xff\xff\xcb" + + "\x91X\x00\xff\xff\xff\xff\xd2Hm\xf0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x03\x00\x00gp\x00\x00\x00\x00ix\x00\x04\x00\x00u0\x01\n\x00\x00p\x80" + + "\x00\x10\x00\x00~\x90\x00\x14\x00\x00p\x80\x00\x10LMT\x00+0730\x00+0820\x00+08\x00+09\x00\n<+08>-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9c" + + "P\xfe\x1c\xdd\x02\xf0\b\x00\x00\xf0\b\x00\x00\r\x00\x1c\x00Asia/Tel_AvivUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZ" + + "if3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\x00\x00\x00\x06\x00\x00\x00\x15\x80\x00\x00\x00\x9e0E\x88\xc8Y\xb2\xe0\xcc\xe5\xc1Pͬ" + + "\xfe\x00\xce\xc6\xf4\xd0Ϗf\xe0Щy\xd0ф`\xe0Ҋ\xc9p\xd3e\xb0\x80\xd4k\xe0\xd0\xd7Z\x14`\xd7\xdf\x1f\xc0\xd8/\xb5p\xd9\x1eF\xe0\xda\x10\xe8\xf0\xda\xeb\xb3\xe0۴4\x00ܹ" + + " \xe0\xdd\xe0\x8d\x00\u07b4\u0380ߤ\xbf\x80\xe0\x8bv\x00\xe1V}\x00\xe2\xbeJ`\xe364\xd0\xe4\x9c\xf7\x00\xe5\x16\x16\xd0\xe6t\xd3\xe0\xe7\x11Ҁ\xe8'\xff\x00\xe8\xe8O\xd0\b|\x8b\xe0\b\xfd" + + "\xb0\xd0\t\xf6\xea`\n\xa63\xd0\x13\xe8\xaa\xe0\x14 \t\xe0\x1a\xf9t\xe0\x1b\x8d\x1c\xe0\x1c\xbe\xf8\xe0\x1d\x89\xf1\xd0\x1e\xcc\xff`\x1f`\x99P \x82\xb1`!I\xb5\xd0\"^\x9e\xe0# ]P$Z" + + "0`%\x00?P&\v\xed\xe0&\xd6\xe6\xd0'\xeb\xcf\xe0(\xc0\x03P)\xd4\xec`*\xa9\x1f\xd0+\xbbe\xe0,\x89\x01\xd0-\x9bG\xe0._\xa9P/{)\xe00H\xc5\xd01H\x96\xe02<" + + "nP31\xb3`4\x1a\xfe\xd05\x11\x95`5\xf1\xa6P7\x04\b\x807\xcf\x01p8\xf6_\x809\xdc\xf9\xe0:\xd0\xedp;\xae[`<\xa3\xa0p=\xa0\xb2`>\x83\x82p?|\x9f\xe0@s" + + "6pAP\xa4`BL\x8f\x00CHOpD,q\x00E\x1e\xf6\xf0F\fS\x00F\xecc\xf0G\xec5\x00H\xe7\xf5pI\xcc\x17\x00J\xbe\x9c\xf0K\xab\xf9\x00L\x8c\t\xf0M\x95\x15\x80N\x87" + + "\x9bpOt\xf7\x80P^B\xf0QTـRlIpS4\xbb\x80TL+pU\x14\x9d\x80V,\rpV\xf4\u007f\x80X\x15)\xf0X\xd4a\x80Y\xf5\v\xf0Z\xb4C\x80[\xd4\xed\xf0\\\x9d" + + "`\x00]\xb4\xcf\xf0^}B\x00_\x94\xb1\xf0`]$\x00a}\xcepb=\x06\x00c]\xb0pd\x1c\xe8\x00e=\x92pf\x06\x04\x80g\x1dtpg\xe5\xe6\x80h\xfdVpi\xc5Ȁj\xdd" + + "8pk\xa5\xaa\x80l\xc6T\xf0m\x85\x8c\x80n\xa66\xf0oen\x80p\x86\x18\xf0qN\x8b\x00re\xfa\xf0s.m\x00tE\xdc\xf0u\x0eO\x00v.\xf9pv\xee1\x00x\x0e\xdbpx\xce" + + "\x13\x00y\xee\xbdpz\xad\xf5\x00{Οp|\x97\x11\x80}\xae\x81p~v\xf3\x80\u007f\x8ecp\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00!" + + "\x06\x00\x00\x00\x00 \xf8\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\f\x00\x008@\x01\x10\x00\x00*0\x01\bLMT\x00JMT\x00IDT\x00IST\x00IDDT\x00TZif3\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\x00\x00\x00\x06\x00\x00\x00\x15\xff\xff\xff\xffV\xb6\xc2\xfa\xff\xff\xff\xff\x9e0E\x88\xff\xff\xff\xff\xc8Y" + + "\xb2\xe0\xff\xff\xff\xff\xcc\xe5\xc1P\xff\xff\xff\xffͬ\xfe\x00\xff\xff\xff\xff\xce\xc6\xf4\xd0\xff\xff\xff\xffϏf\xe0\xff\xff\xff\xffЩy\xd0\xff\xff\xff\xffф`\xe0\xff\xff\xff\xffҊ\xc9p\xff\xff" + + "\xff\xff\xd3e\xb0\x80\xff\xff\xff\xff\xd4k\xe0\xd0\xff\xff\xff\xff\xd7Z\x14`\xff\xff\xff\xff\xd7\xdf\x1f\xc0\xff\xff\xff\xff\xd8/\xb5p\xff\xff\xff\xff\xd9\x1eF\xe0\xff\xff\xff\xff\xda\x10\xe8\xf0\xff\xff\xff\xff\xda\xeb" + + "\xb3\xe0\xff\xff\xff\xff۴4\x00\xff\xff\xff\xffܹ \xe0\xff\xff\xff\xff\xdd\xe0\x8d\x00\xff\xff\xff\xff\u07b4\u0380\xff\xff\xff\xffߤ\xbf\x80\xff\xff\xff\xff\xe0\x8bv\x00\xff\xff\xff\xff\xe1V}\x00\xff\xff" + + "\xff\xff\xe2\xbeJ`\xff\xff\xff\xff\xe364\xd0\xff\xff\xff\xff\xe4\x9c\xf7\x00\xff\xff\xff\xff\xe5\x16\x16\xd0\xff\xff\xff\xff\xe6t\xd3\xe0\xff\xff\xff\xff\xe7\x11Ҁ\xff\xff\xff\xff\xe8'\xff\x00\xff\xff\xff\xff\xe8\xe8" + + "O\xd0\x00\x00\x00\x00\b|\x8b\xe0\x00\x00\x00\x00\b\xfd\xb0\xd0\x00\x00\x00\x00\t\xf6\xea`\x00\x00\x00\x00\n\xa63\xd0\x00\x00\x00\x00\x13\xe8\xaa\xe0\x00\x00\x00\x00\x14 \t\xe0\x00\x00\x00\x00\x1a\xf9t\xe0\x00\x00" + + "\x00\x00\x1b\x8d\x1c\xe0\x00\x00\x00\x00\x1c\xbe\xf8\xe0\x00\x00\x00\x00\x1d\x89\xf1\xd0\x00\x00\x00\x00\x1e\xcc\xff`\x00\x00\x00\x00\x1f`\x99P\x00\x00\x00\x00 \x82\xb1`\x00\x00\x00\x00!I\xb5\xd0\x00\x00\x00\x00\"^" + + "\x9e\xe0\x00\x00\x00\x00# ]P\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00&\xd6\xe6\xd0\x00\x00\x00\x00'\xeb\xcf\xe0\x00\x00\x00\x00(\xc0\x03P\x00\x00" + + "\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xa9\x1f\xd0\x00\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00,\x89\x01\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00._\xa9P\x00\x00\x00\x00/{)\xe0\x00\x00\x00\x000H" + + "\xc5\xd0\x00\x00\x00\x001H\x96\xe0\x00\x00\x00\x002\x83" + + "\x82p\x00\x00\x00\x00?|\x9f\xe0\x00\x00\x00\x00@s6p\x00\x00\x00\x00AP\xa4`\x00\x00\x00\x00BL\x8f\x00\x00\x00\x00\x00CHOp\x00\x00\x00\x00D,q\x00\x00\x00\x00\x00E\x1e\xf6\xf0\x00\x00" + + "\x00\x00F\fS\x00\x00\x00\x00\x00F\xecc\xf0\x00\x00\x00\x00G\xec5\x00\x00\x00\x00\x00H\xe7\xf5p\x00\x00\x00\x00I\xcc\x17\x00\x00\x00\x00\x00J\xbe\x9c\xf0\x00\x00\x00\x00K\xab\xf9\x00\x00\x00\x00\x00L\x8c" + + "\t\xf0\x00\x00\x00\x00M\x95\x15\x80\x00\x00\x00\x00N\x87\x9bp\x00\x00\x00\x00Ot\xf7\x80\x00\x00\x00\x00P^B\xf0\x00\x00\x00\x00QTـ\x00\x00\x00\x00RlIp\x00\x00\x00\x00S4\xbb\x80\x00\x00" + + "\x00\x00TL+p\x00\x00\x00\x00U\x14\x9d\x80\x00\x00\x00\x00V,\rp\x00\x00\x00\x00V\xf4\u007f\x80\x00\x00\x00\x00X\x15)\xf0\x00\x00\x00\x00X\xd4a\x80\x00\x00\x00\x00Y\xf5\v\xf0\x00\x00\x00\x00Z\xb4" + + "C\x80\x00\x00\x00\x00[\xd4\xed\xf0\x00\x00\x00\x00\\\x9d`\x00\x00\x00\x00\x00]\xb4\xcf\xf0\x00\x00\x00\x00^}B\x00\x00\x00\x00\x00_\x94\xb1\xf0\x00\x00\x00\x00`]$\x00\x00\x00\x00\x00a}\xcep\x00\x00" + + "\x00\x00b=\x06\x00\x00\x00\x00\x00c]\xb0p\x00\x00\x00\x00d\x1c\xe8\x00\x00\x00\x00\x00e=\x92p\x00\x00\x00\x00f\x06\x04\x80\x00\x00\x00\x00g\x1dtp\x00\x00\x00\x00g\xe5\xe6\x80\x00\x00\x00\x00h\xfd" + + "Vp\x00\x00\x00\x00i\xc5Ȁ\x00\x00\x00\x00j\xdd8p\x00\x00\x00\x00k\xa5\xaa\x80\x00\x00\x00\x00l\xc6T\xf0\x00\x00\x00\x00m\x85\x8c\x80\x00\x00\x00\x00n\xa66\xf0\x00\x00\x00\x00oen\x80\x00\x00" + + "\x00\x00p\x86\x18\xf0\x00\x00\x00\x00qN\x8b\x00\x00\x00\x00\x00re\xfa\xf0\x00\x00\x00\x00s.m\x00\x00\x00\x00\x00tE\xdc\xf0\x00\x00\x00\x00u\x0eO\x00\x00\x00\x00\x00v.\xf9p\x00\x00\x00\x00v\xee" + + "1\x00\x00\x00\x00\x00x\x0e\xdbp\x00\x00\x00\x00x\xce\x13\x00\x00\x00\x00\x00y\xee\xbdp\x00\x00\x00\x00z\xad\xf5\x00\x00\x00\x00\x00{Οp\x00\x00\x00\x00|\x97\x11\x80\x00\x00\x00\x00}\xae\x81p\x00\x00" + + "\x00\x00~v\xf3\x80\x00\x00\x00\x00\u007f\x8ecp\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00!\x06\x00\x00\x00\x00 \xf8\x00\x04\x00\x00*0\x01\b\x00" + + "\x00\x1c \x00\f\x00\x008@\x01\x10\x00\x00*0\x01\bLMT\x00JMT\x00IDT\x00IST\x00IDDT\x00\nIST-2IDT,M3.4.4/26,M1" + + "0.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe3\x16\xfb\xddi\x02\x00\x00i\x02\x00\x00\n\x00\x1c\x00Asia/SeoulUT\t\x00\x03nӧ^nӧ^u" + + "x\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\a\x00\x00\x00\x10\x8b\xd7" + + "\xf0x\x92\xe6\x16\xf8\xd2C'\xf0\xd7e\x8fp\xd7\xee\x9d`\xd8\xf8\xfap\xd9\xcd-\xe0\xda\u05ca\xf0ۭ\x0f\xe0\xdc\xe6\xe2\xf0\u074c\xf1\xe0\xe2O)\xf0\xe4k\xb7\xf8\xe5\x13\x18h\xe6b\x03x\xe7\x11" + + "L\xe8\xe8/px\xe8\xe7\xf4h\xea\x0fRx\xea\xc7\xd6h\xeb\xef4x째h\xed\xcf\x16x\ue1dah\xf05qx \xa3`\x90!ng\x90\"\x83B\x90#NI\x90\x01\x02\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x04\x03\x04\x03\x04\x00\x00w\b\x00\x00\x00\x00w\x88\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x01\f\x00\x00~\x90\x00\x04\x00\x00\x85\x98\x01\f\x00" + + "\x00\x8c\xa0\x01\fLMT\x00KST\x00JST\x00KDT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00" + + "\a\x00\x00\x00\x10\xff\xff\xff\xff\x8b\xd7\xf0x\xff\xff\xff\xff\x92\xe6\x16\xf8\xff\xff\xff\xff\xd2C'\xf0\xff\xff\xff\xff\xd7e\x8fp\xff\xff\xff\xff\xd7\xee\x9d`\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xd9\xcd-" + + "\xe0\xff\xff\xff\xff\xda\u05ca\xf0\xff\xff\xff\xffۭ\x0f\xe0\xff\xff\xff\xff\xdc\xe6\xe2\xf0\xff\xff\xff\xff\u074c\xf1\xe0\xff\xff\xff\xff\xe2O)\xf0\xff\xff\xff\xff\xe4k\xb7\xf8\xff\xff\xff\xff\xe5\x13\x18h\xff\xff\xff" + + "\xff\xe6b\x03x\xff\xff\xff\xff\xe7\x11L\xe8\xff\xff\xff\xff\xe8/px\xff\xff\xff\xff\xe8\xe7\xf4h\xff\xff\xff\xff\xea\x0fRx\xff\xff\xff\xff\xea\xc7\xd6h\xff\xff\xff\xff\xeb\xef4x\xff\xff\xff\xff째" + + "h\xff\xff\xff\xff\xed\xcf\x16x\xff\xff\xff\xff\ue1dah\xff\xff\xff\xff\xf05qx\x00\x00\x00\x00 \xa3`\x90\x00\x00\x00\x00!ng\x90\x00\x00\x00\x00\"\x83B\x90\x00\x00\x00\x00#NI\x90\x01\x02\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x04\x03\x04\x03\x04\x00\x00w\b\x00\x00\x00\x00w\x88\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x01\f\x00\x00~\x90\x00\x04\x00\x00\x85\x98" + + "\x01\f\x00\x00\x8c\xa0\x01\fLMT\x00KST\x00JST\x00KDT\x00\nKST-9\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xd3Y\xee\x16\xdf\x03\x00\x00\xdf\x03\x00\x00\v\x00\x1c" + + "\x00Asia/AtyrauUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\n\x00\x00\x00\x14\xaa\x19\x93P\xb5\xa4\vP\x16\x18\xce0\x17\b\xb1 \x17\xf9\xf3\xa0\x18\xe9\xf2\xb0\x19\xdb' \x1a\xccw\xb0\x1b\xbc\x84\xd0" + + "\x1c\xacu\xd0\x1d\x9cf\xd0\x1e\x8cW\xd0\x1f|H\xd0 l9\xd0!\\*\xd0\"L\x1b\xd0#<\f\xd0$+\xfd\xd0%\x1b\xee\xd0&\v\xdf\xd0'\x05\vP'\xf4\xfcP(\xe4\xfb`)x\xa3`" + + ")\xd4\xdeP*\xc4\xcfP+\xb4\xc0P,\xa4\xb1P-\x94\xa2P.\x84\x93P/t\x84P0duP1]\xa0\xd02r{\xd03=\x82\xd04R]\xd05\x1dd\xd062?\xd06\xfdF\xd0" + + "8\x1bj`8\xdd6\xe09\xfbL`:\xbd\x18\xe0;\xdb.`<\xa65`=\xbb\x10`>\x86\x17`?\x9a\xf2`@e\xf9`A\x84\x0e\xe0\u007f\xff\xff\xff\x01\x02\x03\x04\x02\x04\x02\x04\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\b\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\b\a\b\a\b\a\b\a\b\a\x05\x05\x00\x000\xb0\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x00\b\x00\x00T" + + "`\x00\f\x00\x00T`\x01\f\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00FP\x01\b\x00\x008@\x00\x10\x00\x00FP\x00\bLMT\x00+03\x00+05\x00+06\x00+04\x00\x00" + + "\x00\x00\x00\x00\x01\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\n\x00\x00\x00\x14\xff\xff\xff\xff\xaa\x19\x93" + + "P\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00" + + "\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b" + + "\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00" + + "\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84" + + "P\x00\x00\x00\x000duP\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\x82\xd0\x00\x00\x00\x004R]\xd0\x00\x00\x00\x005\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00" + + "\x006\xfdF\xd0\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`\x00\x00\x00\x00<\xa65`\x00\x00\x00\x00=\xbb\x10" + + "`\x00\x00\x00\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x04\x02\x04\x02\x04\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\a\b\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\b\a\b\a\b\a\b\a\b\a\x05\x05\x00\x000\xb0\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x00\b\x00\x00T`\x00\f\x00\x00T`" + + "\x01\f\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00FP\x01\b\x00\x008@\x00\x10\x00\x00FP\x00\bLMT\x00+03\x00+05\x00+06\x00+04\x00\x00\x00\x00\x00\x00\x01\x01\x01" + + "\x01\x01\n<+05>-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xd3\"6\x9f\xed\x00\x00\x00\xed\x00\x00\x00\x0e\x00\x1c\x00Asia/PyongyangUT\t\x00\x03" + + "nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00" + + "\x00\x00\x04\x00\x00\x00\f\x8b\xd7\xf1\x9c\x92\xe6\x16\xf8\xd2/apU\xce\x02pZ\xecup\x01\x02\x03\x01\x03\x00\x00u\xe4\x00\x00\x00\x00w\x88\x00\x04\x00\x00~\x90\x00\b\x00\x00~\x90\x00\x04LMT\x00" + + "KST\x00JST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x8b\xd7\xf1\x9c" + + "\xff\xff\xff\xff\x92\xe6\x16\xf8\xff\xff\xff\xff\xd2/ap\x00\x00\x00\x00U\xce\x02p\x00\x00\x00\x00Z\xecup\x01\x02\x03\x01\x03\x00\x00u\xe4\x00\x00\x00\x00w\x88\x00\x04\x00\x00~\x90\x00\b\x00\x00~\x90\x00" + + "\x04LMT\x00KST\x00JST\x00\nKST-9\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x0f֏\x10{\x03\x00\x00{\x03\x00\x00\t\x00\x1c\x00Asia/HovdU" + + "T\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x003\x00\x00\x00\x04\x00\x00\x00\x10\x86\xd3\xfc\x94\x0f\v\xea\xa0\x18\xe9\u0590\x19\xdb\v\x00\x1a\xcc[\x90\x1b\xbc>\x80\x1c\xac=\x90\x1d\x9c \x80\x1e\x8c\x1f\x90\x1f|\x02\x80 l\x01\x90![\xe4\x80\"" + + "K\xe3\x90#;ƀ$+Ő%\x1b\xa8\x80&\v\xa7\x90'\x04\xc5\x00'\xf4\xc4\x10(\xe4\xa7\x00)Ԧ\x10*ĉ\x00+\xb4\x88\x10,\xa4k\x00-\x94j\x10.\x84M\x00/tL\x100" + + "d/\x001]h\x902MK\x803=J\x904--\x805\x1d,\x906\r\x0f\x80:\xe9\xc1\xb0;\xb4\xba\xa0<\xa4\xb9\xb0=\x94\x9c\xa0>\x84\x9b\xb0?t~\xa0@d}\xb0AT`\xa0B" + + "D_\xb0C4B\xa0D$A\xb0E\x1d_ U\x15\xa8\xb0V\x05o\x80V\xf5\x8a\xb0W\xe5Q\x80\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x03\x00\x00U\xec\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\fLMT\x00+06\x00+0" + + "8\x00+07\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x86\xd3\xfc\x94\x00\x00" + + "\x00\x00\x0f\v\xea\xa0\x00\x00\x00\x00\x18\xe9\u0590\x00\x00\x00\x00\x19\xdb\v\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbc>\x80\x00\x00\x00\x00\x1c\xac=\x90\x00\x00\x00\x00\x1d\x9c \x80\x00\x00\x00\x00\x1e\x8c" + + "\x1f\x90\x00\x00\x00\x00\x1f|\x02\x80\x00\x00\x00\x00 l\x01\x90\x00\x00\x00\x00![\xe4\x80\x00\x00\x00\x00\"K\xe3\x90\x00\x00\x00\x00#;ƀ\x00\x00\x00\x00$+Ő\x00\x00\x00\x00%\x1b\xa8\x80\x00\x00" + + "\x00\x00&\v\xa7\x90\x00\x00\x00\x00'\x04\xc5\x00\x00\x00\x00\x00'\xf4\xc4\x10\x00\x00\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00)Ԧ\x10\x00\x00\x00\x00*ĉ\x00\x00\x00\x00\x00+\xb4\x88\x10\x00\x00\x00\x00,\xa4" + + "k\x00\x00\x00\x00\x00-\x94j\x10\x00\x00\x00\x00.\x84M\x00\x00\x00\x00\x00/tL\x10\x00\x00\x00\x000d/\x00\x00\x00\x00\x001]h\x90\x00\x00\x00\x002MK\x80\x00\x00\x00\x003=J\x90\x00\x00" + + "\x00\x004--\x80\x00\x00\x00\x005\x1d,\x90\x00\x00\x00\x006\r\x0f\x80\x00\x00\x00\x00:\xe9\xc1\xb0\x00\x00\x00\x00;\xb4\xba\xa0\x00\x00\x00\x00<\xa4\xb9\xb0\x00\x00\x00\x00=\x94\x9c\xa0\x00\x00\x00\x00>\x84" + + "\x9b\xb0\x00\x00\x00\x00?t~\xa0\x00\x00\x00\x00@d}\xb0\x00\x00\x00\x00AT`\xa0\x00\x00\x00\x00BD_\xb0\x00\x00\x00\x00C4B\xa0\x00\x00\x00\x00D$A\xb0\x00\x00\x00\x00E\x1d_ \x00\x00" + + "\x00\x00U\x15\xa8\xb0\x00\x00\x00\x00V\x05o\x80\x00\x00\x00\x00V\xf5\x8a\xb0\x00\x00\x00\x00W\xe5Q\x80\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x03\x00\x00U\xec\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\fLMT\x00+06" + + "\x00+08\x00+07\x00\n<+07>-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xec\x80*\xa6(\t\x00\x00(\t\x00\x00\v\x00\x1c\x00Asia/HebronU" + + "T\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00" + + "\x00\x00\x96\x00\x00\x00\x06\x00\x00\x00\x15\x80\x00\x00\x00\xc8Y\xb2\xe0\xcc\xe5\xc1Pͬ\xfe\x00\xce\xc6\xf4\xd0Ϗf\xe0Щy\xd0ф`\xe0Ҋ\xc9p\xd3e\xb0\x80\xd4k\xe0\xd0\xe86c`\xe8" + + "\xf4-P\xea\v\xb9`\xea\xd5`\xd0\xeb\xec\xfa\xf0\xec\xb5m\x00\xed\xcf\u007f\xf0\xee\x97\xf2\x00ﰳp\xf0y%\x80\xf1\x91\xe6\xf0\xf2ZY\x00\xf3s\x1ap\xf4;\x8c\x80\xf5U\x9fp\xf6\x1e\x11\x80\xf7" + + "6\xd2\xf0\xf7\xffE\x00\xf9\x18\x06p\xf9\xe1\xca\x00\xfa\xf99\xf0\xfb'BP\b|\x8b\xe0\b\xfd\xb0\xd0\t\xf6\xea`\n\xa63\xd0\x13\xe8\xaa\xe0\x14 \t\xe0\x1a\xf9t\xe0\x1b\x8d\x1c\xe0\x1c\xbe\xf8\xe0\x1d" + + "\x89\xf1\xd0\x1e\xcc\xff`\x1f`\x99P \x82\xb1`!I\xb5\xd0\"^\x9e\xe0# ]P$Z0`%\x00?P&\v\xed\xe0&\xd6\xe6\xd0'\xeb\xcf\xe0(\xc0\x03P)\xd4\xec`*\xa9\x1f\xd0+" + + "\xbbe\xe0,\x89\x01\xd0-\x9bG\xe0._\xa9P/{)\xe00H\xc5\xd00\xe7\a\xe01dF`2A\xc2`3D(`4!\xa4`5$\n`6\x01\x86`7\x16a`8\x06DP8" + + "\xff}\xe09\xef`\xd0:\xdf_\xe0;\xcfB\xd0<\xbfA\xe0=\xaf$\xd0>\x9f#\xe0?\x8f\x06\xd0@\u007f\x05\xe0A\\\x81\xe0B^\xe7\xe0CA\xb7\xf0D-\xa6`E\x12\xfdPF\x0e\xd9\xe0F" + + "\xe8opG\xec\x18\xe0H\xbb\x06PI\xcb\xfa\xe0J\xa0<`K\xab\xdc\xe0La\xbd\xd0M\x94\xf9\x9cN5\xc2PN\\\v\xe0N\x84\xdcPOt\xdb`P[\x91\xe0QT\xbd`RD\xa0PS" + + "4\x9f`TIlPU\x15\xd2\xe0V)NPV\xf5\xc2\xf0X\x13\xca`Xդ\xf0Y\xf3\xac`Z\xb5\x86\xf0[ӎ`\\\x9dC\xe0]\xb3p`^}%\xe0_\x9c\x8c\xe0`]\a\xe0a" + + "|n\xe0b<\xe9\xe0c\\P\xe0d&\x06`e<2\xe0f\x05\xe8`g\x1c\x14\xe0g\xe5\xca`h\xfb\xf6\xe0iŬ`j\xe5\x13`k\xa5\x8e`l\xc4\xf5`m\x8e\xaa\xe0n\xa4\xd7`o" + + "n\x8c\xe0p\x84\xb9`qNn\xe0rd\x9b`s.P\xe0tD}`u\x0e2\xe0v-\x99\xe0v\xee\x14\xe0x\r{\xe0x\xd71`y\xed]\xe0z\xb7\x13`{\xcd?\xe0|\x96\xf5`}" + + "\xad!\xe0~v\xd7`\u007f\x96>`\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x02\x01\x05\x01\x05\x01\x05\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00 \xe7\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00" + + "\x00*0\x01\r\x00\x00\x1c \x00\x11\x00\x00\x1c \x00\tLMT\x00EEST\x00EET\x00IDT\x00IST\x00\x00\x00\x00\x00\x00\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x96\x00\x00\x00\x06\x00\x00\x00\x15\xff\xff\xff\xff}\xbdJ\x19\xff\xff\xff\xff\xc8Y\xb2\xe0\xff\xff\xff\xff\xcc\xe5\xc1P\xff\xff\xff\xffͬ\xfe\x00" + + "\xff\xff\xff\xff\xce\xc6\xf4\xd0\xff\xff\xff\xffϏf\xe0\xff\xff\xff\xffЩy\xd0\xff\xff\xff\xffф`\xe0\xff\xff\xff\xffҊ\xc9p\xff\xff\xff\xff\xd3e\xb0\x80\xff\xff\xff\xff\xd4k\xe0\xd0\xff\xff\xff\xff" + + "\xe86c`\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea\v\xb9`\xff\xff\xff\xff\xea\xd5`\xd0\xff\xff\xff\xff\xeb\xec\xfa\xf0\xff\xff\xff\xff\xec\xb5m\x00\xff\xff\xff\xff\xed\xcf\u007f\xf0\xff\xff\xff\xff\xee\x97\xf2\x00" + + "\xff\xff\xff\xffﰳp\xff\xff\xff\xff\xf0y%\x80\xff\xff\xff\xff\xf1\x91\xe6\xf0\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3s\x1ap\xff\xff\xff\xff\xf4;\x8c\x80\xff\xff\xff\xff\xf5U\x9fp\xff\xff\xff\xff" + + "\xf6\x1e\x11\x80\xff\xff\xff\xff\xf76\xd2\xf0\xff\xff\xff\xff\xf7\xffE\x00\xff\xff\xff\xff\xf9\x18\x06p\xff\xff\xff\xff\xf9\xe1\xca\x00\xff\xff\xff\xff\xfa\xf99\xf0\xff\xff\xff\xff\xfb'BP\x00\x00\x00\x00\b|\x8b\xe0" + + "\x00\x00\x00\x00\b\xfd\xb0\xd0\x00\x00\x00\x00\t\xf6\xea`\x00\x00\x00\x00\n\xa63\xd0\x00\x00\x00\x00\x13\xe8\xaa\xe0\x00\x00\x00\x00\x14 \t\xe0\x00\x00\x00\x00\x1a\xf9t\xe0\x00\x00\x00\x00\x1b\x8d\x1c\xe0\x00\x00\x00\x00" + + "\x1c\xbe\xf8\xe0\x00\x00\x00\x00\x1d\x89\xf1\xd0\x00\x00\x00\x00\x1e\xcc\xff`\x00\x00\x00\x00\x1f`\x99P\x00\x00\x00\x00 \x82\xb1`\x00\x00\x00\x00!I\xb5\xd0\x00\x00\x00\x00\"^\x9e\xe0\x00\x00\x00\x00# ]P" + + "\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00&\xd6\xe6\xd0\x00\x00\x00\x00'\xeb\xcf\xe0\x00\x00\x00\x00(\xc0\x03P\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00" + + "*\xa9\x1f\xd0\x00\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00,\x89\x01\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00._\xa9P\x00\x00\x00\x00/{)\xe0\x00\x00\x00\x000H\xc5\xd0\x00\x00\x00\x000\xe7\a\xe0" + + "\x00\x00\x00\x001dF`\x00\x00\x00\x002A\xc2`\x00\x00\x00\x003D(`\x00\x00\x00\x004!\xa4`\x00\x00\x00\x005$\n`\x00\x00\x00\x006\x01\x86`\x00\x00\x00\x007\x16a`\x00\x00\x00\x00" + + "8\x06DP\x00\x00\x00\x008\xff}\xe0\x00\x00\x00\x009\xef`\xd0\x00\x00\x00\x00:\xdf_\xe0\x00\x00\x00\x00;\xcfB\xd0\x00\x00\x00\x00<\xbfA\xe0\x00\x00\x00\x00=\xaf$\xd0\x00\x00\x00\x00>\x9f#\xe0" + + "\x00\x00\x00\x00?\x8f\x06\xd0\x00\x00\x00\x00@\u007f\x05\xe0\x00\x00\x00\x00A\\\x81\xe0\x00\x00\x00\x00B^\xe7\xe0\x00\x00\x00\x00CA\xb7\xf0\x00\x00\x00\x00D-\xa6`\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00" + + "F\x0e\xd9\xe0\x00\x00\x00\x00F\xe8op\x00\x00\x00\x00G\xec\x18\xe0\x00\x00\x00\x00H\xbb\x06P\x00\x00\x00\x00I\xcb\xfa\xe0\x00\x00\x00\x00J\xa0<`\x00\x00\x00\x00K\xab\xdc\xe0\x00\x00\x00\x00La\xbd\xd0" + + "\x00\x00\x00\x00M\x94\xf9\x9c\x00\x00\x00\x00N5\xc2P\x00\x00\x00\x00N\\\v\xe0\x00\x00\x00\x00N\x84\xdcP\x00\x00\x00\x00Ot\xdb`\x00\x00\x00\x00P[\x91\xe0\x00\x00\x00\x00QT\xbd`\x00\x00\x00\x00" + + "RD\xa0P\x00\x00\x00\x00S4\x9f`\x00\x00\x00\x00TIlP\x00\x00\x00\x00U\x15\xd2\xe0\x00\x00\x00\x00V)NP\x00\x00\x00\x00V\xf5\xc2\xf0\x00\x00\x00\x00X\x13\xca`\x00\x00\x00\x00Xդ\xf0" + + "\x00\x00\x00\x00Y\xf3\xac`\x00\x00\x00\x00Z\xb5\x86\xf0\x00\x00\x00\x00[ӎ`\x00\x00\x00\x00\\\x9dC\xe0\x00\x00\x00\x00]\xb3p`\x00\x00\x00\x00^}%\xe0\x00\x00\x00\x00_\x9c\x8c\xe0\x00\x00\x00\x00" + + "`]\a\xe0\x00\x00\x00\x00a|n\xe0\x00\x00\x00\x00b<\xe9\xe0\x00\x00\x00\x00c\\P\xe0\x00\x00\x00\x00d&\x06`\x00\x00\x00\x00e<2\xe0\x00\x00\x00\x00f\x05\xe8`\x00\x00\x00\x00g\x1c\x14\xe0" + + "\x00\x00\x00\x00g\xe5\xca`\x00\x00\x00\x00h\xfb\xf6\xe0\x00\x00\x00\x00iŬ`\x00\x00\x00\x00j\xe5\x13`\x00\x00\x00\x00k\xa5\x8e`\x00\x00\x00\x00l\xc4\xf5`\x00\x00\x00\x00m\x8e\xaa\xe0\x00\x00\x00\x00" + + "n\xa4\xd7`\x00\x00\x00\x00on\x8c\xe0\x00\x00\x00\x00p\x84\xb9`\x00\x00\x00\x00qNn\xe0\x00\x00\x00\x00rd\x9b`\x00\x00\x00\x00s.P\xe0\x00\x00\x00\x00tD}`\x00\x00\x00\x00u\x0e2\xe0" + + "\x00\x00\x00\x00v-\x99\xe0\x00\x00\x00\x00v\xee\x14\xe0\x00\x00\x00\x00x\r{\xe0\x00\x00\x00\x00x\xd71`\x00\x00\x00\x00y\xed]\xe0\x00\x00\x00\x00z\xb7\x13`\x00\x00\x00\x00{\xcd?\xe0\x00\x00\x00\x00" + + "|\x96\xf5`\x00\x00\x00\x00}\xad!\xe0\x00\x00\x00\x00~v\xd7`\x00\x00\x00\x00\u007f\x96>`\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x02\x01\x05\x01\x05\x01\x05\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00" + + " \xe7\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x01\r\x00\x00\x1c \x00\x11\x00\x00\x1c \x00\tLMT\x00EEST\x00EET\x00IDT\x00IST\x00\x00\x00\x00\x00\x00" + + "\x01\nEET-2EEST,M3.5.5/0,M10.5.6/1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPs\x92<\x8f\xa5\x00\x00\x00\xa5\x00\x00\x00\v\x00\x1c" + + "\x00Asia/KuwaitUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xd5\x1b6\xb4\u007f\xff\xff\xff\x01\x01\x00\x00+\xcc\x00\x00\x00\x00*0\x00\x04LMT\x00+03\x00TZif2\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xd5\x1b6\xb4\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x00+\xcc" + + "\x00\x00\x00\x00*0\x00\x04LMT\x00+03\x00\n<+03>-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb5\xc1\xd0\f\xc5\x04\x00\x00\xc5\x04\x00\x00\n\x00\x1c\x00Asia/" + + "TomskUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\n\x00\x00\x00\x00\x00\x00\x00D\x00\x00\x00\n\x00\x00\x00\x10\xa1\xe5Nٵ\xa3\xe1 \x15'o\x90\x16\x18\xa4\x00\x17\b\xa3\x10\x17\xf9׀\x18\xe9\u0590\x19\xdb\v\x00\x1a\xcc[\x90\x1b\xbch\xb0\x1c\xacY" + + "\xb0\x1d\x9cJ\xb0\x1e\x8c;\xb0\x1f|,\xb0 l\x1d\xb0!\\\x0e\xb0\"K\xff\xb0#;\xf0\xb0$+\xe1\xb0%\x1bҰ&\vð'\x04\xef0'\xf4\xe00(\xe4\xdf@)x\x87@)\xd4\xc2" + + "0*ij0+\xb4\xa40,\xa4\x950-\x94\x860.\x84w0/th00dY01]\x84\xb02r_\xb03=f\xb04RA\xb05\x1dH\xb062#\xb06\xfd*\xb08\x1b@" + + "08\xdd\f\xb09\xfb\"0:\xbc\xee\xb0;\xdb\x040<\xa6\v0<\xce\xe9\xb0=\xba\xf4@>\x85\xfb@?\x9a\xd6@@e\xdd@A\x83\xf2\xc0BE\xbf@Cc\xd4\xc0D%\xa1@EC\xb6" + + "\xc0F\x05\x83@G#\x98\xc0G\xee\x9f\xc0I\x03z\xc0I\u0381\xc0J\xe3\\\xc0K\xaec\xc0L\xccy@M\x8eE\xc0TK\xf30WI\xf8\xc0\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\b\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x04\a\x04\x04\x00\x00O" + + "\xa7\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\f\x00\x00bp\x00\f\x00\x00p\x80\x01\b\x00\x00bp\x01\f\x00\x00T`\x00\x04\x00\x00bp\x01\f\x00\x00bp\x00\fLMT" + + "\x00+06\x00+08\x00+07\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00D\x00" + + "\x00\x00\n\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xe5N\xd9\xff\xff\xff\xff\xb5\xa3\xe1 \x00\x00\x00\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\b\xa3\x10\x00\x00\x00\x00\x17\xf9׀\x00\x00\x00\x00\x18" + + "\xe9\u0590\x00\x00\x00\x00\x19\xdb\v\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbch\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00" + + "\x00\x00\x00 l\x1d\xb0\x00\x00\x00\x00!\\\x0e\xb0\x00\x00\x00\x00\"K\xff\xb0\x00\x00\x00\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1bҰ\x00\x00\x00\x00&\vð\x00\x00\x00\x00'" + + "\x04\xef0\x00\x00\x00\x00'\xf4\xe00\x00\x00\x00\x00(\xe4\xdf@\x00\x00\x00\x00)x\x87@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*ij0\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00,\xa4\x950\x00" + + "\x00\x00\x00-\x94\x860\x00\x00\x00\x00.\x84w0\x00\x00\x00\x00/th0\x00\x00\x00\x000dY0\x00\x00\x00\x001]\x84\xb0\x00\x00\x00\x002r_\xb0\x00\x00\x00\x003=f\xb0\x00\x00\x00\x004" + + "RA\xb0\x00\x00\x00\x005\x1dH\xb0\x00\x00\x00\x0062#\xb0\x00\x00\x00\x006\xfd*\xb0\x00\x00\x00\x008\x1b@0\x00\x00\x00\x008\xdd\f\xb0\x00\x00\x00\x009\xfb\"0\x00\x00\x00\x00:\xbc\xee\xb0\x00" + + "\x00\x00\x00;\xdb\x040\x00\x00\x00\x00<\xa6\v0\x00\x00\x00\x00<\xce\xe9\xb0\x00\x00\x00\x00=\xba\xf4@\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A" + + "\x83\xf2\xc0\x00\x00\x00\x00BE\xbf@\x00\x00\x00\x00Cc\xd4\xc0\x00\x00\x00\x00D%\xa1@\x00\x00\x00\x00EC\xb6\xc0\x00\x00\x00\x00F\x05\x83@\x00\x00\x00\x00G#\x98\xc0\x00\x00\x00\x00G\xee\x9f\xc0\x00" + + "\x00\x00\x00I\x03z\xc0\x00\x00\x00\x00I\u0381\xc0\x00\x00\x00\x00J\xe3\\\xc0\x00\x00\x00\x00K\xaec\xc0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x00\x00\x00\x00TK\xf30\x00\x00\x00\x00W" + + "I\xf8\xc0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\b\a\x06" + + "\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x04\a\x04\x04\x00\x00O\xa7\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\f\x00\x00bp\x00\f\x00\x00p\x80\x01\b\x00\x00bp\x01" + + "\f\x00\x00T`\x00\x04\x00\x00bp\x01\f\x00\x00bp\x00\fLMT\x00+06\x00+08\x00+07\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x01\n<+07>-7\nPK\x03\x04\n\x00" + + "\x00\x00\x00\x00\xf5F\x9cPl\xb2\xad\xbbH\x01\x00\x00H\x01\x00\x00\v\x00\x1c\x00Asia/ManilaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14" + + "\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x05\x00\x00\x00\x10\x80\x00\x00\x00\xc1\x9c\xf4\x80\xc2\x160p\xcb" + + "\xf2\xe7\x00Щ%p\xe2l9\x00\xe2բ\xf0\x0fuF\x80\x10fz\xf0\x02\x01\x02\x03\x02\x01\x02\x01\x02\xff\xff\x1f\xf0\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\b\x00\x00~\x90\x00\f\x00\x00p\x80" + + "\x00\bLMT\x00PDT\x00PST\x00JST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x06\x00\x00" + + "\x00\x10\xff\xff\xff\xff\x14\xe1\xdc\x10\xff\xff\xff\xff{\x1f?\x90\xff\xff\xff\xff\xc1\x9c\xf4\x80\xff\xff\xff\xff\xc2\x160p\xff\xff\xff\xff\xcb\xf2\xe7\x00\xff\xff\xff\xffЩ%p\xff\xff\xff\xff\xe2l9\x00\xff\xff" + + "\xff\xff\xe2բ\xf0\x00\x00\x00\x00\x0fuF\x80\x00\x00\x00\x00\x10fz\xf0\x01\x03\x02\x03\x04\x03\x02\x03\x02\x03\xff\xff\x1f\xf0\x00\x00\x00\x00qp\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\b\x00\x00~\x90" + + "\x00\f\x00\x00p\x80\x00\bLMT\x00PDT\x00PST\x00JST\x00\nPST-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPuX\x12q\xc5\x04\x00\x00\xc5\x04\x00\x00\n\x00\x1c" + + "\x00Asia/ChitaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\v\x00\x00\x00\x10\xa1\xdb\xf9\xa0\xb5\xa3\xc5\x00\x15'Sp\x16\x18\x87\xe0\x17\b\x86\xf0\x17\xf9\xbb`\x18\xe9\xbap\x19\xda\xee\xe0\x1a\xcc?p\x1b" + + "\xbcL\x90\x1c\xac=\x90\x1d\x9c.\x90\x1e\x8c\x1f\x90\x1f|\x10\x90 l\x01\x90![\xf2\x90\"K\xe3\x90#;Ԑ$+Ő%\x1b\xb6\x90&\v\xa7\x90'\x04\xd3\x10'\xf4\xc4\x10(\xe4\xc3 )" + + "xk )Ԧ\x10*ė\x10+\xb4\x88\x10,\xa4y\x10-\x94j\x10.\x84[\x10/tL\x100d=\x101]h\x902rC\x903=J\x904R%\x905\x1d,\x9062\a\x906" + + "\xfd\x0e\x908\x1b$\x108\xdc\xf0\x909\xfb\x06\x10:\xbcҐ;\xda\xe8\x10<\xa5\xef\x10=\xba\xca\x10>\x85\xd1\x10?\x9a\xac\x10@e\xb3\x10A\x83ȐBE\x95\x10Cc\xaa\x90D%w\x10E" + + "C\x8c\x90F\x05Y\x10G#n\x90G\xeeu\x90I\x03P\x90I\xceW\x90J\xe32\x90K\xae9\x90L\xccO\x10M\x8e\x1b\x90TK\xc9\x00V\xf6\xce \u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\b\a\x03\x03\x00\x00" + + "j`\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\f\x00\x00~\x90\x00\f\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x01\f\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x00\b\x00\x00\x8c\xa0\x01\b\x00\x00" + + "~\x90\x00\fLMT\x00+08\x00+10\x00+09\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00" + + "\x00\x00\x00\x00\x00\x00C\x00\x00\x00\v\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xdb\xf9\xa0\xff\xff\xff\xff\xb5\xa3\xc5\x00\x00\x00\x00\x00\x15'Sp\x00\x00\x00\x00\x16\x18\x87\xe0\x00\x00\x00\x00\x17\b\x86\xf0\x00\x00\x00\x00\x17" + + "\xf9\xbb`\x00\x00\x00\x00\x18\xe9\xbap\x00\x00\x00\x00\x19\xda\xee\xe0\x00\x00\x00\x00\x1a\xcc?p\x00\x00\x00\x00\x1b\xbcL\x90\x00\x00\x00\x00\x1c\xac=\x90\x00\x00\x00\x00\x1d\x9c.\x90\x00\x00\x00\x00\x1e\x8c\x1f\x90\x00" + + "\x00\x00\x00\x1f|\x10\x90\x00\x00\x00\x00 l\x01\x90\x00\x00\x00\x00![\xf2\x90\x00\x00\x00\x00\"K\xe3\x90\x00\x00\x00\x00#;Ԑ\x00\x00\x00\x00$+Ő\x00\x00\x00\x00%\x1b\xb6\x90\x00\x00\x00\x00&" + + "\v\xa7\x90\x00\x00\x00\x00'\x04\xd3\x10\x00\x00\x00\x00'\xf4\xc4\x10\x00\x00\x00\x00(\xe4\xc3 \x00\x00\x00\x00)xk \x00\x00\x00\x00)Ԧ\x10\x00\x00\x00\x00*ė\x10\x00\x00\x00\x00+\xb4\x88\x10\x00" + + "\x00\x00\x00,\xa4y\x10\x00\x00\x00\x00-\x94j\x10\x00\x00\x00\x00.\x84[\x10\x00\x00\x00\x00/tL\x10\x00\x00\x00\x000d=\x10\x00\x00\x00\x001]h\x90\x00\x00\x00\x002rC\x90\x00\x00\x00\x003" + + "=J\x90\x00\x00\x00\x004R%\x90\x00\x00\x00\x005\x1d,\x90\x00\x00\x00\x0062\a\x90\x00\x00\x00\x006\xfd\x0e\x90\x00\x00\x00\x008\x1b$\x10\x00\x00\x00\x008\xdc\xf0\x90\x00\x00\x00\x009\xfb\x06\x10\x00" + + "\x00\x00\x00:\xbcҐ\x00\x00\x00\x00;\xda\xe8\x10\x00\x00\x00\x00<\xa5\xef\x10\x00\x00\x00\x00=\xba\xca\x10\x00\x00\x00\x00>\x85\xd1\x10\x00\x00\x00\x00?\x9a\xac\x10\x00\x00\x00\x00@e\xb3\x10\x00\x00\x00\x00A" + + "\x83Ȑ\x00\x00\x00\x00BE\x95\x10\x00\x00\x00\x00Cc\xaa\x90\x00\x00\x00\x00D%w\x10\x00\x00\x00\x00EC\x8c\x90\x00\x00\x00\x00F\x05Y\x10\x00\x00\x00\x00G#n\x90\x00\x00\x00\x00G\xeeu\x90\x00" + + "\x00\x00\x00I\x03P\x90\x00\x00\x00\x00I\xceW\x90\x00\x00\x00\x00J\xe32\x90\x00\x00\x00\x00K\xae9\x90\x00\x00\x00\x00L\xccO\x10\x00\x00\x00\x00M\x8e\x1b\x90\x00\x00\x00\x00TK\xc9\x00\x00\x00\x00\x00V" + + "\xf6\xce \x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\b\a\x03\x03\x00\x00j`\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\f\x00\x00~\x90\x00\f\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x01\f" + + "\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x00\b\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\fLMT\x00+08\x00+10\x00+09\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x00\n<+09>-9\n" + + "PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP)\xfa\xf8j\xd4\x00\x00\x00\xd4\x00\x00\x00\r\x00\x1c\x00Asia/KatmanduUT\t\x00\x03nӧ^nӧ^ux\v\x00" + + "\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x10\xa1\xf2}\x84\x1e" + + "\x180\xa8\u007f\xff\xff\xff\x01\x02\x02\x00\x00O\xfc\x00\x00\x00\x00MX\x00\x04\x00\x00P\xdc\x00\nLMT\x00+0530\x00+0545\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xf2}\x84\x00\x00\x00\x00\x1e\x180\xa8\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x02\x00\x00O\xfc\x00" + + "\x00\x00\x00MX\x00\x04\x00\x00P\xdc\x00\nLMT\x00+0530\x00+0545\x00\n<+0545>-5:45\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP}\x9e\xc1" + + "\xa4\f\t\x00\x00\f\t\x00\x00\t\x00\x1c\x00Asia/GazaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x94\x00\x00\x00\x06\x00\x00\x00\x15\x80\x00\x00\x00\xc8Y\xb2\xe0\xcc\xe5\xc1Pͬ\xfe\x00\xce\xc6\xf4\xd0Ϗf\xe0Щ" + + "y\xd0ф`\xe0Ҋ\xc9p\xd3e\xb0\x80\xd4k\xe0\xd0\xe86c`\xe8\xf4-P\xea\v\xb9`\xea\xd5`\xd0\xeb\xec\xfa\xf0\xec\xb5m\x00\xed\xcf\u007f\xf0\xee\x97\xf2\x00ﰳp\xf0y%\x80\xf1\x91" + + "\xe6\xf0\xf2ZY\x00\xf3s\x1ap\xf4;\x8c\x80\xf5U\x9fp\xf6\x1e\x11\x80\xf76\xd2\xf0\xf7\xffE\x00\xf9\x18\x06p\xf9\xe1\xca\x00\xfa\xf99\xf0\xfb'BP\b|\x8b\xe0\b\xfd\xb0\xd0\t\xf6\xea`\n\xa6" + + "3\xd0\x13\xe8\xaa\xe0\x14 \t\xe0\x1a\xf9t\xe0\x1b\x8d\x1c\xe0\x1c\xbe\xf8\xe0\x1d\x89\xf1\xd0\x1e\xcc\xff`\x1f`\x99P \x82\xb1`!I\xb5\xd0\"^\x9e\xe0# ]P$Z0`%\x00?P&\v" + + "\xed\xe0&\xd6\xe6\xd0'\xeb\xcf\xe0(\xc0\x03P)\xd4\xec`*\xa9\x1f\xd0+\xbbe\xe0,\x89\x01\xd0-\x9bG\xe0._\xa9P/{)\xe00H\xc5\xd00\xe7\a\xe01dF`2A\xc2`3D" + + "(`4!\xa4`5$\n`6\x01\x86`7\x16a`8\x06DP8\xff}\xe09\xef`\xd0:\xdf_\xe0;\xcfB\xd0<\xbfA\xe0=\xaf$\xd0>\x9f#\xe0?\x8f\x06\xd0@\u007f\x05\xe0A\\" + + "\x81\xe0B^\xe7\xe0CA\xb7\xf0D-\xa6`E\x12\xfdPF\x0e\xd9\xe0F\xe8opG\xec\x18\xe0H\xb7\x11\xd0I\xcb\xfa\xe0J\xa0<`K\xad.\x9cLa\xbd\xd0M\x94\xf9\x9cN5\xc2POt" + + "\xdb`P[\x91\xe0QT\xbd`RD\xa0PS4\x9f`TIlPU\x15\xd2\xe0V)NPV\xf5\xc2\xf0X\x13\xca`Xդ\xf0Y\xf3\xac`Z\xb5\x86\xf0[ӎ`\\\x9dC\xe0]\xb3" + + "p`^}%\xe0_\x9c\x8c\xe0`]\a\xe0a|n\xe0b<\xe9\xe0c\\P\xe0d&\x06`e<2\xe0f\x05\xe8`g\x1c\x14\xe0g\xe5\xca`h\xfb\xf6\xe0iŬ`j\xe5\x13`k\xa5" + + "\x8e`l\xc4\xf5`m\x8e\xaa\xe0n\xa4\xd7`on\x8c\xe0p\x84\xb9`qNn\xe0rd\x9b`s.P\xe0tD}`u\x0e2\xe0v-\x99\xe0v\xee\x14\xe0x\r{\xe0x\xd71`y\xed" + + "]\xe0z\xb7\x13`{\xcd?\xe0|\x96\xf5`}\xad!\xe0~v\xd7`\u007f\x96>`\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x02\x01\x05\x01\x05\x01\x05\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00 P\x00\x00" + + "\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x01\r\x00\x00\x1c \x00\x11\x00\x00\x1c \x00\tLMT\x00EEST\x00EET\x00IDT\x00IST\x00\x00\x00\x00\x00\x00\x01TZi" + + "f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x94\x00\x00\x00\x06\x00\x00\x00\x15\xff\xff\xff\xff}\xbdJ\xb0\xff\xff\xff\xff\xc8Y\xb2\xe0\xff\xff\xff" + + "\xff\xcc\xe5\xc1P\xff\xff\xff\xffͬ\xfe\x00\xff\xff\xff\xff\xce\xc6\xf4\xd0\xff\xff\xff\xffϏf\xe0\xff\xff\xff\xffЩy\xd0\xff\xff\xff\xffф`\xe0\xff\xff\xff\xffҊ\xc9p\xff\xff\xff\xff\xd3e\xb0" + + "\x80\xff\xff\xff\xff\xd4k\xe0\xd0\xff\xff\xff\xff\xe86c`\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea\v\xb9`\xff\xff\xff\xff\xea\xd5`\xd0\xff\xff\xff\xff\xeb\xec\xfa\xf0\xff\xff\xff\xff\xec\xb5m\x00\xff\xff\xff" + + "\xff\xed\xcf\u007f\xf0\xff\xff\xff\xff\xee\x97\xf2\x00\xff\xff\xff\xffﰳp\xff\xff\xff\xff\xf0y%\x80\xff\xff\xff\xff\xf1\x91\xe6\xf0\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3s\x1ap\xff\xff\xff\xff\xf4;\x8c" + + "\x80\xff\xff\xff\xff\xf5U\x9fp\xff\xff\xff\xff\xf6\x1e\x11\x80\xff\xff\xff\xff\xf76\xd2\xf0\xff\xff\xff\xff\xf7\xffE\x00\xff\xff\xff\xff\xf9\x18\x06p\xff\xff\xff\xff\xf9\xe1\xca\x00\xff\xff\xff\xff\xfa\xf99\xf0\xff\xff\xff" + + "\xff\xfb'BP\x00\x00\x00\x00\b|\x8b\xe0\x00\x00\x00\x00\b\xfd\xb0\xd0\x00\x00\x00\x00\t\xf6\xea`\x00\x00\x00\x00\n\xa63\xd0\x00\x00\x00\x00\x13\xe8\xaa\xe0\x00\x00\x00\x00\x14 \t\xe0\x00\x00\x00\x00\x1a\xf9t" + + "\xe0\x00\x00\x00\x00\x1b\x8d\x1c\xe0\x00\x00\x00\x00\x1c\xbe\xf8\xe0\x00\x00\x00\x00\x1d\x89\xf1\xd0\x00\x00\x00\x00\x1e\xcc\xff`\x00\x00\x00\x00\x1f`\x99P\x00\x00\x00\x00 \x82\xb1`\x00\x00\x00\x00!I\xb5\xd0\x00\x00\x00" + + "\x00\"^\x9e\xe0\x00\x00\x00\x00# ]P\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00&\xd6\xe6\xd0\x00\x00\x00\x00'\xeb\xcf\xe0\x00\x00\x00\x00(\xc0\x03" + + "P\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xa9\x1f\xd0\x00\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00,\x89\x01\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00._\xa9P\x00\x00\x00\x00/{)\xe0\x00\x00\x00" + + "\x000H\xc5\xd0\x00\x00\x00\x000\xe7\a\xe0\x00\x00\x00\x001dF`\x00\x00\x00\x002A\xc2`\x00\x00\x00\x003D(`\x00\x00\x00\x004!\xa4`\x00\x00\x00\x005$\n`\x00\x00\x00\x006\x01\x86" + + "`\x00\x00\x00\x007\x16a`\x00\x00\x00\x008\x06DP\x00\x00\x00\x008\xff}\xe0\x00\x00\x00\x009\xef`\xd0\x00\x00\x00\x00:\xdf_\xe0\x00\x00\x00\x00;\xcfB\xd0\x00\x00\x00\x00<\xbfA\xe0\x00\x00\x00" + + "\x00=\xaf$\xd0\x00\x00\x00\x00>\x9f#\xe0\x00\x00\x00\x00?\x8f\x06\xd0\x00\x00\x00\x00@\u007f\x05\xe0\x00\x00\x00\x00A\\\x81\xe0\x00\x00\x00\x00B^\xe7\xe0\x00\x00\x00\x00CA\xb7\xf0\x00\x00\x00\x00D-\xa6" + + "`\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00F\x0e\xd9\xe0\x00\x00\x00\x00F\xe8op\x00\x00\x00\x00G\xec\x18\xe0\x00\x00\x00\x00H\xb7\x11\xd0\x00\x00\x00\x00I\xcb\xfa\xe0\x00\x00\x00\x00J\xa0<`\x00\x00\x00" + + "\x00K\xad.\x9c\x00\x00\x00\x00La\xbd\xd0\x00\x00\x00\x00M\x94\xf9\x9c\x00\x00\x00\x00N5\xc2P\x00\x00\x00\x00Ot\xdb`\x00\x00\x00\x00P[\x91\xe0\x00\x00\x00\x00QT\xbd`\x00\x00\x00\x00RD\xa0" + + "P\x00\x00\x00\x00S4\x9f`\x00\x00\x00\x00TIlP\x00\x00\x00\x00U\x15\xd2\xe0\x00\x00\x00\x00V)NP\x00\x00\x00\x00V\xf5\xc2\xf0\x00\x00\x00\x00X\x13\xca`\x00\x00\x00\x00Xդ\xf0\x00\x00\x00" + + "\x00Y\xf3\xac`\x00\x00\x00\x00Z\xb5\x86\xf0\x00\x00\x00\x00[ӎ`\x00\x00\x00\x00\\\x9dC\xe0\x00\x00\x00\x00]\xb3p`\x00\x00\x00\x00^}%\xe0\x00\x00\x00\x00_\x9c\x8c\xe0\x00\x00\x00\x00`]\a" + + "\xe0\x00\x00\x00\x00a|n\xe0\x00\x00\x00\x00b<\xe9\xe0\x00\x00\x00\x00c\\P\xe0\x00\x00\x00\x00d&\x06`\x00\x00\x00\x00e<2\xe0\x00\x00\x00\x00f\x05\xe8`\x00\x00\x00\x00g\x1c\x14\xe0\x00\x00\x00" + + "\x00g\xe5\xca`\x00\x00\x00\x00h\xfb\xf6\xe0\x00\x00\x00\x00iŬ`\x00\x00\x00\x00j\xe5\x13`\x00\x00\x00\x00k\xa5\x8e`\x00\x00\x00\x00l\xc4\xf5`\x00\x00\x00\x00m\x8e\xaa\xe0\x00\x00\x00\x00n\xa4\xd7" + + "`\x00\x00\x00\x00on\x8c\xe0\x00\x00\x00\x00p\x84\xb9`\x00\x00\x00\x00qNn\xe0\x00\x00\x00\x00rd\x9b`\x00\x00\x00\x00s.P\xe0\x00\x00\x00\x00tD}`\x00\x00\x00\x00u\x0e2\xe0\x00\x00\x00" + + "\x00v-\x99\xe0\x00\x00\x00\x00v\xee\x14\xe0\x00\x00\x00\x00x\r{\xe0\x00\x00\x00\x00x\xd71`\x00\x00\x00\x00y\xed]\xe0\x00\x00\x00\x00z\xb7\x13`\x00\x00\x00\x00{\xcd?\xe0\x00\x00\x00\x00|\x96\xf5" + + "`\x00\x00\x00\x00}\xad!\xe0\x00\x00\x00\x00~v\xd7`\x00\x00\x00\x00\u007f\x96>`\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x02\x01\x05\x01\x05\x01\x05\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00 P\x00\x00\x00" + + "\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x01\r\x00\x00\x1c \x00\x11\x00\x00\x1c \x00\tLMT\x00EEST\x00EET\x00IDT\x00IST\x00\x00\x00\x00\x00\x00\x01\nEET" + + "-2EEST,M3.5.5/0,M10.5.6/1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfd\xfc)\xc9A\x02\x00\x00A\x02\x00\x00\x0e\x00\x1c\x00Asia" + + "/SamarkandUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\a\x00\x00\x00\x10\xaa\x19\x857\xb5\xa3\xfd@\x15'\x8b\xb0\x16\x18\xc0 \x17\b\xb1 \x17\xf9\xf3\xa0\x18\xe9\xf2\xb0\x19\xdb' \x1a\xccw\xb0\x1b\xbc" + + "\x84\xd0\x1c\xacu\xd0\x1d\x9cf\xd0\x1e\x8cW\xd0\x1f|H\xd0 l9\xd0!\\*\xd0\"L\x1b\xd0#<\f\xd0$+\xfd\xd0%\x1b\xee\xd0&\v\xdf\xd0'\x05\vP'\xf4\xfcP(\xe4\xedP\u007f\xff" + + "\xff\xff\x01\x02\x03\x04\x03\x02\x03\x02\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x05\x00\x00>\xc9\x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00T`\x00\f\x00\x00F" + + "P\x00\b\x00\x00T`\x01\fLMT\x00+04\x00+05\x00+06\x00\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a" + + "\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\a\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x857\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00" + + "\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0" + + "\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00" + + "&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x04\x03\x02\x03\x02\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x05\x00\x00>\xc9\x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00T`\x00\f\x00\x00FP\x00\b\x00\x00T`\x01\fLMT\x00+04\x00+05\x00+06\x00\x00" + + "\x00\x00\x00\x00\x01\x01\n<+05>-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc7\x1a\x03B\xf9\x02\x00\x00\xf9\x02\x00\x00\v\x00\x1c\x00Asia/TaipeiUT\t\x00" + + "\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)" + + "\x00\x00\x00\x05\x00\x00\x00\x10\x80\x00\x00\x00\xc3UI\x80\xd2TY\x80Ӌ{\x80\xd4B\xad\xf0\xd5E\"\x00\xd6L\xbf\xf0\xd7<\xbf\x00\xd8\x06fp\xd9\x1d\xf2\x80\xd9\xe7\x99\xf0\xda\xff&\x00\xdb\xc8\xcdp" + + "\xdc\xe0Y\x80ݪ\x00\xf0\xders\x00ߵdp\xe0|\x85\x00ᖗ\xf0\xe2]\xb8\x80\xe3w\xcbp\xe4>\xec\x00\xe50 p\xe6!q\x00\xe7\x12\xa5p\xe8\x02\xa4\x80\xe8\xf3\xd8\xf0\xe9\xe3\xd8\x00" + + "\xea\xd5\fp\xeb\xc5\v\x80\xec\xb6?\xf0\xed\xf7\xfc\x00\xee\x98\xc4\xf0\xef\xd9/\x80\xf0y\xf8p\a\xfcV\x00\b\xed\x8ap\t݉\x80\nν\xf0\x11ۡ\x80\x12T\xddp\x01\x02\x01\x03\x01\x03\x01\x03" + + "\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x00\x00q\xe8\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x00\b\x00\x00~\x90\x01\f\x00\x00p" + + "\x80\x00\x04LMT\x00CST\x00JST\x00CDT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00\x05\x00" + + "\x00\x00\x10\xff\xff\xff\xfft\xce\xf0\x18\xff\xff\xff\xff\xc3UI\x80\xff\xff\xff\xff\xd2TY\x80\xff\xff\xff\xffӋ{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff" + + "\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9\xe7\x99\xf0\xff\xff\xff\xff\xda\xff&\x00\xff\xff\xff\xff\xdb\xc8\xcdp\xff\xff\xff\xff\xdc\xe0Y\x80\xff\xff\xff\xff\xdd" + + "\xaa\x00\xf0\xff\xff\xff\xff\xders\x00\xff\xff\xff\xffߵdp\xff\xff\xff\xff\xe0|\x85\x00\xff\xff\xff\xffᖗ\xf0\xff\xff\xff\xff\xe2]\xb8\x80\xff\xff\xff\xff\xe3w\xcbp\xff\xff\xff\xff\xe4>\xec\x00\xff" + + "\xff\xff\xff\xe50 p\xff\xff\xff\xff\xe6!q\x00\xff\xff\xff\xff\xe7\x12\xa5p\xff\xff\xff\xff\xe8\x02\xa4\x80\xff\xff\xff\xff\xe8\xf3\xd8\xf0\xff\xff\xff\xff\xe9\xe3\xd8\x00\xff\xff\xff\xff\xea\xd5\fp\xff\xff\xff\xff\xeb" + + "\xc5\v\x80\xff\xff\xff\xff\xec\xb6?\xf0\xff\xff\xff\xff\xed\xf7\xfc\x00\xff\xff\xff\xff\xee\x98\xc4\xf0\xff\xff\xff\xff\xef\xd9/\x80\xff\xff\xff\xff\xf0y\xf8p\x00\x00\x00\x00\a\xfcV\x00\x00\x00\x00\x00\b\xed\x8ap\x00" + + "\x00\x00\x00\t݉\x80\x00\x00\x00\x00\nν\xf0\x00\x00\x00\x00\x11ۡ\x80\x00\x00\x00\x00\x12T\xddp\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01" + + "\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x00\x00q\xe8\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x00\b\x00\x00~\x90\x01\f\x00\x00p\x80\x00\x04LMT\x00CST\x00JST\x00CDT\x00\nC" + + "ST-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xee\xbf\xd8\xecO\x02\x00\x00O\x02\x00\x00\r\x00\x1c\x00Asia/TashkentUT\t\x00\x03nӧ^nӧ" + + "^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\b\x00\x00\x00\x10" + + "\xaa\x19\x83\t\xb5\xa3\xef0\x15'}\xa0\x16\x18\xb2\x10\x17\b\xb1 \x17\xf9\xe5\x90\x18\xe9\xe4\xa0\x19\xdb\x19\x10\x1a\xcci\xa0\x1b\xbcv\xc0\x1c\xacg\xc0\x1d\x9cX\xc0\x1e\x8cI\xc0\x1f|:\xc0 l+\xc0" + + "!\\\x1c\xc0\"L\r\xc0#;\xfe\xc0$+\xef\xc0%\x1b\xe0\xc0&\v\xd1\xc0'\x04\xfd@'\xf4\xee@(\xe4\xedP\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x06\a\a\x00\x00@\xf7\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\b\x00\x00T`\x00\f\x00\x00T`\x00\f\x00\x00bp\x01\b\x00\x00T`\x01\f\x00\x00FP\x00\x04LMT\x00+05" + + "\x00+07\x00+06\x00\x00\x00\x00\x00\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\b\x00\x00\x00" + + "\x10\xff\xff\xff\xff\xaa\x19\x83\t\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00\x00\x00\x00\x18\xe9\xe4\xa0\x00\x00\x00" + + "\x00\x19\xdb\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f|:\xc0\x00\x00\x00\x00 l+" + + "\xc0\x00\x00\x00\x00!\\\x1c\xc0\x00\x00\x00\x00\"L\r\xc0\x00\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\v\xd1\xc0\x00\x00\x00\x00'\x04\xfd@\x00\x00\x00" + + "\x00'\xf4\xee@\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\a\x00\x00@\xf7\x00\x00\x00\x00FP\x00\x04\x00\x00" + + "bp\x01\b\x00\x00T`\x00\f\x00\x00T`\x00\f\x00\x00bp\x01\b\x00\x00T`\x01\f\x00\x00FP\x00\x04LMT\x00+05\x00+07\x00+06\x00\x00\x00\x00\x00\x01\x01\x01\x01\n<" + + "+05>-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe5.\xe4\xfc\xdb\x04\x00\x00\xdb\x04\x00\x00\x12\x00\x1c\x00Asia/YekaterinburgUT\t\x00\x03" + + "nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00C\x00" + + "\x00\x00\f\x00\x00\x00\x14\x9b_\t'\xa1\x12\xb1\xff\xb5\xa3\xfd@\x15'\x8b\xb0\x16\x18\xc0 \x17\b\xbf0\x17\xf9\xf3\xa0\x18\xe9\xf2\xb0\x19\xdb' \x1a\xccw\xb0\x1b\xbc\x84\xd0\x1c\xacu\xd0\x1d\x9cf\xd0\x1e" + + "\x8cW\xd0\x1f|H\xd0 l9\xd0!\\*\xd0\"L\x1b\xd0#<\f\xd0$+\xfd\xd0%\x1b\xee\xd0&\v\xdf\xd0'\x05\vP'\xf4\xfcP(\xe4\xfb`)x\xa3`)\xd4\xdeP*\xc4\xcfP+" + + "\xb4\xc0P,\xa4\xb1P-\x94\xa2P.\x84\x93P/t\x84P0duP1]\xa0\xd02r{\xd03=\x82\xd04R]\xd05\x1dd\xd062?\xd06\xfdF\xd08\x1b\\P8\xdd(\xd09" + + "\xfb>P:\xbd\n\xd0;\xdb P<\xa6'P=\xbb\x02P>\x86\tP?\x9a\xe4P@e\xebPA\x84\x00\xd0BE\xcdPCc\xe2\xd0D%\xafPEC\xc4\xd0F\x05\x91PG#\xa6\xd0G" + + "\xee\xad\xd0I\x03\x88\xd0IΏ\xd0J\xe3j\xd0K\xaeq\xd0L̇PM\x8eS\xd0TL\x01@\u007f\xff\xff\xff\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\b" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\t\x05\x05\x00\x008\xd9\x00\x00\x00\x004\xc1\x00\x04\x00\x008@\x00\b" + + "\x00\x00T`\x01\f\x00\x00FP\x00\x10\x00\x00FP\x00\x10\x00\x00T`\x01\f\x00\x00FP\x01\x10\x00\x008@\x00\b\x00\x00T`\x00\f\x00\x00T`\x01\f\x00\x00FP\x00\x10LMT\x00PM" + + "T\x00+04\x00+06\x00+05\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00" + + "\x00C\x00\x00\x00\f\x00\x00\x00\x14\xff\xff\xff\xff\x9b_\t'\xff\xff\xff\xff\xa1\x12\xb1\xff\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xbf0\x00\x00" + + "\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8c" + + "W\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00" + + "\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4" + + "\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84P\x00\x00\x00\x000duP\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r{\xd0\x00\x00" + + "\x00\x003=\x82\xd0\x00\x00\x00\x004R]\xd0\x00\x00\x00\x005\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00\x006\xfdF\xd0\x00\x00\x00\x008\x1b\\P\x00\x00\x00\x008\xdd(\xd0\x00\x00\x00\x009\xfb" + + ">P\x00\x00\x00\x00:\xbd\n\xd0\x00\x00\x00\x00;\xdb P\x00\x00\x00\x00<\xa6'P\x00\x00\x00\x00=\xbb\x02P\x00\x00\x00\x00>\x86\tP\x00\x00\x00\x00?\x9a\xe4P\x00\x00\x00\x00@e\xebP\x00\x00" + + "\x00\x00A\x84\x00\xd0\x00\x00\x00\x00BE\xcdP\x00\x00\x00\x00Cc\xe2\xd0\x00\x00\x00\x00D%\xafP\x00\x00\x00\x00EC\xc4\xd0\x00\x00\x00\x00F\x05\x91P\x00\x00\x00\x00G#\xa6\xd0\x00\x00\x00\x00G\xee" + + "\xad\xd0\x00\x00\x00\x00I\x03\x88\xd0\x00\x00\x00\x00IΏ\xd0\x00\x00\x00\x00J\xe3j\xd0\x00\x00\x00\x00K\xaeq\xd0\x00\x00\x00\x00L̇P\x00\x00\x00\x00M\x8eS\xd0\x00\x00\x00\x00TL\x01@\x00\x00" + + "\x00\x00\u007f\xff\xff\xff\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\b\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\t\x05\x05\x00\x008\xd9\x00\x00\x00\x004\xc1\x00\x04\x00\x008@\x00\b\x00\x00T`\x01\f\x00\x00FP\x00\x10\x00\x00FP\x00\x10\x00\x00T`\x01\f\x00\x00FP\x01" + + "\x10\x00\x008@\x00\b\x00\x00T`\x00\f\x00\x00T`\x01\f\x00\x00FP\x00\x10LMT\x00PMT\x00+04\x00+06\x00+05\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\n<+" + + "05>-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP9\xf3\x91\x9b\xcb\x04\x00\x00\xcb\x04\x00\x00\n\x00\x1c\x00Asia/MacauUT\t\x00\x03nӧ^nӧ^u" + + "x\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00G\x00\x00\x00\a\x00\x00\x00\x14\x85i" + + "[\x8e\xcbGu\xf0\xcb\xf2\xca\xe0\xcc\xfb\xbaP\xcd\xd3\xfe`Ν\xa5\xd0\xd2azp\xd3x\xf8p\xd4B\xad\xf0\xd5K\xabp\xd6tL\xf0\xd7?S\xf0\xd8/D\xf0\xd8\xf8\xfap\xda\r\xd5p\xda\xd8" + + "\xdcp\xdb\xed\xb7pܸ\xbep\xdd\xce\xea\xf0ޡ\xda\xf0߶\xb5\xf0\xe0\x81\xbc\xf0ᖗ\xf0\xe2O)\xf0\xe3vy\xf0\xe4/\v\xf0\xe5_\x96p\xe6\x0e\xed\xf0\xe7?\xa9\xa8\xe7\xf8I\xb8\xe9\x1f" + + "\x8b\xa8\xe9\xd8+\xb8\xea\xffm\xa8\xeb\xb8\r\xb8\xec\xdfO\xa8\xed\x97\xef\xb8\xee\xc8l(\xefwѸ\xf0\xa8N(\xf1W\xb3\xb8\xf2\x880(\xf3@\xd08\xf4h\x12(\xf5 \xb28\xf6G\xf4(\xf7%" + + "~8\xf8\x15S\x18\xf9\x05`8\xf9\xf55\x18\xfa\xe5B8\xfb\xde_\xa8\xfc\xce^\xb8\xfd\xbeA\xa8\xfe\xae@\xb8\xff\x9e#\xa8\x00\x8e\"\xb8\x01~\x05\xa8\x02n\x04\xb8\x03]\xe7\xa8\x04M\xe6\xb8\x05G" + + "\x04(\x067\x038\a&\xe6(\a\x83=8\t\x06\xc8(\t\xf6\xc78\n\xe6\xaa(\v֩8\fƌ(\x11\x9b98\x12ol\xa8\x01\x03\x02\x03\x02\x03\x01\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x00\x00jr\x00\x00\x00" + + "\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\f\x00\x00~\x90\x01\x10\x00\x00p\x80\x00\x04\x00\x00~\x90\x01\x10LMT\x00CST\x00+10\x00+09\x00CDT\x00\x00\x00\x00\x00\x01" + + "\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00G\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xff\x85i[\x8e\xff\xff\xff\xff\xcbG" + + "u\xf0\xff\xff\xff\xff\xcb\xf2\xca\xe0\xff\xff\xff\xff\xcc\xfb\xbaP\xff\xff\xff\xff\xcd\xd3\xfe`\xff\xff\xff\xffΝ\xa5\xd0\xff\xff\xff\xff\xd2azp\xff\xff\xff\xff\xd3x\xf8p\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff" + + "\xff\xff\xd5K\xabp\xff\xff\xff\xff\xd6tL\xf0\xff\xff\xff\xff\xd7?S\xf0\xff\xff\xff\xff\xd8/D\xf0\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xda\r\xd5p\xff\xff\xff\xff\xda\xd8\xdcp\xff\xff\xff\xff\xdb\xed" + + "\xb7p\xff\xff\xff\xffܸ\xbep\xff\xff\xff\xff\xdd\xce\xea\xf0\xff\xff\xff\xffޡ\xda\xf0\xff\xff\xff\xff߶\xb5\xf0\xff\xff\xff\xff\xe0\x81\xbc\xf0\xff\xff\xff\xffᖗ\xf0\xff\xff\xff\xff\xe2O)\xf0\xff\xff" + + "\xff\xff\xe3vy\xf0\xff\xff\xff\xff\xe4/\v\xf0\xff\xff\xff\xff\xe5_\x96p\xff\xff\xff\xff\xe6\x0e\xed\xf0\xff\xff\xff\xff\xe7?\xa9\xa8\xff\xff\xff\xff\xe7\xf8I\xb8\xff\xff\xff\xff\xe9\x1f\x8b\xa8\xff\xff\xff\xff\xe9\xd8" + + "+\xb8\xff\xff\xff\xff\xea\xffm\xa8\xff\xff\xff\xff\xeb\xb8\r\xb8\xff\xff\xff\xff\xec\xdfO\xa8\xff\xff\xff\xff\xed\x97\xef\xb8\xff\xff\xff\xff\xee\xc8l(\xff\xff\xff\xff\xefwѸ\xff\xff\xff\xff\xf0\xa8N(\xff\xff" + + "\xff\xff\xf1W\xb3\xb8\xff\xff\xff\xff\xf2\x880(\xff\xff\xff\xff\xf3@\xd08\xff\xff\xff\xff\xf4h\x12(\xff\xff\xff\xff\xf5 \xb28\xff\xff\xff\xff\xf6G\xf4(\xff\xff\xff\xff\xf7%~8\xff\xff\xff\xff\xf8\x15" + + "S\x18\xff\xff\xff\xff\xf9\x05`8\xff\xff\xff\xff\xf9\xf55\x18\xff\xff\xff\xff\xfa\xe5B8\xff\xff\xff\xff\xfb\xde_\xa8\xff\xff\xff\xff\xfc\xce^\xb8\xff\xff\xff\xff\xfd\xbeA\xa8\xff\xff\xff\xff\xfe\xae@\xb8\xff\xff" + + "\xff\xff\xff\x9e#\xa8\x00\x00\x00\x00\x00\x8e\"\xb8\x00\x00\x00\x00\x01~\x05\xa8\x00\x00\x00\x00\x02n\x04\xb8\x00\x00\x00\x00\x03]\xe7\xa8\x00\x00\x00\x00\x04M\xe6\xb8\x00\x00\x00\x00\x05G\x04(\x00\x00\x00\x00\x067" + + "\x038\x00\x00\x00\x00\a&\xe6(\x00\x00\x00\x00\a\x83=8\x00\x00\x00\x00\t\x06\xc8(\x00\x00\x00\x00\t\xf6\xc78\x00\x00\x00\x00\n\xe6\xaa(\x00\x00\x00\x00\v֩8\x00\x00\x00\x00\fƌ(\x00\x00" + + "\x00\x00\x11\x9b98\x00\x00\x00\x00\x12ol\xa8\x01\x03\x02\x03\x02\x03\x01\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06" + + "\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x00\x00jr\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\f\x00\x00~\x90\x01\x10\x00\x00p\x80\x00" + + "\x04\x00\x00~\x90\x01\x10LMT\x00CST\x00+10\x00+09\x00CDT\x00\x00\x00\x00\x00\x01\x01\x00\nCST-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\n:\xf3_\x01" + + "\x04\x00\x00\x01\x04\x00\x00\x0e\x00\x1c\x00Asia/QyzylordaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00\v\x00\x00\x00\x10\xaa\x19\x86\xa0\xb5\xa3\xfd@\x15'\x8b\xb0\x16\x18\xc0 \x17\b\xb1 \x17\xf9\xf3" + + "\xa0\x18\xe9\xf2\xb0\x19\xdb' \x1a\xccw\xb0\x1b\xbc\x84\xd0\x1c\xacu\xd0\x1d\x9cf\xd0\x1e\x8cW\xd0\x1f|H\xd0 l9\xd0!\\*\xd0\"L\x1b\xd0#<\f\xd0$+\xfd\xd0%\x1b\xee\xd0&\v\xdf" + + "\xd0'\x05\vP'\xf4\xfcP(\xe4\xfb`)x\x95P)\xd4\xd0@*\xc4\xcfP+\xb4\xc0P,\xa4\xb1P-\x94\xa2P.\x84\x93P/t\x84P0duP1]\xa0\xd02r{\xd03=\x82" + + "\xd04R]\xd05\x1dd\xd062?\xd06\xfdF\xd08\x1b\\P8\xdd(\xd09\xfb>P:\xbd\n\xd0;\xdb P<\xa6'P=\xbb\x02P>\x86\tP?\x9a\xe4P@e\xebPA\x84\x00" + + "\xd0\\\x1bؠ\u007f\xff\xff\xff\x01\x02\x03\x04\x03\x02\x03\x02\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\x05\b\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\b" + + "\x02\x02\x00\x00=`\x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00T`\x00\f\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00FP\x01\b\x00\x00T`\x00\f\x00\x00T`" + + "\x01\f\x00\x00FP\x00\bLMT\x00+04\x00+05\x00+06\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\v\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00\v\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x86\xa0\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xb1 \x00" + + "\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e" + + "\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00" + + "\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\x95P\x00\x00\x00\x00)\xd4\xd0@\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+" + + "\xb4\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84P\x00\x00\x00\x000duP\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r{\xd0\x00" + + "\x00\x00\x003=\x82\xd0\x00\x00\x00\x004R]\xd0\x00\x00\x00\x005\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00\x006\xfdF\xd0\x00\x00\x00\x008\x1b\\P\x00\x00\x00\x008\xdd(\xd0\x00\x00\x00\x009" + + "\xfb>P\x00\x00\x00\x00:\xbd\n\xd0\x00\x00\x00\x00;\xdb P\x00\x00\x00\x00<\xa6'P\x00\x00\x00\x00=\xbb\x02P\x00\x00\x00\x00>\x86\tP\x00\x00\x00\x00?\x9a\xe4P\x00\x00\x00\x00@e\xebP\x00" + + "\x00\x00\x00A\x84\x00\xd0\x00\x00\x00\x00\\\x1bؠ\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x04\x03\x02\x03\x02\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\x05\b\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\b\x02\x02\x00\x00=`\x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00T`\x00\f\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00" + + "FP\x01\b\x00\x00T`\x00\f\x00\x00T`\x01\f\x00\x00FP\x00\bLMT\x00+04\x00+05\x00+06\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x00\n<+05>-5\nPK" + + "\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP9\xf3\x91\x9b\xcb\x04\x00\x00\xcb\x04\x00\x00\n\x00\x1c\x00Asia/MacaoUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00" + + "\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00G\x00\x00\x00\a\x00\x00\x00\x14\x85i[\x8e\xcbGu\xf0\xcb\xf2" + + "\xca\xe0\xcc\xfb\xbaP\xcd\xd3\xfe`Ν\xa5\xd0\xd2azp\xd3x\xf8p\xd4B\xad\xf0\xd5K\xabp\xd6tL\xf0\xd7?S\xf0\xd8/D\xf0\xd8\xf8\xfap\xda\r\xd5p\xda\xd8\xdcp\xdb\xed\xb7pܸ" + + "\xbep\xdd\xce\xea\xf0ޡ\xda\xf0߶\xb5\xf0\xe0\x81\xbc\xf0ᖗ\xf0\xe2O)\xf0\xe3vy\xf0\xe4/\v\xf0\xe5_\x96p\xe6\x0e\xed\xf0\xe7?\xa9\xa8\xe7\xf8I\xb8\xe9\x1f\x8b\xa8\xe9\xd8+\xb8\xea\xff" + + "m\xa8\xeb\xb8\r\xb8\xec\xdfO\xa8\xed\x97\xef\xb8\xee\xc8l(\xefwѸ\xf0\xa8N(\xf1W\xb3\xb8\xf2\x880(\xf3@\xd08\xf4h\x12(\xf5 \xb28\xf6G\xf4(\xf7%~8\xf8\x15S\x18\xf9\x05" + + "`8\xf9\xf55\x18\xfa\xe5B8\xfb\xde_\xa8\xfc\xce^\xb8\xfd\xbeA\xa8\xfe\xae@\xb8\xff\x9e#\xa8\x00\x8e\"\xb8\x01~\x05\xa8\x02n\x04\xb8\x03]\xe7\xa8\x04M\xe6\xb8\x05G\x04(\x067\x038\a&" + + "\xe6(\a\x83=8\t\x06\xc8(\t\xf6\xc78\n\xe6\xaa(\v֩8\fƌ(\x11\x9b98\x12ol\xa8\x01\x03\x02\x03\x02\x03\x01\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x00\x00jr\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c" + + "\xa0\x01\b\x00\x00~\x90\x00\f\x00\x00~\x90\x01\x10\x00\x00p\x80\x00\x04\x00\x00~\x90\x01\x10LMT\x00CST\x00+10\x00+09\x00CDT\x00\x00\x00\x00\x00\x01\x01\x00TZif2\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00G\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xff\x85i[\x8e\xff\xff\xff\xff\xcbGu\xf0\xff\xff\xff\xff\xcb\xf2" + + "\xca\xe0\xff\xff\xff\xff\xcc\xfb\xbaP\xff\xff\xff\xff\xcd\xd3\xfe`\xff\xff\xff\xffΝ\xa5\xd0\xff\xff\xff\xff\xd2azp\xff\xff\xff\xff\xd3x\xf8p\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5K\xabp\xff\xff" + + "\xff\xff\xd6tL\xf0\xff\xff\xff\xff\xd7?S\xf0\xff\xff\xff\xff\xd8/D\xf0\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xda\r\xd5p\xff\xff\xff\xff\xda\xd8\xdcp\xff\xff\xff\xff\xdb\xed\xb7p\xff\xff\xff\xffܸ" + + "\xbep\xff\xff\xff\xff\xdd\xce\xea\xf0\xff\xff\xff\xffޡ\xda\xf0\xff\xff\xff\xff߶\xb5\xf0\xff\xff\xff\xff\xe0\x81\xbc\xf0\xff\xff\xff\xffᖗ\xf0\xff\xff\xff\xff\xe2O)\xf0\xff\xff\xff\xff\xe3vy\xf0\xff\xff" + + "\xff\xff\xe4/\v\xf0\xff\xff\xff\xff\xe5_\x96p\xff\xff\xff\xff\xe6\x0e\xed\xf0\xff\xff\xff\xff\xe7?\xa9\xa8\xff\xff\xff\xff\xe7\xf8I\xb8\xff\xff\xff\xff\xe9\x1f\x8b\xa8\xff\xff\xff\xff\xe9\xd8+\xb8\xff\xff\xff\xff\xea\xff" + + "m\xa8\xff\xff\xff\xff\xeb\xb8\r\xb8\xff\xff\xff\xff\xec\xdfO\xa8\xff\xff\xff\xff\xed\x97\xef\xb8\xff\xff\xff\xff\xee\xc8l(\xff\xff\xff\xff\xefwѸ\xff\xff\xff\xff\xf0\xa8N(\xff\xff\xff\xff\xf1W\xb3\xb8\xff\xff" + + "\xff\xff\xf2\x880(\xff\xff\xff\xff\xf3@\xd08\xff\xff\xff\xff\xf4h\x12(\xff\xff\xff\xff\xf5 \xb28\xff\xff\xff\xff\xf6G\xf4(\xff\xff\xff\xff\xf7%~8\xff\xff\xff\xff\xf8\x15S\x18\xff\xff\xff\xff\xf9\x05" + + "`8\xff\xff\xff\xff\xf9\xf55\x18\xff\xff\xff\xff\xfa\xe5B8\xff\xff\xff\xff\xfb\xde_\xa8\xff\xff\xff\xff\xfc\xce^\xb8\xff\xff\xff\xff\xfd\xbeA\xa8\xff\xff\xff\xff\xfe\xae@\xb8\xff\xff\xff\xff\xff\x9e#\xa8\x00\x00" + + "\x00\x00\x00\x8e\"\xb8\x00\x00\x00\x00\x01~\x05\xa8\x00\x00\x00\x00\x02n\x04\xb8\x00\x00\x00\x00\x03]\xe7\xa8\x00\x00\x00\x00\x04M\xe6\xb8\x00\x00\x00\x00\x05G\x04(\x00\x00\x00\x00\x067\x038\x00\x00\x00\x00\a&" + + "\xe6(\x00\x00\x00\x00\a\x83=8\x00\x00\x00\x00\t\x06\xc8(\x00\x00\x00\x00\t\xf6\xc78\x00\x00\x00\x00\n\xe6\xaa(\x00\x00\x00\x00\v֩8\x00\x00\x00\x00\fƌ(\x00\x00\x00\x00\x11\x9b98\x00\x00" + + "\x00\x00\x12ol\xa8\x01\x03\x02\x03\x02\x03\x01\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06" + + "\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x00\x00jr\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\f\x00\x00~\x90\x01\x10\x00\x00p\x80\x00\x04\x00\x00~\x90\x01\x10L" + + "MT\x00CST\x00+10\x00+09\x00CDT\x00\x00\x00\x00\x00\x01\x01\x00\nCST-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\fH\xe6\r5\x01\x00\x005\x01\x00\x00\n" + + "\x00\x1c\x00Asia/TokyoUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x04\x00\x00\x00\f\x80\x00\x00\x00\xd7>\x02p\xd7\xedY\xf0\xd8\xf8\xfap\xd9\xcd;\xf0\xdb\a\x00\xf0ۭ\x1d\xf0\xdc\xe6\xe2\xf0\u074c\xff" + + "\xf0\x03\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x83\x03\x00\x00\x00\x00\x8c\xa0\x01\x04\x00\x00~\x90\x00\b\x00\x00~\x90\x00\bLMT\x00JDT\x00JST\x00\x00\x00\x00\x01\x00\x00\x00\x01TZif2\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xffe¤p\xff\xff\xff\xff\xd7>\x02p\xff\xff\xff\xff\xd7\xed" + + "Y\xf0\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xd9\xcd;\xf0\xff\xff\xff\xff\xdb\a\x00\xf0\xff\xff\xff\xffۭ\x1d\xf0\xff\xff\xff\xff\xdc\xe6\xe2\xf0\xff\xff\xff\xff\u074c\xff\xf0\x03\x01\x02\x01\x02\x01\x02\x01\x02\x00" + + "\x00\x83\x03\x00\x00\x00\x00\x8c\xa0\x01\x04\x00\x00~\x90\x00\b\x00\x00~\x90\x00\bLMT\x00JDT\x00JST\x00\x00\x00\x00\x01\x00\x00\x00\x01\nJST-9\nPK\x03\x04\n\x00\x00\x00\x00\x00" + + "\xf5F\x9cP\xc9 \xb3\x05\xcb\x04\x00\x00\xcb\x04\x00\x00\t\x00\x1c\x00Asia/BakuUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZi" + + "f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\n\x00\x00\x00\x10\xaa\x19\x95D\xe7\xda\fP\x15'\x99\xc0\x16\x18\xce0\x17\b\xcd" + + "@\x17\xfa\x01\xb0\x18\xea\x00\xc0\x19\xdb50\x1a̅\xc0\x1b\xbc\x92\xe0\x1c\xac\x83\xe0\x1d\x9ct\xe0\x1e\x8ce\xe0\x1f|V\xe0 lG\xe0!\\8\xe0\"L)\xe0#<\x1a\xe0$,\v\xe0%\x1b\xfc" + + "\xe0&\v\xed\xe0'\x05\x19`'\xf5\n`(\xe5\tp)\xd4\xfap*\xc4\xebp1]\xd9\x102r\xb4\x103=\xad\x004R\x88\x005\x1d\x8f\x0062j\x006\xfdq\x008\x1b\x86\x808\xddS" + + "\x009\xfbh\x80:\xbd5\x00;\xdbJ\x80<\xa6Q\x80=\xbb,\x80>\x863\x80?\x9b\x0e\x80@f\x15\x80A\x84+\x00BE\xf7\x80Cd\r\x00D%ـEC\xef\x00F\x05\xbb\x80G#\xd1" + + "\x00G\xee\xd8\x00I\x03\xb3\x00Iκ\x00J\xe3\x95\x00K\xae\x9c\x00Ḻ\x80M\x8e~\x00N\xac\x93\x80On`\x00P\x8cu\x80QW|\x80RlW\x80S7^\x80TL9\x80U\x17@" + + "\x80V,\x1b\x80\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x06\x04\b\t\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x03\x00\x00.\xbc\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x00\f\x00\x00FP\x01\b\x00\x008@\x01\f\x00\x00" + + "*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\fLMT\x00+03\x00+05\x00+04\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\n\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x95D\xff\xff\xff\xff\xe7\xda\fP\x00\x00\x00\x00\x15'\x99\xc0" + + "\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00" + + "\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0" + + "\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\x19`\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe5\tp\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00" + + "*\xc4\xebp\x00\x00\x00\x001]\xd9\x10\x00\x00\x00\x002r\xb4\x10\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x8f\x00\x00\x00\x00\x0062j\x00\x00\x00\x00\x006\xfdq\x00" + + "\x00\x00\x00\x008\x1b\x86\x80\x00\x00\x00\x008\xddS\x00\x00\x00\x00\x009\xfbh\x80\x00\x00\x00\x00:\xbd5\x00\x00\x00\x00\x00;\xdbJ\x80\x00\x00\x00\x00<\xa6Q\x80\x00\x00\x00\x00=\xbb,\x80\x00\x00\x00\x00" + + ">\x863\x80\x00\x00\x00\x00?\x9b\x0e\x80\x00\x00\x00\x00@f\x15\x80\x00\x00\x00\x00A\x84+\x00\x00\x00\x00\x00BE\xf7\x80\x00\x00\x00\x00Cd\r\x00\x00\x00\x00\x00D%ـ\x00\x00\x00\x00EC\xef\x00" + + "\x00\x00\x00\x00F\x05\xbb\x80\x00\x00\x00\x00G#\xd1\x00\x00\x00\x00\x00G\xee\xd8\x00\x00\x00\x00\x00I\x03\xb3\x00\x00\x00\x00\x00Iκ\x00\x00\x00\x00\x00J\xe3\x95\x00\x00\x00\x00\x00K\xae\x9c\x00\x00\x00\x00\x00" + + "Ḻ\x80\x00\x00\x00\x00M\x8e~\x00\x00\x00\x00\x00N\xac\x93\x80\x00\x00\x00\x00On`\x00\x00\x00\x00\x00P\x8cu\x80\x00\x00\x00\x00QW|\x80\x00\x00\x00\x00RlW\x80\x00\x00\x00\x00S7^\x80" + + "\x00\x00\x00\x00TL9\x80\x00\x00\x00\x00U\x17@\x80\x00\x00\x00\x00V,\x1b\x80\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x06\x04\b\t" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x03\x00\x00.\xbc\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008" + + "@\x00\f\x00\x008@\x00\f\x00\x00FP\x01\b\x00\x008@\x01\f\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\fLMT\x00+03\x00+05\x00+04\x00\x00\x00\x00\x00\x01" + + "\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\n<+04>-4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP}\x94iH\xc5\x04\x00\x00\xc5\x04\x00\x00\f\x00\x1c\x00Asia/B" + + "arnaulUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\n\x00\x00\x00\x00\x00\x00\x00D\x00\x00\x00\n\x00\x00\x00\x10\xa1\xd5}\xfc\xb5\xa3\xe1 \x15'o\x90\x16\x18\xa4\x00\x17\b\xa3\x10\x17\xf9׀\x18\xe9\u0590\x19\xdb\v\x00\x1a\xcc[\x90\x1b\xbch\xb0\x1c\xac" + + "Y\xb0\x1d\x9cJ\xb0\x1e\x8c;\xb0\x1f|,\xb0 l\x1d\xb0!\\\x0e\xb0\"K\xff\xb0#;\xf0\xb0$+\xe1\xb0%\x1bҰ&\vð'\x04\xef0'\xf4\xe00(\xe4\xdf@)x\x87@)\xd4" + + "\xc20*ij0+\xb4\xa40,\xa4\x950-\x94\x860.\x84w0/th0/\xc7L\x800dg@1]\x92\xc02rm\xc03=t\xc04RO\xc05\x1dV\xc0621\xc06\xfd" + + "8\xc08\x1bN@8\xdd\x1a\xc09\xfb0@:\xbc\xfc\xc0;\xdb\x12@<\xa6\x19@=\xba\xf4@>\x85\xfb@?\x9a\xd6@@e\xdd@A\x83\xf2\xc0BE\xbf@Cc\xd4\xc0D%\xa1@EC" + + "\xb6\xc0F\x05\x83@G#\x98\xc0G\xee\x9f\xc0I\x03z\xc0I\u0381\xc0J\xe3\\\xc0K\xaec\xc0L\xccy@M\x8eE\xc0TK\xf30V\xf6\xea@\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04\x05\b\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x04\a\x04\x04\x00\x00" + + "N\x84\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\f\x00\x00bp\x00\f\x00\x00p\x80\x01\b\x00\x00bp\x01\f\x00\x00T`\x00\x04\x00\x00bp\x01\f\x00\x00bp\x00\fLM" + + "T\x00+06\x00+08\x00+07\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00D" + + "\x00\x00\x00\n\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xd5}\xfc\xff\xff\xff\xff\xb5\xa3\xe1 \x00\x00\x00\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\b\xa3\x10\x00\x00\x00\x00\x17\xf9׀\x00\x00\x00\x00" + + "\x18\xe9\u0590\x00\x00\x00\x00\x19\xdb\v\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbch\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0" + + "\x00\x00\x00\x00 l\x1d\xb0\x00\x00\x00\x00!\\\x0e\xb0\x00\x00\x00\x00\"K\xff\xb0\x00\x00\x00\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1bҰ\x00\x00\x00\x00&\vð\x00\x00\x00\x00" + + "'\x04\xef0\x00\x00\x00\x00'\xf4\xe00\x00\x00\x00\x00(\xe4\xdf@\x00\x00\x00\x00)x\x87@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*ij0\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00,\xa4\x950" + + "\x00\x00\x00\x00-\x94\x860\x00\x00\x00\x00.\x84w0\x00\x00\x00\x00/th0\x00\x00\x00\x00/\xc7L\x80\x00\x00\x00\x000dg@\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x002rm\xc0\x00\x00\x00\x00" + + "3=t\xc0\x00\x00\x00\x004RO\xc0\x00\x00\x00\x005\x1dV\xc0\x00\x00\x00\x00621\xc0\x00\x00\x00\x006\xfd8\xc0\x00\x00\x00\x008\x1bN@\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb0@" + + "\x00\x00\x00\x00:\xbc\xfc\xc0\x00\x00\x00\x00;\xdb\x12@\x00\x00\x00\x00<\xa6\x19@\x00\x00\x00\x00=\xba\xf4@\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00" + + "A\x83\xf2\xc0\x00\x00\x00\x00BE\xbf@\x00\x00\x00\x00Cc\xd4\xc0\x00\x00\x00\x00D%\xa1@\x00\x00\x00\x00EC\xb6\xc0\x00\x00\x00\x00F\x05\x83@\x00\x00\x00\x00G#\x98\xc0\x00\x00\x00\x00G\xee\x9f\xc0" + + "\x00\x00\x00\x00I\x03z\xc0\x00\x00\x00\x00I\u0381\xc0\x00\x00\x00\x00J\xe3\\\xc0\x00\x00\x00\x00K\xaec\xc0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x00\x00\x00\x00TK\xf30\x00\x00\x00\x00" + + "V\xf6\xea@\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04\x05\b\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x04\a\x04\x04\x00\x00N\x84\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\f\x00\x00bp\x00\f\x00\x00p\x80\x01\b\x00\x00bp" + + "\x01\f\x00\x00T`\x00\x04\x00\x00bp\x01\f\x00\x00bp\x00\fLMT\x00+06\x00+08\x00+07\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x01\n<+07>-7\nPK\x03\x04\n" + + "\x00\x00\x00\x00\x00\xf5F\x9cP\xc2\xf47\xbd\x9b\a\x00\x00\x9b\a\x00\x00\r\x00\x1c\x00Asia/IstanbulUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00" + + "\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00t\x00\x00\x00\v\x00\x00\x00\x19\x80\x00\x00\x00\x90\x8b\xf5\x98\x9b\f" + + "\x17`\x9bվТec\xe0\xa3{\x82P\xa4N\x80`\xa5?\xb4Ц%'\xe0\xa7'\u007fЪ((`\xaa\xe1\xfdЫ\xf9\x89\xe0\xac\xc31Pȁ?\xe0\xc9\x01\x13P\xc9J\xf5`\xca\xce" + + "\x80P\xcbˮ`\xd2k\tPӢ9`\xd4C\x02P\xd5L\r\xe0\xd6){\xd0\xd7+\xef\xe0\xd8\t]\xd0\xd9\x02\x97`\xd9\xe9?\xd0\xda\xeb\xb3\xe0\xdb\xd2\\P\xdc\xd4\xd0`ݲ>P\xf1\xf4" + + "\xb9`\xf4b\xefP\xf5h\x06`\xf6\x1f8\xd0\x06n\x93p\a9\x9ap\a\xfbu\x00\t\x19|p\t\xd0\xcb\x00\n\xf9^p\v\xb1\xfe\x80\f\xd9@p\r\xa4U\x80\x0e\xa6\xadp\x0f\x847\x80\x0f\xf8" + + "\x11P\x19\x89\xb0p\x19ܰ\xe0\x1b\xe6\xd0\xf0\x1c\xc6\xef\xf0\x1d\x9b1p\x1e\x8cs\xf0\x1f|d\xf0 lU\xf0!\\F\xf0\"L7\xf0#<(\xf0$,\x19\xf0%\x1c\n\xf0&\v\xfb\xf0'\x05" + + "'p'\xf5\x18p(\xe5\tp)\xd4\xfap*\xc4\xebp+\xb4\xdcp,\xa4\xcdp-\x8b\x83\xf0.\x84\xafp/t\xa0p0d\x91p1]\xbc\xf02r\x97\xf03=\x9e\xf04Ry\xf05\x1d" + + "\x80\xf062[\xf06\xfdb\xf08\x1bxp8\xddD\xf09\xfbZp:\xbd&\xf0;\xdb\x86%p?\x9b\x00p@f\apA\x84\x1c\xf0BE\xe9pCc" + + "\xfe\xf0D%\xcbpEC\xe0\xf0F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8fݐN\xac\xa1\x90Onn\x10P\x8c\x83\x90QW" + + "\x8a\x90Rle\x90S8\xbe\x10TLG\x90U\x17N\x90V>\x9e\x90V\xf70\x90W\xcf.P\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x03\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" + + "\a\x06\a\x06\a\x06\a\x06\a\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\x04\x04\x00\x00\x1b(\x00\x00\x00\x00\x1bh\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x00\x11" + + "\x00\x008@\x01\x15\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x00\x11LMT\x00IMT\x00EEST\x00EET\x00+03\x00+04" + + "\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00t\x00" + + "\x00\x00\v\x00\x00\x00\x19\xff\xff\xff\xffV\xb6\xc8\xd8\xff\xff\xff\xff\x90\x8b\xf5\x98\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9bվ\xd0\xff\xff\xff\xff\xa2ec\xe0\xff\xff\xff\xff\xa3{\x82P\xff\xff\xff\xff\xa4" + + "N\x80`\xff\xff\xff\xff\xa5?\xb4\xd0\xff\xff\xff\xff\xa6%'\xe0\xff\xff\xff\xff\xa7'\u007f\xd0\xff\xff\xff\xff\xaa((`\xff\xff\xff\xff\xaa\xe1\xfd\xd0\xff\xff\xff\xff\xab\xf9\x89\xe0\xff\xff\xff\xff\xac\xc31P\xff" + + "\xff\xff\xffȁ?\xe0\xff\xff\xff\xff\xc9\x01\x13P\xff\xff\xff\xff\xc9J\xf5`\xff\xff\xff\xff\xca\u0380P\xff\xff\xff\xff\xcbˮ`\xff\xff\xff\xff\xd2k\tP\xff\xff\xff\xffӢ9`\xff\xff\xff\xff\xd4" + + "C\x02P\xff\xff\xff\xff\xd5L\r\xe0\xff\xff\xff\xff\xd6){\xd0\xff\xff\xff\xff\xd7+\xef\xe0\xff\xff\xff\xff\xd8\t]\xd0\xff\xff\xff\xff\xd9\x02\x97`\xff\xff\xff\xff\xd9\xe9?\xd0\xff\xff\xff\xff\xda\xeb\xb3\xe0\xff" + + "\xff\xff\xff\xdb\xd2\\P\xff\xff\xff\xff\xdc\xd4\xd0`\xff\xff\xff\xffݲ>P\xff\xff\xff\xff\xf1\xf4\xb9`\xff\xff\xff\xff\xf4b\xefP\xff\xff\xff\xff\xf5h\x06`\xff\xff\xff\xff\xf6\x1f8\xd0\x00\x00\x00\x00\x06" + + "n\x93p\x00\x00\x00\x00\a9\x9ap\x00\x00\x00\x00\a\xfbu\x00\x00\x00\x00\x00\t\x19|p\x00\x00\x00\x00\t\xd0\xcb\x00\x00\x00\x00\x00\n\xf9^p\x00\x00\x00\x00\v\xb1\xfe\x80\x00\x00\x00\x00\f\xd9@p\x00" + + "\x00\x00\x00\r\xa4U\x80\x00\x00\x00\x00\x0e\xa6\xadp\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x0f\xf8\x11P\x00\x00\x00\x00\x19\x89\xb0p\x00\x00\x00\x00\x19ܰ\xe0\x00\x00\x00\x00\x1b\xe6\xd0\xf0\x00\x00\x00\x00\x1c" + + "\xc6\xef\xf0\x00\x00\x00\x00\x1d\x9b1p\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00" + + "\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\tp\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*" + + "\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x8b\x83\xf0\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00" + + "\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008" + + "\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb\x86%p\x00\x00\x00\x00?\x9b\x00p\x00" + + "\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G" + + "#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8fݐ\x00" + + "\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S8\xbe\x10\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U" + + "\x17N\x90\x00\x00\x00\x00V>\x9e\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00W\xcf.P\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x03\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\x04\x04\x00\x00\x1b(\x00\x00\x00\x00\x1bh\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x00" + + "\x11\x00\x008@\x01\x15\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x00\x11LMT\x00IMT\x00EEST\x00EET\x00+03\x00+0" + + "4\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\n<+03>-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPj\xcc\xd7\xe7\xdb\x04\x00\x00\xdb\x04\x00\x00\f" + + "\x00\x1c\x00Asia/IrkutskUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\f\x00\x00\x00\x14\x80\x00\x00\x00\xa2\x12\x0f\xbf\xb5\xa3\xd3\x10\x15'a\x80\x16\x18\x95\xf0\x17\b\x95\x00\x17\xf9\xc9p\x18\xe9Ȁ\x19" + + "\xda\xfc\xf0\x1a\xccM\x80\x1b\xbcZ\xa0\x1c\xacK\xa0\x1d\x9c<\xa0\x1e\x8c-\xa0\x1f|\x1e\xa0 l\x0f\xa0!\\\x00\xa0\"K\xf1\xa0#;\xe2\xa0$+Ӡ%\x1bĠ&\v\xb5\xa0'\x04\xe1 '" + + "\xf4\xd2 (\xe4\xd10)xy0)Դ *ĥ +\xb4\x96 ,\xa4\x87 -\x94x .\x84i /tZ 0dK 1]v\xa02rQ\xa03=X\xa04R3\xa05" + + "\x1d:\xa062\x15\xa06\xfd\x1c\xa08\x1b2 8\xdc\xfe\xa09\xfb\x14 :\xbc\xe0\xa0;\xda\xf6 <\xa5\xfd =\xba\xd8 >\x85\xdf ?\x9a\xba @e\xc1 A\x83֠BE\xa3 C" + + "c\xb8\xa0D%\x85 EC\x9a\xa0F\x05g G#|\xa0G\ue0e0I\x03^\xa0I\xcee\xa0J\xe3@\xa0K\xaeG\xa0L\xcc] M\x8e)\xa0TK\xd7\x10\u007f\xff\xff\xff\x01\x02\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\b\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\t" + + "\x05\x05\x00\x00a\xc1\x00\x00\x00\x00a\xc1\x00\x04\x00\x00bp\x00\b\x00\x00~\x90\x01\f\x00\x00p\x80\x00\x10\x00\x00p\x80\x00\x10\x00\x00~\x90\x01\f\x00\x00p\x80\x01\x10\x00\x00bp\x00\b\x00\x00~\x90" + + "\x00\f\x00\x00~\x90\x01\f\x00\x00p\x80\x00\x10LMT\x00IMT\x00+07\x00+09\x00+08\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\f\x00\x00\x00\x14\xff\xff\xff\xffV\xb6\x82?\xff\xff\xff\xff\xa2\x12\x0f\xbf\xff\xff\xff\xff\xb5\xa3\xd3\x10\x00\x00\x00\x00\x15'" + + "a\x80\x00\x00\x00\x00\x16\x18\x95\xf0\x00\x00\x00\x00\x17\b\x95\x00\x00\x00\x00\x00\x17\xf9\xc9p\x00\x00\x00\x00\x18\xe9Ȁ\x00\x00\x00\x00\x19\xda\xfc\xf0\x00\x00\x00\x00\x1a\xccM\x80\x00\x00\x00\x00\x1b\xbcZ\xa0\x00\x00" + + "\x00\x00\x1c\xacK\xa0\x00\x00\x00\x00\x1d\x9c<\xa0\x00\x00\x00\x00\x1e\x8c-\xa0\x00\x00\x00\x00\x1f|\x1e\xa0\x00\x00\x00\x00 l\x0f\xa0\x00\x00\x00\x00!\\\x00\xa0\x00\x00\x00\x00\"K\xf1\xa0\x00\x00\x00\x00#;" + + "\xe2\xa0\x00\x00\x00\x00$+Ӡ\x00\x00\x00\x00%\x1bĠ\x00\x00\x00\x00&\v\xb5\xa0\x00\x00\x00\x00'\x04\xe1 \x00\x00\x00\x00'\xf4\xd2 \x00\x00\x00\x00(\xe4\xd10\x00\x00\x00\x00)xy0\x00\x00" + + "\x00\x00)Դ \x00\x00\x00\x00*ĥ \x00\x00\x00\x00+\xb4\x96 \x00\x00\x00\x00,\xa4\x87 \x00\x00\x00\x00-\x94x \x00\x00\x00\x00.\x84i \x00\x00\x00\x00/tZ \x00\x00\x00\x000d" + + "K \x00\x00\x00\x001]v\xa0\x00\x00\x00\x002rQ\xa0\x00\x00\x00\x003=X\xa0\x00\x00\x00\x004R3\xa0\x00\x00\x00\x005\x1d:\xa0\x00\x00\x00\x0062\x15\xa0\x00\x00\x00\x006\xfd\x1c\xa0\x00\x00" + + "\x00\x008\x1b2 \x00\x00\x00\x008\xdc\xfe\xa0\x00\x00\x00\x009\xfb\x14 \x00\x00\x00\x00:\xbc\xe0\xa0\x00\x00\x00\x00;\xda\xf6 \x00\x00\x00\x00<\xa5\xfd \x00\x00\x00\x00=\xba\xd8 \x00\x00\x00\x00>\x85" + + "\xdf \x00\x00\x00\x00?\x9a\xba \x00\x00\x00\x00@e\xc1 \x00\x00\x00\x00A\x83֠\x00\x00\x00\x00BE\xa3 \x00\x00\x00\x00Cc\xb8\xa0\x00\x00\x00\x00D%\x85 \x00\x00\x00\x00EC\x9a\xa0\x00\x00" + + "\x00\x00F\x05g \x00\x00\x00\x00G#|\xa0\x00\x00\x00\x00G\ue0e0\x00\x00\x00\x00I\x03^\xa0\x00\x00\x00\x00I\xcee\xa0\x00\x00\x00\x00J\xe3@\xa0\x00\x00\x00\x00K\xaeG\xa0\x00\x00\x00\x00L\xcc" + + "] \x00\x00\x00\x00M\x8e)\xa0\x00\x00\x00\x00TK\xd7\x10\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\b\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\t\x05\x05\x00\x00a\xc1\x00\x00\x00\x00a\xc1\x00\x04\x00\x00bp\x00\b\x00\x00~\x90\x01\f\x00\x00p" + + "\x80\x00\x10\x00\x00p\x80\x00\x10\x00\x00~\x90\x01\f\x00\x00p\x80\x01\x10\x00\x00bp\x00\b\x00\x00~\x90\x00\f\x00\x00~\x90\x01\f\x00\x00p\x80\x00\x10LMT\x00IMT\x00+07\x00+09" + + "\x00+08\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\n<+08>-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP@+\xbfW\xc7\x00\x00\x00\xc7\x00\x00\x00\n\x00\x1c\x00Asia" + + "/QatarUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\f\xa1\xf2\x9d0\x04\x8a\x92\xc0\u007f\xff\xff\xff\x01\x02\x02\x00\x000P\x00\x00\x00\x008@\x00\x04\x00\x00*0\x00\bLMT\x00+04\x00+" + + "03\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xa1\xf2\x9d0\x00\x00\x00\x00\x04" + + "\x8a\x92\xc0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x02\x00\x000P\x00\x00\x00\x008@\x00\x04\x00\x00*0\x00\bLMT\x00+04\x00+03\x00\n<+03>-3\nPK\x03\x04\n\x00\x00" + + "\x00\x00\x00\xf5F\x9cP@+\xbfW\xc7\x00\x00\x00\xc7\x00\x00\x00\f\x00\x1c\x00Asia/BahrainUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14" + + "\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\f\xa1\xf2\x9d0\x04\x8a\x92\xc0\u007f\xff\xff\xff\x01" + + "\x02\x02\x00\x000P\x00\x00\x00\x008@\x00\x04\x00\x00*0\x00\bLMT\x00+04\x00+03\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xa1\xf2\x9d0\x00\x00\x00\x00\x04\x8a\x92\xc0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x02\x00\x000P\x00\x00\x00\x008@\x00\x04\x00\x00*0\x00" + + "\bLMT\x00+04\x00+03\x00\n<+03>-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x1d`u\xd5\f\x01\x00\x00\f\x01\x00\x00\v\x00\x1c\x00Asia/Yan" + + "gonUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x12\x80\x00\x00\x00\xa1\xf2sQ\xcb\xf2\xfc\x18њg\xf0\u007f\xff\xff\xff\x01\x02\x03\x02\x02\x00\x00Z/\x00\x00\x00\x00Z/\x00\x04\x00\x00[h\x00\b\x00\x00" + + "~\x90\x00\x0e\x00\x00[h\x00\bLMT\x00RMT\x00+0630\x00+09\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x12\xff\xff\xff\xffV\xb6\x89\xd1\xff\xff\xff\xff\xa1\xf2sQ\xff\xff\xff\xff\xcb\xf2\xfc\x18\xff\xff\xff\xffњg\xf0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x02\x00\x00Z" + + "/\x00\x00\x00\x00Z/\x00\x04\x00\x00[h\x00\b\x00\x00~\x90\x00\x0e\x00\x00[h\x00\bLMT\x00RMT\x00+0630\x00+09\x00\n<+0630>-6:30\nP" + + "K\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPz\xfb\xb5\x11\u007f\x04\x00\x00\u007f\x04\x00\x00\f\x00\x1c\x00Asia/YerevanUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04" + + "\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00?\x00\x00\x00\n\x00\x00\x00\x10\xaa\x19\x9aH\xe7\xda\f" + + "P\x15'\x99\xc0\x16\x18\xce0\x17\b\xcd@\x17\xfa\x01\xb0\x18\xea\x00\xc0\x19\xdb50\x1a̅\xc0\x1b\xbc\x92\xe0\x1c\xac\x83\xe0\x1d\x9ct\xe0\x1e\x8ce\xe0\x1f|V\xe0 lG\xe0!\\8\xe0\"L)" + + "\xe0#<\x1a\xe0$,\v\xe0%\x1b\xfc\xe0&\v\xed\xe0'\x05\x19`'\xf5\n`(\xe5\tp)\xd4\xfap*\xc4\xebp+\xb4\xdcp,\xa4\xcdp-\x94\xbep.\x84\xafp/t\xa0p0d\x91" + + "p3=\x90\xe04Rk\xe05\x1dr\xe062M\xe06\xfdT\xe08\x1bj`8\xdd6\xe09\xfbL`:\xbd\x18\xe0;\xdb.`<\xa65`=\xbb\x10`>\x86\x17`?\x9a\xf2`@e\xf9" + + "`A\x84\x0e\xe0BE\xdb`Cc\xf0\xe0D%\xbd`EC\xd2\xe0F\x05\x9f`G#\xb4\xe0G\xee\xbb\xe0I\x03\x96\xe0IΝ\xe0J\xe3x\xe0K\xae\u007f\xe0L̕`M\x8ea\xe0N\xacw" + + "`\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x06\a\x06\a\x06\a\x06\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x04\x00\x00)\xb8\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x00\f\x00\x00FP\x01\b\x00\x008@\x01\f\x00\x00*0\x00\x04\x00\x00FP" + + "\x01\b\x00\x008@\x00\fLMT\x00+03\x00+05\x00+04\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\n\x00\x00\x00\x00\x00\x00\x00?\x00\x00\x00\n\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x9aH\xff\xff\xff\xff\xe7\xda\fP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00" + + "\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8c" + + "e\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00" + + "\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\x19`\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe5\tp\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4" + + "\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004Rk\xe0\x00\x00\x00\x005\x1dr\xe0\x00\x00" + + "\x00\x0062M\xe0\x00\x00\x00\x006\xfdT\xe0\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`\x00\x00\x00\x00<\xa6" + + "5`\x00\x00\x00\x00=\xbb\x10`\x00\x00\x00\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0\x00\x00\x00\x00BE\xdb`\x00\x00\x00\x00Cc\xf0\xe0\x00\x00" + + "\x00\x00D%\xbd`\x00\x00\x00\x00EC\xd2\xe0\x00\x00\x00\x00F\x05\x9f`\x00\x00\x00\x00G#\xb4\xe0\x00\x00\x00\x00G\xee\xbb\xe0\x00\x00\x00\x00I\x03\x96\xe0\x00\x00\x00\x00IΝ\xe0\x00\x00\x00\x00J\xe3" + + "x\xe0\x00\x00\x00\x00K\xae\u007f\xe0\x00\x00\x00\x00L̕`\x00\x00\x00\x00M\x8ea\xe0\x00\x00\x00\x00N\xacw`\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x06\a\x06\a\x06\a\x06\a\x06\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x04\x00\x00)\xb8\x00\x00\x00\x00*0\x00\x04\x00\x00F" + + "P\x01\b\x00\x008@\x00\f\x00\x008@\x00\f\x00\x00FP\x01\b\x00\x008@\x01\f\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\fLMT\x00+03\x00+05\x00+04" + + "\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\n<+04>-4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc4/ձ\xe5\x03\x00\x00\xe5\x03\x00\x00\v\x00\x1c\x00Asia/Almat" + + "yUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00" + + "\x00\x00\x00\x004\x00\x00\x00\n\x00\x00\x00\x10\xaa\x19{ܵ\xa3\xef0\x15'}\xa0\x16\x18\xb2\x10\x17\b\xb1 \x17\xf9\xe5\x90\x18\xe9\xe4\xa0\x19\xdb\x19\x10\x1a\xcci\xa0\x1b\xbcv\xc0\x1c\xacg\xc0\x1d\x9cX" + + "\xc0\x1e\x8cI\xc0\x1f|:\xc0 l+\xc0!\\\x1c\xc0\"L\r\xc0#;\xfe\xc0$+\xef\xc0%\x1b\xe0\xc0&\v\xd1\xc0'\x04\xfd@'\xf4\xee@(\xe4\xedP)x\x95P)\xd4\xd0@*\xc4\xc1" + + "@+\xb4\xb2@,\xa4\xa3@-\x94\x94@.\x84\x85@/tv@0dg@1]\x92\xc02rm\xc03=t\xc04RO\xc05\x1dV\xc0621\xc06\xfd8\xc08\x1bN@8\xdd\x1a" + + "\xc09\xfb0@:\xbc\xfc\xc0;\xdb\x12@<\xa6\x19@=\xba\xf4@>\x85\xfb@?\x9a\xd6@@e\xdd@A\x83\xf2\xc0\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x04\x00\x00H$\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\b\x00\x00T`\x00\f\x00\x00T" + + "`\x00\f\x00\x00bp\x01\b\x00\x00T`\x01\f\x00\x00FP\x00\x04\x00\x00bp\x01\b\x00\x00T`\x00\fLMT\x00+05\x00+07\x00+06\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01T" + + "Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x004\x00\x00\x00\n\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19{\xdc\xff\xff\xff\xff\xb5\xa3\xef0\x00" + + "\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00\x00\x00\x00\x18\xe9\xe4\xa0\x00\x00\x00\x00\x19\xdb\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b" + + "\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f|:\xc0\x00\x00\x00\x00 l+\xc0\x00\x00\x00\x00!\\\x1c\xc0\x00\x00\x00\x00\"L\r\xc0\x00" + + "\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\v\xd1\xc0\x00\x00\x00\x00'\x04\xfd@\x00\x00\x00\x00'\xf4\xee@\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)" + + "x\x95P\x00\x00\x00\x00)\xd4\xd0@\x00\x00\x00\x00*\xc4\xc1@\x00\x00\x00\x00+\xb4\xb2@\x00\x00\x00\x00,\xa4\xa3@\x00\x00\x00\x00-\x94\x94@\x00\x00\x00\x00.\x84\x85@\x00\x00\x00\x00/tv@\x00" + + "\x00\x00\x000dg@\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x002rm\xc0\x00\x00\x00\x003=t\xc0\x00\x00\x00\x004RO\xc0\x00\x00\x00\x005\x1dV\xc0\x00\x00\x00\x00621\xc0\x00\x00\x00\x006" + + "\xfd8\xc0\x00\x00\x00\x008\x1bN@\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb0@\x00\x00\x00\x00:\xbc\xfc\xc0\x00\x00\x00\x00;\xdb\x12@\x00\x00\x00\x00<\xa6\x19@\x00\x00\x00\x00=\xba\xf4@\x00" + + "\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A\x83\xf2\xc0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x06\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x04\x00\x00H$\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\b\x00\x00T`\x00\f\x00\x00T`\x00" + + "\f\x00\x00bp\x01\b\x00\x00T`\x01\f\x00\x00FP\x00\x04\x00\x00bp\x01\b\x00\x00T`\x00\fLMT\x00+05\x00+07\x00+06\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\n<+" + + "06>-6\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPp-9\n" + + "PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPq\x16UAQ\x01\x00\x00Q\x01\x00\x00\n\x00\x1c\x00Asia/DaccaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5" + + "\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x06\x00\x00\x00\x1c\x80\x00\x00\x00\xcaۆ\xb0" + + "\xcc\x05q\x18̕2\xa8ݨҘJ;\xc4\x10K<ؐ\u007f\xff\xff\xff\x01\x02\x03\x02\x04\x05\x04\x04\x00\x00T\xc4\x00\x00\x00\x00R\xd0\x00\x04\x00\x00[h\x00\b\x00\x00MX\x00\x0e\x00\x00T`" + + "\x00\x14\x00\x00bp\x01\x18LMT\x00HMT\x00+0630\x00+0530\x00+06\x00+07\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x06\x00\x00\x00\x1c\xff\xff\xff\xffi\x86\x86\xbc\xff\xff\xff\xff\xcaۆ\xb0\xff\xff\xff\xff\xcc\x05q\x18\xff\xff\xff\xff̕2\xa8\xff\xff\xff\xffݨҘ" + + "\x00\x00\x00\x00J;\xc4\x10\x00\x00\x00\x00K<ؐ\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x04\x05\x04\x04\x00\x00T\xc4\x00\x00\x00\x00R\xd0\x00\x04\x00\x00[h\x00\b\x00\x00MX\x00\x0e\x00\x00T`" + + "\x00\x14\x00\x00bp\x01\x18LMT\x00HMT\x00+0630\x00+0530\x00+06\x00+07\x00\n<+06>-6\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPy" + + "\x84\xe1i1\x02\x00\x001\x02\x00\x00\x0e\x00\x1c\x00Asia/ChongqingUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZi" + + "f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x03\x00\x00\x00\f\x80\x00\x00\x00\xa0\x97\xa2\x80\xa1y\x04\xf0\xc8Y^\x80\xc9\t\xf9" + + "p\xc9ӽ\x00\xcb\x05\x8a\xf0\xcb|@\x00\xd2;>\xf0Ӌ{\x80\xd4B\xad\xf0\xd5E\"\x00\xd6L\xbf\xf0\xd7<\xbf\x00\xd8\x06fp\xd9\x1d\xf2\x80\xd9A|\xf0\x1e\xbaR \x1fi\x9b\x90 ~\x84" + + "\xa0!I}\x90\"g\xa1 #)_\x90$G\x83 %\x12|\x10&'e &\xf2^\x10(\aG (\xd2@\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\bLMT\x00CDT\x00CST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff~6C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff\xff\xa1y\x04\xf0\xff\xff\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9\t\xf9p" + + "\xff\xff\xff\xff\xc9ӽ\x00\xff\xff\xff\xff\xcb\x05\x8a\xf0\xff\xff\xff\xff\xcb|@\x00\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xffӋ{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff" + + "\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00\x00\x1e\xbaR \x00\x00\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 ~\x84\xa0" + + "\x00\x00\x00\x00!I}\x90\x00\x00\x00\x00\"g\xa1 \x00\x00\x00\x00#)_\x90\x00\x00\x00\x00$G\x83 \x00\x00\x00\x00%\x12|\x10\x00\x00\x00\x00&'e \x00\x00\x00\x00&\xf2^\x10\x00\x00\x00\x00" + + "(\aG \x00\x00\x00\x00(\xd2@\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\bL" + + "MT\x00CDT\x00CST\x00\nCST-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPrI\xe7\x8c\xe4\x04\x00\x00\xe4\x04\x00\x00\r\x00\x1c\x00Asia/Ust-Ner" + + "aUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00" + + "\x00\x00\x00\x00C\x00\x00\x00\f\x00\x00\x00\x18\xa1\xdbݺ\xb5\xa3\xc5\x00\x15'Sp\x16\x18k\xc0\x17\bj\xd0\x17\xf9\x9f@\x18\xe9\x9eP\x19\xda\xd2\xc0\x1a\xcc#P\x1b\xbc0p\x1c\xac!p\x1d\x9c\x12" + + "p\x1e\x8c\x03p\x1f{\xf4p k\xe5p![\xd6p\"K\xc7p#;\xb8p$+\xa9p%\x1b\x9ap&\v\x8bp'\x04\xb6\xf0'\xf4\xa7\xf0(\xe4\xa7\x00)xO\x00)ԉ\xf0*\xc4z" + + "\xf0+\xb4k\xf0,\xa4\\\xf0-\x94M\xf0.\x84>\xf0/t/\xf00d \xf01]Lp2r'p3=.p4R\tp5\x1d\x10p61\xebp6\xfc\xf2p8\x1b\a\xf08\xdc\xd4" + + "p9\xfa\xe9\xf0:\xbc\xb6p;\xda\xcb\xf0<\xa5\xd2\xf0=\xba\xad\xf0>\x85\xb4\xf0?\x9a\x8f\xf0@e\x96\xf0A\x83\xacpBEx\xf0Cc\x8epD%Z\xf0ECppF\x05<\xf0G#R" + + "pG\xeeYpI\x034pI\xce;pJ\xe3\x16pK\xae\x1dpL\xcc2\xf0M\x8d\xffpNm\xf4@TK\xba\xf0\u007f\xff\xff\xff\x01\x02\x04\x03\x04\x03\x04\x03\x04\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\a\b\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\t\x05\b\b\x00\x00\x86F\x00\x00\x00\x00p\x80\x00\x04" + + "\x00\x00~\x90\x00\b\x00\x00\x9a\xb0\x00\f\x00\x00\xa8\xc0\x01\x10\x00\x00\x9a\xb0\x00\f\x00\x00\xa8\xc0\x01\x10\x00\x00\x9a\xb0\x01\f\x00\x00\x8c\xa0\x00\x14\x00\x00\xa8\xc0\x00\x10\x00\x00\xa8\xc0\x01\x10\x00\x00\x8c\xa0\x00\x14" + + "LMT\x00+08\x00+09\x00+11\x00+12\x00+10\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\f\x00\x00\x00\x18\xff\xff\xff\xff\xa1\xdbݺ\xff\xff\xff\xff\xb5\xa3\xc5\x00\x00\x00\x00\x00\x15'Sp\x00\x00\x00\x00\x16\x18k\xc0\x00\x00\x00\x00\x17\bj\xd0" + + "\x00\x00\x00\x00\x17\xf9\x9f@\x00\x00\x00\x00\x18\xe9\x9eP\x00\x00\x00\x00\x19\xda\xd2\xc0\x00\x00\x00\x00\x1a\xcc#P\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00" + + "\x1e\x8c\x03p\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xe5p\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\"K\xc7p\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x9ap" + + "\x00\x00\x00\x00&\v\x8bp\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xa7\xf0\x00\x00\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00)xO\x00\x00\x00\x00\x00)ԉ\xf0\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00" + + "+\xb4k\xf0\x00\x00\x00\x00,\xa4\\\xf0\x00\x00\x00\x00-\x94M\xf0\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t/\xf0\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Lp\x00\x00\x00\x002r'p" + + "\x00\x00\x00\x003=.p\x00\x00\x00\x004R\tp\x00\x00\x00\x005\x1d\x10p\x00\x00\x00\x0061\xebp\x00\x00\x00\x006\xfc\xf2p\x00\x00\x00\x008\x1b\a\xf0\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x00" + + "9\xfa\xe9\xf0\x00\x00\x00\x00:\xbc\xb6p\x00\x00\x00\x00;\xda\xcb\xf0\x00\x00\x00\x00<\xa5\xd2\xf0\x00\x00\x00\x00=\xba\xad\xf0\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x8f\xf0\x00\x00\x00\x00@e\x96\xf0" + + "\x00\x00\x00\x00A\x83\xacp\x00\x00\x00\x00BEx\xf0\x00\x00\x00\x00Cc\x8ep\x00\x00\x00\x00D%Z\xf0\x00\x00\x00\x00ECpp\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Rp\x00\x00\x00\x00" + + "G\xeeYp\x00\x00\x00\x00I\x034p\x00\x00\x00\x00I\xce;p\x00\x00\x00\x00J\xe3\x16p\x00\x00\x00\x00K\xae\x1dp\x00\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M\x8d\xffp\x00\x00\x00\x00Nm\xf4@" + + "\x00\x00\x00\x00TK\xba\xf0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x04\x03\x04\x03\x04\x03\x04\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\b\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\t\x05\b\b\x00\x00\x86F\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x00\b\x00\x00\x9a\xb0\x00\f\x00\x00\xa8\xc0\x01\x10\x00\x00\x9a\xb0\x00\f\x00" + + "\x00\xa8\xc0\x01\x10\x00\x00\x9a\xb0\x01\f\x00\x00\x8c\xa0\x00\x14\x00\x00\xa8\xc0\x00\x10\x00\x00\xa8\xc0\x01\x10\x00\x00\x8c\xa0\x00\x14LMT\x00+08\x00+09\x00+11\x00+12\x00+10\x00\x00" + + "\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\n<+10>-10\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xbb8\x81\x97\xc6\x04\x00\x00\xc6\x04\x00\x00\f\x00\x1c\x00Asia/Maga" + + "danUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00" + + "\x00\x00\x00\x00\x00\x00C\x00\x00\x00\v\x00\x00\x00\x10\xaa\x196\xa0\xb5\xa3\xa8\xe0\x15'7P\x16\x18k\xc0\x17\bj\xd0\x17\xf9\x9f@\x18\xe9\x9eP\x19\xda\xd2\xc0\x1a\xcc#P\x1b\xbc0p\x1c\xac!p\x1d" + + "\x9c\x12p\x1e\x8c\x03p\x1f{\xf4p k\xe5p![\xd6p\"K\xc7p#;\xb8p$+\xa9p%\x1b\x9ap&\v\x8bp'\x04\xb6\xf0'\xf4\xa7\xf0(\xe4\xa7\x00)xO\x00)ԉ\xf0*" + + "\xc4z\xf0+\xb4k\xf0,\xa4\\\xf0-\x94M\xf0.\x84>\xf0/t/\xf00d \xf01]Lp2r'p3=.p4R\tp5\x1d\x10p61\xebp6\xfc\xf2p8\x1b\a\xf08" + + "\xdc\xd4p9\xfa\xe9\xf0:\xbc\xb6p;\xda\xcb\xf0<\xa5\xd2\xf0=\xba\xad\xf0>\x85\xb4\xf0?\x9a\x8f\xf0@e\x96\xf0A\x83\xacpBEx\xf0Cc\x8epD%Z\xf0ECppF\x05<\xf0G" + + "#RpG\xeeYpI\x034pI\xce;pJ\xe3\x16pK\xae\x1dpL\xcc2\xf0M\x8d\xffpTK\xac\xe0W\x1b\x9c\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\b\a\x04\x04\x00\x00\x8d`\x00\x00\x00\x00\x8c\xa0" + + "\x00\x04\x00\x00\xa8\xc0\x01\b\x00\x00\x9a\xb0\x00\f\x00\x00\x9a\xb0\x00\f\x00\x00\xa8\xc0\x01\b\x00\x00\x9a\xb0\x01\f\x00\x00\x8c\xa0\x00\x04\x00\x00\xa8\xc0\x00\b\x00\x00\xa8\xc0\x01\b\x00\x00\x9a\xb0\x00\fLMT\x00" + + "+10\x00+12\x00+11\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00C\x00" + + "\x00\x00\v\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x196\xa0\xff\xff\xff\xff\xb5\xa3\xa8\xe0\x00\x00\x00\x00\x15'7P\x00\x00\x00\x00\x16\x18k\xc0\x00\x00\x00\x00\x17\bj\xd0\x00\x00\x00\x00\x17\xf9\x9f@\x00\x00\x00\x00\x18" + + "\xe9\x9eP\x00\x00\x00\x00\x19\xda\xd2\xc0\x00\x00\x00\x00\x1a\xcc#P\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x03p\x00\x00\x00\x00\x1f{\xf4p\x00" + + "\x00\x00\x00 k\xe5p\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\"K\xc7p\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\v\x8bp\x00\x00\x00\x00'" + + "\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xa7\xf0\x00\x00\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00)xO\x00\x00\x00\x00\x00)ԉ\xf0\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00,\xa4\\\xf0\x00" + + "\x00\x00\x00-\x94M\xf0\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t/\xf0\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Lp\x00\x00\x00\x002r'p\x00\x00\x00\x003=.p\x00\x00\x00\x004" + + "R\tp\x00\x00\x00\x005\x1d\x10p\x00\x00\x00\x0061\xebp\x00\x00\x00\x006\xfc\xf2p\x00\x00\x00\x008\x1b\a\xf0\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xfa\xe9\xf0\x00\x00\x00\x00:\xbc\xb6p\x00" + + "\x00\x00\x00;\xda\xcb\xf0\x00\x00\x00\x00<\xa5\xd2\xf0\x00\x00\x00\x00=\xba\xad\xf0\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x8f\xf0\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xacp\x00\x00\x00\x00B" + + "Ex\xf0\x00\x00\x00\x00Cc\x8ep\x00\x00\x00\x00D%Z\xf0\x00\x00\x00\x00ECpp\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Rp\x00\x00\x00\x00G\xeeYp\x00\x00\x00\x00I\x034p\x00" + + "\x00\x00\x00I\xce;p\x00\x00\x00\x00J\xe3\x16p\x00\x00\x00\x00K\xae\x1dp\x00\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M\x8d\xffp\x00\x00\x00\x00TK\xac\xe0\x00\x00\x00\x00W\x1b\x9c\x00\x00\x00\x00\x00\u007f" + + "\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\b\a\x04\x04\x00\x00\x8d`\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\xa8\xc0\x01\b\x00\x00\x9a\xb0\x00\f\x00\x00\x9a\xb0\x00\f\x00\x00\xa8\xc0\x01\b\x00\x00\x9a\xb0\x01\f\x00\x00\x8c\xa0\x00\x04\x00\x00" + + "\xa8\xc0\x00\b\x00\x00\xa8\xc0\x01\b\x00\x00\x9a\xb0\x00\fLMT\x00+10\x00+12\x00+11\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\n<+11>-11\nPK\x03\x04\n\x00\x00" + + "\x00\x00\x00\xf5F\x9cPB\x03\xf8\xfat\x01\x00\x00t\x01\x00\x00\f\x00\x1c\x00Asia/ColomboUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14" + + "\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\b\x00\x00\x00\x18\x80\x00\x00\x00\x87\x9d\xbd\x1c\xcbZ\x1c(\xcc" + + "\x95+\xa0\xd2u\x8081\xa6\x00(2q\x00 D?\xea(\u007f\xff\xff\xff\x01\x02\x03\x04\x02\x05\x06\x02\x02\x00\x00J\xdc\x00\x00\x00\x00J\xe4\x00\x04\x00\x00MX\x00\b\x00\x00T`\x01\x0e\x00\x00[h" + + "\x01\x12\x00\x00[h\x00\x12\x00\x00T`\x00\x0e\x00\x00MX\x00\bLMT\x00MMT\x00+0530\x00+06\x00+0630\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\b\x00\x00\x00\x18\xff\xff\xff\xffV\xb6\x99$\xff\xff\xff\xff\x87\x9d\xbd\x1c\xff\xff\xff\xff\xcbZ\x1c(\xff\xff\xff\xff̕+\xa0" + + "\xff\xff\xff\xff\xd2u\x808\x00\x00\x00\x001\xa6\x00(\x00\x00\x00\x002q\x00 \x00\x00\x00\x00D?\xea(\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x04\x02\x05\x06\x02\x02\x00\x00J\xdc\x00\x00\x00\x00J\xe4\x00" + + "\x04\x00\x00MX\x00\b\x00\x00T`\x01\x0e\x00\x00[h\x01\x12\x00\x00[h\x00\x12\x00\x00T`\x00\x0e\x00\x00MX\x00\bLMT\x00MMT\x00+0530\x00+06\x00+0630" + + "\x00\n<+0530>-5:30\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPO.\xd4X\xb7\x04\x00\x00\xb7\x04\x00\x00\x10\x00\x1c\x00Asia/Krasnoyars" + + "kUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00" + + "\x00\x00\x00\x00B\x00\x00\x00\v\x00\x00\x00\x10\xa1\xf9\r\xf2\xb5\xa3\xe1 \x15'o\x90\x16\x18\xa4\x00\x17\b\xa3\x10\x17\xf9׀\x18\xe9\u0590\x19\xdb\v\x00\x1a\xcc[\x90\x1b\xbch\xb0\x1c\xacY\xb0\x1d\x9cJ" + + "\xb0\x1e\x8c;\xb0\x1f|,\xb0 l\x1d\xb0!\\\x0e\xb0\"K\xff\xb0#;\xf0\xb0$+\xe1\xb0%\x1bҰ&\vð'\x04\xef0'\xf4\xe00(\xe4\xdf@)x\x87@)\xd4\xc20*ij" + + "0+\xb4\xa40,\xa4\x950-\x94\x860.\x84w0/th00dY01]\x84\xb02r_\xb03=f\xb04RA\xb05\x1dH\xb062#\xb06\xfd*\xb08\x1b@08\xdd\f" + + "\xb09\xfb\"0:\xbc\xee\xb0;\xdb\x040<\xa6\v0=\xba\xe60>\x85\xed0?\x9a\xc80@e\xcf0A\x83\xe4\xb0BE\xb10CcưD%\x930EC\xa8\xb0F\x05u0G#\x8a" + + "\xb0G\ue470I\x03l\xb0I\xces\xb0J\xe3N\xb0K\xaeU\xb0L\xcck0M\x8e7\xb0TK\xe5 \u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06" + + "\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\b\x04\x04\x00\x00W\x0e\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01" + + "\b\x00\x00bp\x00\f\x00\x00bp\x00\f\x00\x00p\x80\x01\b\x00\x00bp\x01\f\x00\x00T`\x00\x04\x00\x00p\x80\x00\b\x00\x00p\x80\x01\b\x00\x00bp\x00\fLMT\x00+06\x00+08" + + "\x00+07\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\v\x00\x00\x00\x10" + + "\xff\xff\xff\xff\xa1\xf9\r\xf2\xff\xff\xff\xff\xb5\xa3\xe1 \x00\x00\x00\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\b\xa3\x10\x00\x00\x00\x00\x17\xf9׀\x00\x00\x00\x00\x18\xe9\u0590\x00\x00\x00\x00" + + "\x19\xdb\v\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbch\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00\x00\x00\x00 l\x1d\xb0" + + "\x00\x00\x00\x00!\\\x0e\xb0\x00\x00\x00\x00\"K\xff\xb0\x00\x00\x00\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1bҰ\x00\x00\x00\x00&\vð\x00\x00\x00\x00'\x04\xef0\x00\x00\x00\x00" + + "'\xf4\xe00\x00\x00\x00\x00(\xe4\xdf@\x00\x00\x00\x00)x\x87@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*ij0\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00,\xa4\x950\x00\x00\x00\x00-\x94\x860" + + "\x00\x00\x00\x00.\x84w0\x00\x00\x00\x00/th0\x00\x00\x00\x000dY0\x00\x00\x00\x001]\x84\xb0\x00\x00\x00\x002r_\xb0\x00\x00\x00\x003=f\xb0\x00\x00\x00\x004RA\xb0\x00\x00\x00\x00" + + "5\x1dH\xb0\x00\x00\x00\x0062#\xb0\x00\x00\x00\x006\xfd*\xb0\x00\x00\x00\x008\x1b@0\x00\x00\x00\x008\xdd\f\xb0\x00\x00\x00\x009\xfb\"0\x00\x00\x00\x00:\xbc\xee\xb0\x00\x00\x00\x00;\xdb\x040" + + "\x00\x00\x00\x00<\xa6\v0\x00\x00\x00\x00=\xba\xe60\x00\x00\x00\x00>\x85\xed0\x00\x00\x00\x00?\x9a\xc80\x00\x00\x00\x00@e\xcf0\x00\x00\x00\x00A\x83\xe4\xb0\x00\x00\x00\x00BE\xb10\x00\x00\x00\x00" + + "Ccư\x00\x00\x00\x00D%\x930\x00\x00\x00\x00EC\xa8\xb0\x00\x00\x00\x00F\x05u0\x00\x00\x00\x00G#\x8a\xb0\x00\x00\x00\x00G\ue470\x00\x00\x00\x00I\x03l\xb0\x00\x00\x00\x00I\xces\xb0" + + "\x00\x00\x00\x00J\xe3N\xb0\x00\x00\x00\x00K\xaeU\xb0\x00\x00\x00\x00L\xcck0\x00\x00\x00\x00M\x8e7\xb0\x00\x00\x00\x00TK\xe5 \x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\b\x04\x04\x00\x00W\x0e\x00\x00" + + "\x00\x00T`\x00\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\f\x00\x00bp\x00\f\x00\x00p\x80\x01\b\x00\x00bp\x01\f\x00\x00T`\x00\x04\x00\x00p\x80\x00\b\x00\x00p\x80\x01\b\x00\x00bp\x00\f" + + "LMT\x00+06\x00+08\x00+07\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\n<+07>-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x9dB\xa1\x85\x8e\x04\x00\x00\x8e\x04" + + "\x00\x00\x0e\x00\x1c\x00Asia/KamchatkaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x00\t\x00\x00\x00\x10\xa7R\x96ĵ\xa3\x9a\xd0\x15')@\x16\x18]\xb0\x17\b\\\xc0\x17\xf9\x910\x18\xe9\x90@" + + "\x19\xdaİ\x1a\xcc\x15@\x1b\xbc\"`\x1c\xac\x13`\x1d\x9c\x04`\x1e\x8b\xf5`\x1f{\xe6` k\xd7`![\xc8`\"K\xb9`#;\xaa`$+\x9b`%\x1b\x8c`&\v}`'\x04\xa8\xe0" + + "'\xf4\x99\xe0(\xe4\x98\xf0)x@\xf0)\xd4{\xe0*\xc4l\xe0+\xb4]\xe0,\xa4N\xe0-\x94?\xe0.\x840\xe0/t!\xe00d\x12\xe01]>`2r\x19`3= `4Q\xfb`" + + "5\x1d\x02`61\xdd`6\xfc\xe4`8\x1a\xf9\xe08\xdc\xc6`9\xfa\xdb\xe0:\xbc\xa8`;ڽ\xe0<\xa5\xc4\xe0=\xba\x9f\xe0>\x85\xa6\xe0?\x9a\x81\xe0@e\x88\xe0A\x83\x9e`BEj\xe0" + + "Cc\x80`D%L\xe0ECb`F\x05.\xe0G#D`G\xeeK`I\x03&`I\xce-`J\xe3\b`K\xae\x0f`L\xcc2\xf0M\x8d\xffp\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x04\x00\x00\x94" + + "\xbc\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00\xb6\xd0\x01\b\x00\x00\xa8\xc0\x00\f\x00\x00\xa8\xc0\x00\f\x00\x00\xb6\xd0\x01\b\x00\x00\xa8\xc0\x01\f\x00\x00\x9a\xb0\x00\x04\x00\x00\xa8\xc0\x00\fLMT\x00+11\x00+" + + "13\x00+12\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x00\t\x00\x00\x00\x10" + + "\xff\xff\xff\xff\xa7R\x96\xc4\xff\xff\xff\xff\xb5\xa3\x9a\xd0\x00\x00\x00\x00\x15')@\x00\x00\x00\x00\x16\x18]\xb0\x00\x00\x00\x00\x17\b\\\xc0\x00\x00\x00\x00\x17\xf9\x910\x00\x00\x00\x00\x18\xe9\x90@\x00\x00\x00\x00" + + "\x19\xdaİ\x00\x00\x00\x00\x1a\xcc\x15@\x00\x00\x00\x00\x1b\xbc\"`\x00\x00\x00\x00\x1c\xac\x13`\x00\x00\x00\x00\x1d\x9c\x04`\x00\x00\x00\x00\x1e\x8b\xf5`\x00\x00\x00\x00\x1f{\xe6`\x00\x00\x00\x00 k\xd7`" + + "\x00\x00\x00\x00![\xc8`\x00\x00\x00\x00\"K\xb9`\x00\x00\x00\x00#;\xaa`\x00\x00\x00\x00$+\x9b`\x00\x00\x00\x00%\x1b\x8c`\x00\x00\x00\x00&\v}`\x00\x00\x00\x00'\x04\xa8\xe0\x00\x00\x00\x00" + + "'\xf4\x99\xe0\x00\x00\x00\x00(\xe4\x98\xf0\x00\x00\x00\x00)x@\xf0\x00\x00\x00\x00)\xd4{\xe0\x00\x00\x00\x00*\xc4l\xe0\x00\x00\x00\x00+\xb4]\xe0\x00\x00\x00\x00,\xa4N\xe0\x00\x00\x00\x00-\x94?\xe0" + + "\x00\x00\x00\x00.\x840\xe0\x00\x00\x00\x00/t!\xe0\x00\x00\x00\x000d\x12\xe0\x00\x00\x00\x001]>`\x00\x00\x00\x002r\x19`\x00\x00\x00\x003= `\x00\x00\x00\x004Q\xfb`\x00\x00\x00\x00" + + "5\x1d\x02`\x00\x00\x00\x0061\xdd`\x00\x00\x00\x006\xfc\xe4`\x00\x00\x00\x008\x1a\xf9\xe0\x00\x00\x00\x008\xdc\xc6`\x00\x00\x00\x009\xfa\xdb\xe0\x00\x00\x00\x00:\xbc\xa8`\x00\x00\x00\x00;ڽ\xe0" + + "\x00\x00\x00\x00<\xa5\xc4\xe0\x00\x00\x00\x00=\xba\x9f\xe0\x00\x00\x00\x00>\x85\xa6\xe0\x00\x00\x00\x00?\x9a\x81\xe0\x00\x00\x00\x00@e\x88\xe0\x00\x00\x00\x00A\x83\x9e`\x00\x00\x00\x00BEj\xe0\x00\x00\x00\x00" + + "Cc\x80`\x00\x00\x00\x00D%L\xe0\x00\x00\x00\x00ECb`\x00\x00\x00\x00F\x05.\xe0\x00\x00\x00\x00G#D`\x00\x00\x00\x00G\xeeK`\x00\x00\x00\x00I\x03&`\x00\x00\x00\x00I\xce-`" + + "\x00\x00\x00\x00J\xe3\b`\x00\x00\x00\x00K\xae\x0f`\x00\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M\x8d\xffp\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x04\x00\x00\x94\xbc\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00\xb6" + + "\xd0\x01\b\x00\x00\xa8\xc0\x00\f\x00\x00\xa8\xc0\x00\f\x00\x00\xb6\xd0\x01\b\x00\x00\xa8\xc0\x01\f\x00\x00\x9a\xb0\x00\x04\x00\x00\xa8\xc0\x00\fLMT\x00+11\x00+13\x00+12\x00\x00\x00\x00\x00\x01" + + "\x01\x01\x01\x01\n<+12>-12\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP{\xad\x05\xdc\xfe\x00\x00\x00\xfe\x00\x00\x00\x12\x00\x1c\x00Asia/Ujung_Panda" + + "ngUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x15\xa1\xf2]\x90\xba\x16Րˈ\x1d\x80\xd2V\xeep\x01\x02\x03\x04\x00\x00o\xf0\x00\x00\x00\x00o\xf0\x00\x04\x00\x00p\x80\x00\b\x00\x00~\x90\x00\f\x00\x00" + + "p\x80\x00\x10LMT\x00MMT\x00+08\x00+09\x00WITA\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x04\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff\xa1\xf2]\x90\xff\xff\xff\xff\xba\x16Ր\xff\xff\xff\xffˈ\x1d\x80\xff\xff\xff\xff\xd2V\xeep\x01\x02\x03\x04\x00\x00o\xf0\x00\x00\x00\x00o\xf0\x00\x04\x00\x00p" + + "\x80\x00\b\x00\x00~\x90\x00\f\x00\x00p\x80\x00\x10LMT\x00MMT\x00+08\x00+09\x00WITA\x00\nWITA-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP@\xca" + + "5\xe2c\x01\x00\x00c\x01\x00\x00\f\x00\x1c\x00Asia/JakartaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\a\x00\x00\x00 \x80\x00\x00\x00\xa9x\x85\xe0\xba\x16\xde`˿\x83\x88\xd2V\xeep\xd7<" + + "\xc6\b\xda\xff&\x00\xf4\xb5\xbe\x88\x01\x02\x03\x04\x03\x05\x03\x06\x00\x00d \x00\x00\x00\x00d \x00\x04\x00\x00g \x00\b\x00\x00ix\x00\x0e\x00\x00~\x90\x00\x14\x00\x00p\x80\x00\x18\x00\x00bp\x00\x1c" + + "LMT\x00BMT\x00+0720\x00+0730\x00+09\x00+08\x00WIB\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\a\x00\x00\x00 \xff\xff\xff\xff?fI`\xff\xff\xff\xff\xa9x\x85\xe0\xff\xff\xff\xff\xba\x16\xde`\xff\xff\xff\xff˿\x83\x88\xff\xff\xff\xff\xd2V\xeep\xff\xff\xff\xff" + + "\xd7<\xc6\b\xff\xff\xff\xff\xda\xff&\x00\xff\xff\xff\xff\xf4\xb5\xbe\x88\x01\x02\x03\x04\x03\x05\x03\x06\x00\x00d \x00\x00\x00\x00d \x00\x04\x00\x00g \x00\b\x00\x00ix\x00\x0e\x00\x00~\x90\x00\x14\x00\x00" + + "p\x80\x00\x18\x00\x00bp\x00\x1cLMT\x00BMT\x00+0720\x00+0730\x00+09\x00+08\x00WIB\x00\nWIB-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5" + + "F\x9cP\x88括\x1d\x01\x00\x00\x1d\x01\x00\x00\f\x00\x1c\x00Asia/KolkataUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00T" + + "Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\x12\x80\x00\x00\x00\x87\x9d\xbc\xba\xcaی(\xcc\x05q\x18\xcc" + + "\x952\xa8\xd2t\x12\x98\x01\x02\x03\x02\x03\x02\x00\x00R\xd8\x00\x00\x00\x00KF\x00\x04\x00\x00MX\x00\b\x00\x00[h\x01\fLMT\x00MMT\x00IST\x00+0630\x00TZif2" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x05\x00\x00\x00\x16\xff\xff\xff\xff&\xba\x18(\xff\xff\xff\xffC\xe7\xeb0\xff\xff\xff\xff\x87" + + "\x9d\xbc\xba\xff\xff\xff\xff\xcaی(\xff\xff\xff\xff\xcc\x05q\x18\xff\xff\xff\xff̕2\xa8\xff\xff\xff\xff\xd2t\x12\x98\x01\x02\x03\x04\x03\x04\x03\x00\x00R\xd8\x00\x00\x00\x00R\xd0\x00\x04\x00\x00KF\x00\b" + + "\x00\x00MX\x00\f\x00\x00[h\x01\x10LMT\x00HMT\x00MMT\x00IST\x00+0630\x00\nIST-5:30\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa2\xe1" + + "z\xed\xd0\x00\x00\x00\xd0\x00\x00\x00\n\x00\x1c\x00Asia/KabulUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x0e\x80\x00\x00\x00\xd0\xf9\xd7@\u007f\xff\xff\xff\x01\x02\x02\x00\x00@\xe0\x00\x00\x00\x008" + + "@\x00\x04\x00\x00?H\x00\bLMT\x00+04\x00+0430\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00" + + "\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffi\x86\x9a\xa0\xff\xff\xff\xff\xd0\xf9\xd7@\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x02\x00\x00@\xe0\x00\x00\x00\x008@\x00\x04\x00\x00?H\x00\bLMT\x00+04\x00" + + "+0430\x00\n<+0430>-4:30\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\v\xb8\xfc?\xed\x03\x00\x00\xed\x03\x00\x00\t\x00\x1c\x00Asia/OralU" + + "T\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00" + + "\x00\x004\x00\x00\x00\n\x00\x00\x00\x14\xaa\x19\x93ܵ\xa4\vP\x15'\x8b\xb0\x16\x18\xc0 \x17\b\xb1 \x17\xf9\xf3\xa0\x18\xe9\xf2\xb0\x19\xdb' \x1a\xccw\xb0\x1b\xbc\x84\xd0\x1c\xacu\xd0\x1d\x9cf\xd0\x1e" + + "\x8cW\xd0\x1f|H\xd0 l9\xd0!\\*\xd0\"L\x1b\xd0#<\f\xd0$+\xfd\xd0%\x1b\xfc\xe0&\v\xed\xe0'\x05\x19`'\xf5\n`(\xe4\xfb`)x\xa3`)\xd4\xdeP*\xc4\xdd`+" + + "\xb4\xce`,\xa4\xbf`-\x94\xb0`.\x84\xa1`/t\x92`0d\x83`1]\xae\xe02r\x89\xe03=\x90\xe04Rk\xe05\x1dr\xe062M\xe06\xfdT\xe08\x1bj`8\xdd6\xe09" + + "\xfbL`:\xbd\x18\xe0;\xdb.`<\xa65`=\xbb\x10`>\x86\x17`?\x9a\xf2`@e\xf9`A\x84\x0e\xe0\u007f\xff\xff\xff\x01\x02\x03\x04\x03\x02\x03\x02\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\b\a" + + "\b\a\b\x05\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\x05\x05\x00\x000$\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00T`\x00" + + "\f\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00FP\x01\b\x00\x008@\x00\x10\x00\x00FP\x00\bLMT\x00+03\x00+05\x00+06\x00+04\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01" + + "\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x004\x00\x00\x00\n\x00\x00\x00\x14\xff\xff\xff\xff\xaa\x19\x93\xdc\xff\xff\xff\xff\xb5\xa4\v" + + "P\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00" + + "\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b" + + "\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\x19`\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00" + + "\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xdd`\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xbf`\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\xa1`\x00\x00\x00\x00/t\x92" + + "`\x00\x00\x00\x000d\x83`\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r\x89\xe0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004Rk\xe0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062M\xe0\x00\x00\x00" + + "\x006\xfdT\xe0\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`\x00\x00\x00\x00<\xa65`\x00\x00\x00\x00=\xbb\x10" + + "`\x00\x00\x00\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x04\x03\x02\x03\x02\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\a" + + "\b\a\b\a\b\x05\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\x05\x05\x00\x000$\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00T" + + "`\x00\f\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00FP\x01\b\x00\x008@\x00\x10\x00\x00FP\x00\bLMT\x00+03\x00+05\x00+06\x00+04\x00\x00\x00\x00\x00\x00\x01\x01" + + "\x01\x01\x01\n<+05>-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x05\xdb\xebb\xdd\x00\x00\x00\xdd\x00\x00\x00\r\x00\x1c\x00Asia/JayapuraUT\t\x00\x03" + + "nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00" + + "\x00\x00\x04\x00\x00\x00\x12\xba\x16\xc1\x98\xd0X\xb9\xf0\xf4\xb5\xa2h\x01\x02\x03\x00\x00\x83\xe8\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x85\x98\x00\b\x00\x00~\x90\x00\x0eLMT\x00+09\x00+0930\x00" + + "WIT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\xba\x16\xc1\x98\xff\xff\xff\xff" + + "\xd0X\xb9\xf0\xff\xff\xff\xff\xf4\xb5\xa2h\x01\x02\x03\x00\x00\x83\xe8\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x85\x98\x00\b\x00\x00~\x90\x00\x0eLMT\x00+09\x00+0930\x00WIT\x00\nWI" + + "T-9\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP{\xc0\xa0\xd4a\x01\x00\x00a\x01\x00\x00\x0e\x00\x1c\x00Asia/PontianakUT\t\x00\x03nӧ^nӧ" + + "^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\a\x00\x00\x00\x1f" + + "\x8b\xff\x8e\x00\xba\x16\xdf\x00\xcby\xa4\b\xd2V\xeep\xd7<\xc6\b\xda\xff&\x00\xf4\xb5\xbe\x88!\xdat\x80\x01\x02\x03\x02\x04\x02\x05\x06\x00\x00f\x80\x00\x00\x00\x00f\x80\x00\x04\x00\x00ix\x00\b\x00\x00" + + "~\x90\x00\x0e\x00\x00p\x80\x00\x12\x00\x00p\x80\x00\x16\x00\x00bp\x00\x1bLMT\x00PMT\x00+0730\x00+09\x00+08\x00WITA\x00WIB\x00TZif2\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\a\x00\x00\x00\x1f\xff\xff\xff\xff\x8b\xff\x8e\x00\xff\xff\xff\xff\xba\x16\xdf\x00\xff\xff\xff\xff\xcby\xa4" + + "\b\xff\xff\xff\xff\xd2V\xeep\xff\xff\xff\xff\xd7<\xc6\b\xff\xff\xff\xff\xda\xff&\x00\xff\xff\xff\xff\xf4\xb5\xbe\x88\x00\x00\x00\x00!\xdat\x80\x01\x02\x03\x02\x04\x02\x05\x06\x00\x00f\x80\x00\x00\x00\x00f\x80\x00" + + "\x04\x00\x00ix\x00\b\x00\x00~\x90\x00\x0e\x00\x00p\x80\x00\x12\x00\x00p\x80\x00\x16\x00\x00bp\x00\x1bLMT\x00PMT\x00+0730\x00+09\x00+08\x00WITA\x00WI" + + "B\x00\nWIB-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP{\xad\x05\xdc\xfe\x00\x00\x00\xfe\x00\x00\x00\r\x00\x1c\x00Asia/MakassarUT\t\x00\x03nӧ" + + "^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05" + + "\x00\x00\x00\x15\xa1\xf2]\x90\xba\x16Րˈ\x1d\x80\xd2V\xeep\x01\x02\x03\x04\x00\x00o\xf0\x00\x00\x00\x00o\xf0\x00\x04\x00\x00p\x80\x00\b\x00\x00~\x90\x00\f\x00\x00p\x80\x00\x10LMT\x00MM" + + "T\x00+08\x00+09\x00WITA\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x15\xff" + + "\xff\xff\xff\xa1\xf2]\x90\xff\xff\xff\xff\xba\x16Ր\xff\xff\xff\xffˈ\x1d\x80\xff\xff\xff\xff\xd2V\xeep\x01\x02\x03\x04\x00\x00o\xf0\x00\x00\x00\x00o\xf0\x00\x04\x00\x00p\x80\x00\b\x00\x00~\x90\x00\f\x00" + + "\x00p\x80\x00\x10LMT\x00MMT\x00+08\x00+09\x00WITA\x00\nWITA-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa9YT\x17\v\x04\x00\x00\v\x04\x00\x00" + + "\f\x00\x1c\x00Asia/TbilisiUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00\v\x00\x00\x00\x15\x80\x00\x00\x00\xaa\x19\x9a\x01\xe7\xda\fP\x15'\x99\xc0\x16\x18\xce0\x17\b\xcd@\x17\xfa\x01\xb0\x18\xea\x00\xc0" + + "\x19\xdb50\x1a̅\xc0\x1b\xbc\x92\xe0\x1c\xac\x83\xe0\x1d\x9ct\xe0\x1e\x8ce\xe0\x1f|V\xe0 lG\xe0!\\8\xe0\"L)\xe0#<\x1a\xe0$,\v\xe0%\x1b\xfc\xe0&\v\xed\xe0'\x05\x19`" + + "'\xf5\n`(\xe5\tp)\xd4\xdeP*\xc4\xc1@+\xb4\xc0P,\xa4\xa3@-\x94\xa2P.\x84\x85@/tv@0dY01]\x92\xc03=f\xb04RA\xb05\x1dV\xc062#\xb0" + + "6\xfd8\xc08\x1b@08\xdd\x1a\xc09\xfb\"0:\xbc\xfc\xc0;\xdb\x040<\xa6\x19@=\xba\xe60>\x85\xfb@?\x9a\xc80@e\xdd@@\xddǰA\x84\x1c\xf0BE\xe9p\u007f\xff\xff\xff" + + "\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\b\t\x02\t\x02\t\x04\x03\x04\x03\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\t\b\x04\x04\x00\x00)\xff\x00\x00\x00" + + "\x00)\xff\x00\x04\x00\x00*0\x00\t\x00\x00FP\x01\r\x00\x008@\x00\x11\x00\x008@\x00\x11\x00\x00FP\x01\r\x00\x008@\x01\x11\x00\x00*0\x00\t\x00\x008@\x01\x11\x00\x008@\x00\x11L" + + "MT\x00TBMT\x00+03\x00+05\x00+04\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00" + + "\x00\x00\x00\x00\x00\x005\x00\x00\x00\v\x00\x00\x00\x15\xff\xff\xff\xffV\xb6\xba\x01\xff\xff\xff\xff\xaa\x19\x9a\x01\xff\xff\xff\xff\xe7\xda\fP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17" + + "\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00" + + "\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%" + + "\x1b\xfc\xe0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\x19`\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe5\tp\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xc1@\x00\x00\x00\x00+\xb4\xc0P\x00" + + "\x00\x00\x00,\xa4\xa3@\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x85@\x00\x00\x00\x00/tv@\x00\x00\x00\x000dY0\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x003=f\xb0\x00\x00\x00\x004" + + "RA\xb0\x00\x00\x00\x005\x1dV\xc0\x00\x00\x00\x0062#\xb0\x00\x00\x00\x006\xfd8\xc0\x00\x00\x00\x008\x1b@0\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb\"0\x00\x00\x00\x00:\xbc\xfc\xc0\x00" + + "\x00\x00\x00;\xdb\x040\x00\x00\x00\x00<\xa6\x19@\x00\x00\x00\x00=\xba\xe60\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xc80\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00@\xddǰ\x00\x00\x00\x00A" + + "\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\b\t\x02\t\x02\t\x04\x03\x04\x03\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\t\b\x04\x04\x00\x00)\xff\x00\x00\x00\x00)\xff\x00\x04\x00\x00*0\x00\t\x00\x00FP\x01\r\x00\x008@\x00\x11\x00\x008@\x00\x11\x00\x00FP\x01\r\x00\x008@\x01\x11" + + "\x00\x00*0\x00\t\x00\x008@\x01\x11\x00\x008@\x00\x11LMT\x00TBMT\x00+03\x00+05\x00+04\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\n<+04>-4\nP" + + "K\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\b\x01\xc8*\u007f\x01\x00\x00\u007f\x01\x00\x00\x0e\x00\x1c\x00Asia/SingaporeUT\t\x00\x03nӧ^nӧ^ux\v\x00" + + "\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\b\x00\x00\x00 \x80\x00\x00\x00\x86" + + "\x83\x85\xa3\xbagN\x90\xc0\n\xe4`ʳ\xe5`ˑ_\b\xd2Hm\xf0\x16\x91\xf5\b\u007f\xff\xff\xff\x01\x02\x03\x04\x05\x06\x05\a\a\x00\x00a]\x00\x00\x00\x00a]\x00\x04\x00\x00bp\x00\b\x00\x00" + + "g \x01\f\x00\x00g \x00\f\x00\x00ix\x00\x12\x00\x00~\x90\x00\x18\x00\x00p\x80\x00\x1cLMT\x00SMT\x00+07\x00+0720\x00+0730\x00+09\x00+08\x00" + + "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\b\x00\x00\x00 \xff\xff\xff\xff~6S\xa3\xff\xff\xff\xff\x86\x83\x85\xa3" + + "\xff\xff\xff\xff\xbagN\x90\xff\xff\xff\xff\xc0\n\xe4`\xff\xff\xff\xffʳ\xe5`\xff\xff\xff\xffˑ_\b\xff\xff\xff\xff\xd2Hm\xf0\x00\x00\x00\x00\x16\x91\xf5\b\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x04" + + "\x05\x06\x05\a\a\x00\x00a]\x00\x00\x00\x00a]\x00\x04\x00\x00bp\x00\b\x00\x00g \x01\f\x00\x00g \x00\f\x00\x00ix\x00\x12\x00\x00~\x90\x00\x18\x00\x00p\x80\x00\x1cLMT\x00SMT" + + "\x00+07\x00+0720\x00+0730\x00+09\x00+08\x00\n<+08>-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPy\x84\xe1i1\x02\x00\x001\x02\x00\x00" + + "\v\x00\x1c\x00Asia/HarbinUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x03\x00\x00\x00\f\x80\x00\x00\x00\xa0\x97\xa2\x80\xa1y\x04\xf0\xc8Y^\x80\xc9\t\xf9p\xc9ӽ\x00\xcb\x05\x8a\xf0\xcb|@\x00\xd2" + + ";>\xf0Ӌ{\x80\xd4B\xad\xf0\xd5E\"\x00\xd6L\xbf\xf0\xd7<\xbf\x00\xd8\x06fp\xd9\x1d\xf2\x80\xd9A|\xf0\x1e\xbaR \x1fi\x9b\x90 ~\x84\xa0!I}\x90\"g\xa1 #)_\x90$" + + "G\x83 %\x12|\x10&'e &\xf2^\x10(\aG (\xd2@\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00q\xd7\x00\x00\x00\x00" + + "~\x90\x01\x04\x00\x00p\x80\x00\bLMT\x00CDT\x00CST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00" + + "\x00\x03\x00\x00\x00\f\xff\xff\xff\xff~6C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff\xff\xa1y\x04\xf0\xff\xff\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9\t\xf9p\xff\xff\xff\xff\xc9ӽ\x00\xff\xff\xff\xff\xcb\x05" + + "\x8a\xf0\xff\xff\xff\xff\xcb|@\x00\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xffӋ{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff" + + "\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00\x00\x1e\xbaR \x00\x00\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 ~\x84\xa0\x00\x00\x00\x00!I}\x90\x00\x00\x00\x00\"g" + + "\xa1 \x00\x00\x00\x00#)_\x90\x00\x00\x00\x00$G\x83 \x00\x00\x00\x00%\x12|\x10\x00\x00\x00\x00&'e \x00\x00\x00\x00&\xf2^\x10\x00\x00\x00\x00(\aG \x00\x00\x00\x00(\xd2@\x10\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\bLMT\x00CDT\x00CST\x00\nCS" + + "T-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPw:\xb4ե\x00\x00\x00\xa5\x00\x00\x00\f\x00\x1c\x00Asia/KashgarUT\t\x00\x03nӧ^nӧ^u" + + "x\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xb0\xfe" + + "\xbad\u007f\xff\xff\xff\x01\x01\x00\x00R\x1c\x00\x00\x00\x00T`\x00\x04LMT\x00+06\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xb0\xfe\xbad\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x00R\x1c\x00\x00\x00\x00T`\x00\x04LMT\x00+06\x00\n<+06>-6\nP" + + "K\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPq\x16UAQ\x01\x00\x00Q\x01\x00\x00\n\x00\x1c\x00Asia/DhakaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01" + + "\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x06\x00\x00\x00\x1c\x80\x00\x00\x00\xcaۆ\xb0\xcc" + + "\x05q\x18̕2\xa8ݨҘJ;\xc4\x10K<ؐ\u007f\xff\xff\xff\x01\x02\x03\x02\x04\x05\x04\x04\x00\x00T\xc4\x00\x00\x00\x00R\xd0\x00\x04\x00\x00[h\x00\b\x00\x00MX\x00\x0e\x00\x00T`\x00" + + "\x14\x00\x00bp\x01\x18LMT\x00HMT\x00+0630\x00+0530\x00+06\x00+07\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x06\x00\x00\x00\x1c\xff\xff\xff\xffi\x86\x86\xbc\xff\xff\xff\xff\xcaۆ\xb0\xff\xff\xff\xff\xcc\x05q\x18\xff\xff\xff\xff̕2\xa8\xff\xff\xff\xffݨҘ\x00" + + "\x00\x00\x00J;\xc4\x10\x00\x00\x00\x00K<ؐ\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x04\x05\x04\x04\x00\x00T\xc4\x00\x00\x00\x00R\xd0\x00\x04\x00\x00[h\x00\b\x00\x00MX\x00\x0e\x00\x00T`\x00" + + "\x14\x00\x00bp\x01\x18LMT\x00HMT\x00+0630\x00+0530\x00+06\x00+07\x00\n<+06>-6\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x9f\x8d" + + "\xa7i\xb7\x04\x00\x00\xb7\x04\x00\x00\f\x00\x1c\x00Asia/YakutskUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\v\x00\x00\x00\x10\xa1\xdb\xea^\xb5\xa3\xc5\x00\x15'Sp\x16\x18\x87\xe0\x17\b\x86\xf0\x17\xf9" + + "\xbb`\x18\xe9\xbap\x19\xda\xee\xe0\x1a\xcc?p\x1b\xbcL\x90\x1c\xac=\x90\x1d\x9c.\x90\x1e\x8c\x1f\x90\x1f|\x10\x90 l\x01\x90![\xf2\x90\"K\xe3\x90#;Ԑ$+Ő%\x1b\xb6\x90&\v" + + "\xa7\x90'\x04\xd3\x10'\xf4\xc4\x10(\xe4\xc3 )xk )Ԧ\x10*ė\x10+\xb4\x88\x10,\xa4y\x10-\x94j\x10.\x84[\x10/tL\x100d=\x101]h\x902rC\x903=" + + "J\x904R%\x905\x1d,\x9062\a\x906\xfd\x0e\x908\x1b$\x108\xdc\xf0\x909\xfb\x06\x10:\xbcҐ;\xda\xe8\x10<\xa5\xef\x10=\xba\xca\x10>\x85\xd1\x10?\x9a\xac\x10@e\xb3\x10A\x83" + + "ȐBE\x95\x10Cc\xaa\x90D%w\x10EC\x8c\x90F\x05Y\x10G#n\x90G\xeeu\x90I\x03P\x90I\xceW\x90J\xe32\x90K\xae9\x90L\xccO\x10M\x8e\x1b\x90TK\xc9\x00\u007f\xff" + + "\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\b\x04\x04\x00\x00y\xa2\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\f\x00\x00~\x90\x00\f\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x01\f\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0" + + "\x00\b\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\fLMT\x00+08\x00+10\x00+09\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\v\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xdb\xea^\xff\xff\xff\xff\xb5\xa3\xc5\x00\x00\x00\x00\x00\x15'Sp\x00\x00\x00\x00\x16\x18\x87\xe0\x00\x00\x00" + + "\x00\x17\b\x86\xf0\x00\x00\x00\x00\x17\xf9\xbb`\x00\x00\x00\x00\x18\xe9\xbap\x00\x00\x00\x00\x19\xda\xee\xe0\x00\x00\x00\x00\x1a\xcc?p\x00\x00\x00\x00\x1b\xbcL\x90\x00\x00\x00\x00\x1c\xac=\x90\x00\x00\x00\x00\x1d\x9c." + + "\x90\x00\x00\x00\x00\x1e\x8c\x1f\x90\x00\x00\x00\x00\x1f|\x10\x90\x00\x00\x00\x00 l\x01\x90\x00\x00\x00\x00![\xf2\x90\x00\x00\x00\x00\"K\xe3\x90\x00\x00\x00\x00#;Ԑ\x00\x00\x00\x00$+Ő\x00\x00\x00" + + "\x00%\x1b\xb6\x90\x00\x00\x00\x00&\v\xa7\x90\x00\x00\x00\x00'\x04\xd3\x10\x00\x00\x00\x00'\xf4\xc4\x10\x00\x00\x00\x00(\xe4\xc3 \x00\x00\x00\x00)xk \x00\x00\x00\x00)Ԧ\x10\x00\x00\x00\x00*ė" + + "\x10\x00\x00\x00\x00+\xb4\x88\x10\x00\x00\x00\x00,\xa4y\x10\x00\x00\x00\x00-\x94j\x10\x00\x00\x00\x00.\x84[\x10\x00\x00\x00\x00/tL\x10\x00\x00\x00\x000d=\x10\x00\x00\x00\x001]h\x90\x00\x00\x00" + + "\x002rC\x90\x00\x00\x00\x003=J\x90\x00\x00\x00\x004R%\x90\x00\x00\x00\x005\x1d,\x90\x00\x00\x00\x0062\a\x90\x00\x00\x00\x006\xfd\x0e\x90\x00\x00\x00\x008\x1b$\x10\x00\x00\x00\x008\xdc\xf0" + + "\x90\x00\x00\x00\x009\xfb\x06\x10\x00\x00\x00\x00:\xbcҐ\x00\x00\x00\x00;\xda\xe8\x10\x00\x00\x00\x00<\xa5\xef\x10\x00\x00\x00\x00=\xba\xca\x10\x00\x00\x00\x00>\x85\xd1\x10\x00\x00\x00\x00?\x9a\xac\x10\x00\x00\x00" + + "\x00@e\xb3\x10\x00\x00\x00\x00A\x83Ȑ\x00\x00\x00\x00BE\x95\x10\x00\x00\x00\x00Cc\xaa\x90\x00\x00\x00\x00D%w\x10\x00\x00\x00\x00EC\x8c\x90\x00\x00\x00\x00F\x05Y\x10\x00\x00\x00\x00G#n" + + "\x90\x00\x00\x00\x00G\xeeu\x90\x00\x00\x00\x00I\x03P\x90\x00\x00\x00\x00I\xceW\x90\x00\x00\x00\x00J\xe32\x90\x00\x00\x00\x00K\xae9\x90\x00\x00\x00\x00L\xccO\x10\x00\x00\x00\x00M\x8e\x1b\x90\x00\x00\x00" + + "\x00TK\xc9\x00\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\b\x04\x04\x00\x00y\xa2\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\f\x00\x00~\x90\x00\f\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x01" + + "\f\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x00\b\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\fLMT\x00+08\x00+10\x00+09\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\n<+09>-9" + + "\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPl\x13\x82S\u007f\x01\x00\x00\u007f\x01\x00\x00\x11\x00\x1c\x00Asia/Kuala_LumpurUT\t\x00\x03nӧ^nӧ" + + "^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\b\x00\x00\x00 " + + "\x80\x00\x00\x00\x86\x83\x85\xa3\xbagN\x90\xc0\n\xe4`ʳ\xe5`ˑ_\b\xd2Hm\xf0\x16\x91\xf5\b\u007f\xff\xff\xff\x01\x02\x03\x04\x05\x06\x05\a\a\x00\x00_V\x00\x00\x00\x00a]\x00\x04\x00\x00b" + + "p\x00\b\x00\x00g \x01\f\x00\x00g \x00\f\x00\x00ix\x00\x12\x00\x00~\x90\x00\x18\x00\x00p\x80\x00\x1cLMT\x00SMT\x00+07\x00+0720\x00+0730\x00+09" + + "\x00+08\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\b\x00\x00\x00 \xff\xff\xff\xff~6U\xaa\xff\xff\xff" + + "\xff\x86\x83\x85\xa3\xff\xff\xff\xff\xbagN\x90\xff\xff\xff\xff\xc0\n\xe4`\xff\xff\xff\xffʳ\xe5`\xff\xff\xff\xffˑ_\b\xff\xff\xff\xff\xd2Hm\xf0\x00\x00\x00\x00\x16\x91\xf5\b\x00\x00\x00\x00\u007f\xff\xff" + + "\xff\x01\x02\x03\x04\x05\x06\x05\a\a\x00\x00_V\x00\x00\x00\x00a]\x00\x04\x00\x00bp\x00\b\x00\x00g \x01\f\x00\x00g \x00\f\x00\x00ix\x00\x12\x00\x00~\x90\x00\x18\x00\x00p\x80\x00\x1cLM" + + "T\x00SMT\x00+07\x00+0720\x00+0730\x00+09\x00+08\x00\n<+08>-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x93G\xdd9\x16\n\x00" + + "\x00\x16\n\x00\x00\v\x00\x1c\x00Asia/TehranUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\a\x00\x00\x00\x1c\x9al}\xc8\xd2\xdb\x12\xc8\x0e\xbb\xa2H\x0ft-@\x10\x8e@0\x10\xed:@\x11Ug\xc8" + + "\x12EJ\xb8\x137\xec\xc8\x14-\x15\xb8( v\xc8(\u06dd\xb8)˜\xc8*\xbe\"\xb8+\xac\xd0H,\x9fV8-\x8e\x03\xc8.\x80\x89\xb8/o7H0a\xbd81Pj\xc82B\xf0\xb8" + + "32\xef\xc84%u\xb85\x14#H6\x06\xa986\xf5V\xc87\xe7ܸ8֊H9\xc9\x108:\xb9\x0fH;\xab\x958<\x9aB\xc8=\x8cȸ>{vH?m\xfc8@\\\xa9\xc8" + + "AO/\xb8B?.\xc8C1\xb4\xb8G\xe2\xc9HH\xd5O8I\xc5NHJ\xb7\xd48K\xa6\x81\xc8L\x99\a\xb8M\x87\xb5HNz;8Oh\xe8\xc8P[n\xb8QKm\xc8R=\xf3\xb8" + + "S,\xa1HT\x1f'8U\r\xd4\xc8V\x00Z\xb8V\xef\bHW\xe1\x8e8XэHY\xc4\x138Z\xb2\xc0\xc8[\xa5F\xb8\\\x93\xf4H]\x86z8^u'\xc8_g\xad\xb8`W\xac\xc8" + + "aJ2\xb8b8\xe0Hc+f8d\x1a\x13\xc8e\f\x99\xb8e\xfbGHf\xed\xcd8g\xdd\xccHh\xd0R8i\xbe\xff\xc8j\xb1\x85\xb8k\xa03Hl\x92\xb98m\x81f\xc8ns\xec\xb8" + + "ob\x9aHpU 8qE\x1fHr7\xa58s&R\xc8t\x18ظu\a\x86Hu\xfa\f8v\xe8\xb9\xc8w\xdb?\xb8x\xcb>\xc8y\xbdĸz\xacrH{\x9e\xf88|\x8d\xa5\xc8" + + "}\x80+\xb8~n\xd9H\u007fa_8\x01\x02\x04\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02" + + "\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x00\x0008\x00\x00\x00\x00" + + "08\x00\x04\x00\x0018\x00\b\x00\x00FP\x01\x0e\x00\x008@\x00\x12\x00\x00?H\x01\x16\x00\x0018\x00\bLMT\x00TMT\x00+0330\x00+05\x00+04\x00+043" + + "0\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff\x9al}\xc8\xff\xff\xff\xff\xd2\xdb" + + "\x12\xc8\x00\x00\x00\x00\x0e\xbb\xa2H\x00\x00\x00\x00\x0ft-@\x00\x00\x00\x00\x10\x8e@0\x00\x00\x00\x00\x10\xed:@\x00\x00\x00\x00\x11Ug\xc8\x00\x00\x00\x00\x12EJ\xb8\x00\x00\x00\x00\x137\xec\xc8\x00\x00" + + "\x00\x00\x14-\x15\xb8\x00\x00\x00\x00( v\xc8\x00\x00\x00\x00(\u06dd\xb8\x00\x00\x00\x00)˜\xc8\x00\x00\x00\x00*\xbe\"\xb8\x00\x00\x00\x00+\xac\xd0H\x00\x00\x00\x00,\x9fV8\x00\x00\x00\x00-\x8e" + + "\x03\xc8\x00\x00\x00\x00.\x80\x89\xb8\x00\x00\x00\x00/o7H\x00\x00\x00\x000a\xbd8\x00\x00\x00\x001Pj\xc8\x00\x00\x00\x002B\xf0\xb8\x00\x00\x00\x0032\xef\xc8\x00\x00\x00\x004%u\xb8\x00\x00" + + "\x00\x005\x14#H\x00\x00\x00\x006\x06\xa98\x00\x00\x00\x006\xf5V\xc8\x00\x00\x00\x007\xe7ܸ\x00\x00\x00\x008֊H\x00\x00\x00\x009\xc9\x108\x00\x00\x00\x00:\xb9\x0fH\x00\x00\x00\x00;\xab" + + "\x958\x00\x00\x00\x00<\x9aB\xc8\x00\x00\x00\x00=\x8cȸ\x00\x00\x00\x00>{vH\x00\x00\x00\x00?m\xfc8\x00\x00\x00\x00@\\\xa9\xc8\x00\x00\x00\x00AO/\xb8\x00\x00\x00\x00B?.\xc8\x00\x00" + + "\x00\x00C1\xb4\xb8\x00\x00\x00\x00G\xe2\xc9H\x00\x00\x00\x00H\xd5O8\x00\x00\x00\x00I\xc5NH\x00\x00\x00\x00J\xb7\xd48\x00\x00\x00\x00K\xa6\x81\xc8\x00\x00\x00\x00L\x99\a\xb8\x00\x00\x00\x00M\x87" + + "\xb5H\x00\x00\x00\x00Nz;8\x00\x00\x00\x00Oh\xe8\xc8\x00\x00\x00\x00P[n\xb8\x00\x00\x00\x00QKm\xc8\x00\x00\x00\x00R=\xf3\xb8\x00\x00\x00\x00S,\xa1H\x00\x00\x00\x00T\x1f'8\x00\x00" + + "\x00\x00U\r\xd4\xc8\x00\x00\x00\x00V\x00Z\xb8\x00\x00\x00\x00V\xef\bH\x00\x00\x00\x00W\xe1\x8e8\x00\x00\x00\x00XэH\x00\x00\x00\x00Y\xc4\x138\x00\x00\x00\x00Z\xb2\xc0\xc8\x00\x00\x00\x00[\xa5" + + "F\xb8\x00\x00\x00\x00\\\x93\xf4H\x00\x00\x00\x00]\x86z8\x00\x00\x00\x00^u'\xc8\x00\x00\x00\x00_g\xad\xb8\x00\x00\x00\x00`W\xac\xc8\x00\x00\x00\x00aJ2\xb8\x00\x00\x00\x00b8\xe0H\x00\x00" + + "\x00\x00c+f8\x00\x00\x00\x00d\x1a\x13\xc8\x00\x00\x00\x00e\f\x99\xb8\x00\x00\x00\x00e\xfbGH\x00\x00\x00\x00f\xed\xcd8\x00\x00\x00\x00g\xdd\xccH\x00\x00\x00\x00h\xd0R8\x00\x00\x00\x00i\xbe" + + "\xff\xc8\x00\x00\x00\x00j\xb1\x85\xb8\x00\x00\x00\x00k\xa03H\x00\x00\x00\x00l\x92\xb98\x00\x00\x00\x00m\x81f\xc8\x00\x00\x00\x00ns\xec\xb8\x00\x00\x00\x00ob\x9aH\x00\x00\x00\x00pU 8\x00\x00" + + "\x00\x00qE\x1fH\x00\x00\x00\x00r7\xa58\x00\x00\x00\x00s&R\xc8\x00\x00\x00\x00t\x18ظ\x00\x00\x00\x00u\a\x86H\x00\x00\x00\x00u\xfa\f8\x00\x00\x00\x00v\xe8\xb9\xc8\x00\x00\x00\x00w\xdb" + + "?\xb8\x00\x00\x00\x00x\xcb>\xc8\x00\x00\x00\x00y\xbdĸ\x00\x00\x00\x00z\xacrH\x00\x00\x00\x00{\x9e\xf88\x00\x00\x00\x00|\x8d\xa5\xc8\x00\x00\x00\x00}\x80+\xb8\x00\x00\x00\x00~n\xd9H\x00\x00" + + "\x00\x00\u007fa_8\x00\x00\x00\x00\x80Q^H\x00\x00\x00\x00\x81C\xe48\x00\x00\x00\x00\x822\x91\xc8\x00\x00\x00\x00\x83%\x17\xb8\x00\x00\x00\x00\x84\x13\xc5H\x00\x00\x00\x00\x85\x06K8\x00\x00\x00\x00\x85\xf4" + + "\xf8\xc8\x00\x00\x00\x00\x86\xe7~\xb8\x00\x00\x00\x00\x87\xd7}\xc8\x00\x00\x00\x00\x88\xca\x03\xb8\x00\x00\x00\x00\x89\xb8\xb1H\x00\x00\x00\x00\x8a\xab78\x00\x00\x00\x00\x8b\x99\xe4\xc8\x00\x00\x00\x00\x8c\x8cj\xb8\x00\x00" + + "\x00\x00\x8d{\x18H\x00\x00\x00\x00\x8em\x9e8\x00\x00\x00\x00\x8f]\x9dH\x00\x00\x00\x00\x90P#8\x00\x00\x00\x00\x91>\xd0\xc8\x00\x00\x00\x00\x921V\xb8\x00\x00\x00\x00\x93 \x04H\x00\x00\x00\x00\x94\x12" + + "\x8a8\x00\x00\x00\x00\x95\x017\xc8\x00\x00\x00\x00\x95\xf3\xbd\xb8\x00\x00\x00\x00\x96\xe3\xbc\xc8\x00\x00\x00\x00\x97\xd6B\xb8\x00\x00\x00\x00\x98\xc4\xf0H\x00\x00\x00\x00\x99\xb7v8\x00\x00\x00\x00\x9a\xa6#\xc8\x00\x00" + + "\x00\x00\x9b\x98\xa9\xb8\x00\x00\x00\x00\x9c\x87WH\x00\x00\x00\x00\x9dy\xdd8\x00\x00\x00\x00\x9ei\xdcH\x00\x00\x00\x00\x9f\\b8\x00\x00\x00\x00\xa0K\x0f\xc8\x00\x00\x00\x00\xa1=\x95\xb8\x00\x00\x00\x00\xa2," + + "CH\x00\x00\x00\x00\xa3\x1e\xc98\x00\x00\x00\x00\xa4\rv\xc8\x00\x00\x00\x00\xa4\xff\xfc\xb8\x00\x00\x00\x00\xa5\xef\xfb\xc8\x00\x00\x00\x00\xa6⁸\x00\x00\x00\x00\xa7\xd1/H\x00\x00\x00\x00\xa8õ8\x00\x00" + + "\x00\x00\xa9\xb2b\xc8\x00\x00\x00\x00\xaa\xa4\xe8\xb8\x00\x00\x00\x00\xab\x93\x96H\x00\x00\x00\x00\xac\x86\x1c8\x00\x00\x00\x00\xadt\xc9\xc8\x00\x00\x00\x00\xaegO\xb8\x00\x00\x00\x00\xafWN\xc8\x00\x00\x00\x00\xb0I" + + "Ը\x00\x00\x00\x00\xb18\x82H\x00\x00\x00\x00\xb2+\b8\x00\x00\x00\x00\xb3\x19\xb5\xc8\x00\x00\x00\x00\xb4\f;\xb8\x00\x00\x00\x00\xb4\xfa\xe9H\x00\x00\x00\x00\xb5\xedo8\x00\x00\x00\x00\xb6\xddnH\x00\x00" + + "\x00\x00\xb7\xcf\xf48\x00\x00\x00\x00\xb8\xbe\xa1\xc8\x00\x00\x00\x00\xb9\xb1'\xb8\x00\x00\x00\x00\xba\x9f\xd5H\x00\x00\x00\x00\xbb\x92[8\x00\x00\x00\x00\xbc\x81\b\xc8\x00\x00\x00\x00\xbds\x8e\xb8\x00\x00\x00\x00\xbec" + + "\x8d\xc8\x00\x00\x00\x00\xbfV\x13\xb8\x00\x00\x00\x00\xc0D\xc1H\x00\x00\x00\x00\xc17G8\x00\x00\x00\x00\xc2%\xf4\xc8\x00\x00\x00\x00\xc3\x18z\xb8\x00\x00\x00\x00\xc4\a(H\x00\x00\x00\x00\xc4\xf9\xae8\x00\x00" + + "\x00\x00\xc5\xe9\xadH\x00\x00\x00\x00\xc6\xdc38\x00\x00\x00\x00\xc7\xca\xe0\xc8\x00\x00\x00\x00Ƚf\xb8\x00\x00\x00\x00ɬ\x14H\x00\x00\x00\x00ʞ\x9a8\x00\x00\x00\x00ˍG\xc8\x00\x00\x00\x00\xcc\u007f" + + "\u0378\x00\x00\x00\x00\xcdo\xcc\xc8\x00\x00\x00\x00\xcebR\xb8\x00\x00\x00\x00\xcfQ\x00H\x00\x00\x00\x00\xd0C\x868\x00\x00\x00\x00\xd123\xc8\x00\x00\x00\x00\xd2$\xb9\xb8\x00\x00\x00\x00\xd3\x13gH\x00\x00" + + "\x00\x00\xd4\x05\xed8\x00\x00\x00\x00\xd4\xf5\xecH\x00\x00\x00\x00\xd5\xe8r8\x00\x00\x00\x00\xd6\xd7\x1f\xc8\x00\x00\x00\x00\xd7ɥ\xb8\x00\x00\x00\x00ظSH\x00\x00\x00\x00٪\xd98\x00\x00\x00\x00ڙ" + + "\x86\xc8\x00\x00\x00\x00ی\f\xb8\x00\x00\x00\x00\xdc|\v\xc8\x00\x00\x00\x00\xddn\x91\xb8\x00\x00\x00\x00\xde]?H\x00\x00\x00\x00\xdfO\xc58\x01\x02\x04\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02" + + "\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02" + + "\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02" + + "\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02" + + "\x05\x02\x05\x02\x00\x0008\x00\x00\x00\x0008\x00\x04\x00\x0018\x00\b\x00\x00FP\x01\x0e\x00\x008@\x00\x12\x00\x00?H\x01\x16\x00\x0018\x00\bLMT\x00TMT\x00+0330\x00" + + "+05\x00+04\x00+0430\x00\n<+0330>-3:30<+0430>,J79/24,J263/24\nPK\x03\x04\n\x00\x00\x00\x00\x00" + + "\xf5F\x9cP\fl\xe3/j\b\x00\x00j\b\x00\x00\v\x00\x1c\x00Asia/BeirutUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00T" + + "Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8d\x00\x00\x00\x03\x00\x00\x00\r\x80\x00\x00\x00\xa2ec\xe0\xa3{\x82P\xa4N\x80`\xa5" + + "?\xb4Ц%'\xe0\xa7'\u007fШ)\xf3\xe0\xa8\xeb\xb2P\xe8*\x85\xe0\xe8\xf4-P\xea\v\xb9`\xea\xd5`\xd0\xeb\xec\xec\xe0추P\xed\xcfq\xe0\xee\x99\x19Pﰥ`\xf0zL\xd0\x04" + + "\xa6^`\x05+w\xd0\x06C\x03\xe0\a\f\xabP\b$7`\b\xed\xde\xd0\n\x05j\xe0\n\xcf\x12P\v\xe7\xef\xe0\f\xb1\x97P\r\xc9#`\x0e\x92\xca\xd0\x0f\xa9\x05`\x10r\xac\xd0\x1a\xf4.\xe0\x1b" + + "ќ\xd0\x1c\xd5b`\x1d\xb2\xd0P\x1e\xb6\x95\xe0\x1f\x94\x03\xd0 \x97\xc9`!u7P\"\xa3,\xe0#W\xbcP$g_`%8\xef\xd0&<\xb5`'\x1a#P(\x1d\xe8\xe0(\xfbV\xd0*" + + "\x00m\xe0*\xce\t\xd0+\xb4\xce`,\xa4\xb1P-\x94\xb0`.\x84\x93P/t\x92`0duP1]\xae\xe02M\x91\xd03=\x90\xe04-s\xd05\x1dr\xe06\rU\xd06\xfdT\xe08" + + "\x1b\\P8\xdd6\xe09\xfb>P:\xbd\x18\xe0;\xdb P<\xa65`=\xbb\x02P>\x86\x17`?\x9a\xe4P@e\xf9`A\x84\x00\xd0BE\xdb`Cc\xe2\xd0D%\xbd`EC\xc4\xd0F" + + "\x05\x9f`G#\xa6\xd0G\xee\xbb\xe0I\x03\x88\xd0IΝ\xe0J\xe3j\xd0K\xae\u007f\xe0L̇PM\x8ea\xe0N\xaciPOnC\xe0P\x8cKPQW``Rl-PS7B`T" + + "L\x0fPU\x17$`V+\xf1PV\xf7\x06`X\x15\r\xd0X\xd6\xe8`Y\xf4\xef\xd0Z\xb6\xca`[\xd4\xd1\xd0\\\x9f\xe6\xe0]\xb4\xb3\xd0^\u007f\xc8\xe0_\x94\x95\xd0`_\xaa\xe0a}\xb2Pb" + + "?\x8c\xe0c]\x94Pd\x1fn\xe0e=vPf\b\x8b`g\x1dXPg\xe8m`h\xfd:Pi\xc8O`j\xdd\x1cPk\xa81`l\xc68\xd0m\x88\x13`n\xa6\x1a\xd0og\xf5`p" + + "\x85\xfc\xd0qQ\x11\xe0re\xde\xd0s0\xf3\xe0tE\xc0\xd0u\x10\xd5\xe0v.\xddPv\xf0\xb7\xe0x\x0e\xbfPxЙ\xe0y\xee\xa1Pz\xb0{\xe0{\u0383P|\x99\x98`}\xaeeP~" + + "yz`\u007f\x8eGP\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00!H\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\tLMT\x00EEST\x00EET\x00T" + + "Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8d\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffV\xb6¸\xff\xff\xff\xff\xa2ec\xe0\xff" + + "\xff\xff\xff\xa3{\x82P\xff\xff\xff\xff\xa4N\x80`\xff\xff\xff\xff\xa5?\xb4\xd0\xff\xff\xff\xff\xa6%'\xe0\xff\xff\xff\xff\xa7'\u007f\xd0\xff\xff\xff\xff\xa8)\xf3\xe0\xff\xff\xff\xff\xa8\xeb\xb2P\xff\xff\xff\xff\xe8" + + "*\x85\xe0\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea\v\xb9`\xff\xff\xff\xff\xea\xd5`\xd0\xff\xff\xff\xff\xeb\xec\xec\xe0\xff\xff\xff\xff추P\xff\xff\xff\xff\xed\xcfq\xe0\xff\xff\xff\xff\xee\x99\x19P\xff" + + "\xff\xff\xffﰥ`\xff\xff\xff\xff\xf0zL\xd0\x00\x00\x00\x00\x04\xa6^`\x00\x00\x00\x00\x05+w\xd0\x00\x00\x00\x00\x06C\x03\xe0\x00\x00\x00\x00\a\f\xabP\x00\x00\x00\x00\b$7`\x00\x00\x00\x00\b" + + "\xed\xde\xd0\x00\x00\x00\x00\n\x05j\xe0\x00\x00\x00\x00\n\xcf\x12P\x00\x00\x00\x00\v\xe7\xef\xe0\x00\x00\x00\x00\f\xb1\x97P\x00\x00\x00\x00\r\xc9#`\x00\x00\x00\x00\x0e\x92\xca\xd0\x00\x00\x00\x00\x0f\xa9\x05`\x00" + + "\x00\x00\x00\x10r\xac\xd0\x00\x00\x00\x00\x1a\xf4.\xe0\x00\x00\x00\x00\x1bќ\xd0\x00\x00\x00\x00\x1c\xd5b`\x00\x00\x00\x00\x1d\xb2\xd0P\x00\x00\x00\x00\x1e\xb6\x95\xe0\x00\x00\x00\x00\x1f\x94\x03\xd0\x00\x00\x00\x00 " + + "\x97\xc9`\x00\x00\x00\x00!u7P\x00\x00\x00\x00\"\xa3,\xe0\x00\x00\x00\x00#W\xbcP\x00\x00\x00\x00$g_`\x00\x00\x00\x00%8\xef\xd0\x00\x00\x00\x00&<\xb5`\x00\x00\x00\x00'\x1a#P\x00" + + "\x00\x00\x00(\x1d\xe8\xe0\x00\x00\x00\x00(\xfbV\xd0\x00\x00\x00\x00*\x00m\xe0\x00\x00\x00\x00*\xce\t\xd0\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00." + + "\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002M\x91\xd0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004-s\xd0\x00\x00\x00\x005\x1dr\xe0\x00" + + "\x00\x00\x006\rU\xd0\x00\x00\x00\x006\xfdT\xe0\x00\x00\x00\x008\x1b\\P\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfb>P\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00;\xdb P\x00\x00\x00\x00<" + + "\xa65`\x00\x00\x00\x00=\xbb\x02P\x00\x00\x00\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xe4P\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x00\xd0\x00\x00\x00\x00BE\xdb`\x00\x00\x00\x00Cc\xe2\xd0\x00" + + "\x00\x00\x00D%\xbd`\x00\x00\x00\x00EC\xc4\xd0\x00\x00\x00\x00F\x05\x9f`\x00\x00\x00\x00G#\xa6\xd0\x00\x00\x00\x00G\xee\xbb\xe0\x00\x00\x00\x00I\x03\x88\xd0\x00\x00\x00\x00IΝ\xe0\x00\x00\x00\x00J" + + "\xe3j\xd0\x00\x00\x00\x00K\xae\u007f\xe0\x00\x00\x00\x00L̇P\x00\x00\x00\x00M\x8ea\xe0\x00\x00\x00\x00N\xaciP\x00\x00\x00\x00OnC\xe0\x00\x00\x00\x00P\x8cKP\x00\x00\x00\x00QW``\x00" + + "\x00\x00\x00Rl-P\x00\x00\x00\x00S7B`\x00\x00\x00\x00TL\x0fP\x00\x00\x00\x00U\x17$`\x00\x00\x00\x00V+\xf1P\x00\x00\x00\x00V\xf7\x06`\x00\x00\x00\x00X\x15\r\xd0\x00\x00\x00\x00X" + + "\xd6\xe8`\x00\x00\x00\x00Y\xf4\xef\xd0\x00\x00\x00\x00Z\xb6\xca`\x00\x00\x00\x00[\xd4\xd1\xd0\x00\x00\x00\x00\\\x9f\xe6\xe0\x00\x00\x00\x00]\xb4\xb3\xd0\x00\x00\x00\x00^\u007f\xc8\xe0\x00\x00\x00\x00_\x94\x95\xd0\x00" + + "\x00\x00\x00`_\xaa\xe0\x00\x00\x00\x00a}\xb2P\x00\x00\x00\x00b?\x8c\xe0\x00\x00\x00\x00c]\x94P\x00\x00\x00\x00d\x1fn\xe0\x00\x00\x00\x00e=vP\x00\x00\x00\x00f\b\x8b`\x00\x00\x00\x00g" + + "\x1dXP\x00\x00\x00\x00g\xe8m`\x00\x00\x00\x00h\xfd:P\x00\x00\x00\x00i\xc8O`\x00\x00\x00\x00j\xdd\x1cP\x00\x00\x00\x00k\xa81`\x00\x00\x00\x00l\xc68\xd0\x00\x00\x00\x00m\x88\x13`\x00" + + "\x00\x00\x00n\xa6\x1a\xd0\x00\x00\x00\x00og\xf5`\x00\x00\x00\x00p\x85\xfc\xd0\x00\x00\x00\x00qQ\x11\xe0\x00\x00\x00\x00re\xde\xd0\x00\x00\x00\x00s0\xf3\xe0\x00\x00\x00\x00tE\xc0\xd0\x00\x00\x00\x00u" + + "\x10\xd5\xe0\x00\x00\x00\x00v.\xddP\x00\x00\x00\x00v\xf0\xb7\xe0\x00\x00\x00\x00x\x0e\xbfP\x00\x00\x00\x00xЙ\xe0\x00\x00\x00\x00y\xee\xa1P\x00\x00\x00\x00z\xb0{\xe0\x00\x00\x00\x00{\u0383P\x00" + + "\x00\x00\x00|\x99\x98`\x00\x00\x00\x00}\xaeeP\x00\x00\x00\x00~yz`\x00\x00\x00\x00\u007f\x8eGP\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00!H\x00\x00\x00\x00" + + "*0\x01\x04\x00\x00\x1c \x00\tLMT\x00EEST\x00EET\x00\nEET-2EEST,M3.5.0/0,M10.5.0/0\nPK\x03\x04\n\x00\x00" + + "\x00\x00\x00\xf5F\x9cP\xcdb\xe7\x86\xf3\x03\x00\x00\xf3\x03\x00\x00\v\x00\x1c\x00Asia/AqtobeUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00" + + "\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x004\x00\x00\x00\v\x00\x00\x00\x10\xaa\x19\x8eh\xb5\xa3\xfd@\x15'\x8b\xb0\x16\x18" + + "\xc0 \x17\b\xb1 \x17\xf9\xf3\xa0\x18\xe9\xf2\xb0\x19\xdb' \x1a\xccw\xb0\x1b\xbc\x84\xd0\x1c\xacu\xd0\x1d\x9cf\xd0\x1e\x8cW\xd0\x1f|H\xd0 l9\xd0!\\*\xd0\"L\x1b\xd0#<\f\xd0$+" + + "\xfd\xd0%\x1b\xee\xd0&\v\xdf\xd0'\x05\vP'\xf4\xfcP(\xe4\xfb`)x\xa3`)\xd4\xdeP*\xc4\xcfP+\xb4\xc0P,\xa4\xb1P-\x94\xa2P.\x84\x93P/t\x84P0duP1]" + + "\xa0\xd02r{\xd03=\x82\xd04R]\xd05\x1dd\xd062?\xd06\xfdF\xd08\x1b\\P8\xdd(\xd09\xfb>P:\xbd\n\xd0;\xdb P<\xa6'P=\xbb\x02P>\x86\tP?\x9a" + + "\xe4P@e\xebPA\x84\x00\xd0\u007f\xff\xff\xff\x01\x02\x03\x04\x03\x02\x03\x02\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\b\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x05\x00\x005\x98\x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00T`\x00\f\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00FP\x01\b\x00\x008@\x00\x04" + + "\x00\x00T`\x01\f\x00\x00FP\x00\bLMT\x00+04\x00+05\x00+06\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x004\x00\x00\x00\v\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x8eh\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17" + + "\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00" + + "\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%" + + "\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xcfP\x00" + + "\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84P\x00\x00\x00\x000duP\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002" + + "r{\xd0\x00\x00\x00\x003=\x82\xd0\x00\x00\x00\x004R]\xd0\x00\x00\x00\x005\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00\x006\xfdF\xd0\x00\x00\x00\x008\x1b\\P\x00\x00\x00\x008\xdd(\xd0\x00" + + "\x00\x00\x009\xfb>P\x00\x00\x00\x00:\xbd\n\xd0\x00\x00\x00\x00;\xdb P\x00\x00\x00\x00<\xa6'P\x00\x00\x00\x00=\xbb\x02P\x00\x00\x00\x00>\x86\tP\x00\x00\x00\x00?\x9a\xe4P\x00\x00\x00\x00@" + + "e\xebP\x00\x00\x00\x00A\x84\x00\xd0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x04\x03\x02\x03\x02\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\b\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x05\x00\x005\x98\x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00T`\x00\f\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00FP\x01\b\x00" + + "\x008@\x00\x04\x00\x00T`\x01\f\x00\x00FP\x00\bLMT\x00+04\x00+05\x00+06\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\n<+05>-5\nPK\x03\x04\n\x00\x00" + + "\x00\x00\x00\xf5F\x9cP\xe1;\x9e&\xa4\x04\x00\x00\xa4\x04\x00\x00\v\x00\x1c\x00Asia/AnadyrUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00" + + "\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x00\n\x00\x00\x00\x14\xaa\x19\x1d\x9c\xb5\xa3\x8c\xc0\x15'\x1b0\x16\x18" + + "O\xa0\x17\bN\xb0\x17\xf9\x910\x18\xe9\x90@\x19\xdaİ\x1a\xcc\x15@\x1b\xbc\"`\x1c\xac\x13`\x1d\x9c\x04`\x1e\x8b\xf5`\x1f{\xe6` k\xd7`![\xc8`\"K\xb9`#;\xaa`$+" + + "\x9b`%\x1b\x8c`&\v}`'\x04\xa8\xe0'\xf4\x99\xe0(\xe4\x98\xf0)x@\xf0)\xd4{\xe0*\xc4l\xe0+\xb4]\xe0,\xa4N\xe0-\x94?\xe0.\x840\xe0/t!\xe00d\x12\xe01]" + + ">`2r\x19`3= `4Q\xfb`5\x1d\x02`61\xdd`6\xfc\xe4`8\x1a\xf9\xe08\xdc\xc6`9\xfa\xdb\xe0:\xbc\xa8`;ڽ\xe0<\xa5\xc4\xe0=\xba\x9f\xe0>\x85\xa6\xe0?\x9a" + + "\x81\xe0@e\x88\xe0A\x83\x9e`BEj\xe0Cc\x80`D%L\xe0ECb`F\x05.\xe0G#D`G\xeeK`I\x03&`I\xce-`J\xe3\b`K\xae\x0f`L\xcc2\xf0M\x8d" + + "\xffp\u007f\xff\xff\xff\x01\x03\x02\x03\x04\x01\x04\x01\x04\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\b\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\a\b\x05\x05\x00\x00\xa6d\x00\x00\x00\x00\xa8\xc0\x00\x04\x00\x00\xc4\xe0\x01\b\x00\x00\xb6\xd0\x00\f\x00\x00\xb6\xd0\x01\f\x00\x00\xa8\xc0\x00\x04\x00\x00\xb6\xd0\x01\f\x00\x00\xa8\xc0\x01\x04\x00" + + "\x00\x9a\xb0\x00\x10\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00+14\x00+13\x00+11\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x00\n\x00\x00\x00\x14\xff\xff\xff\xff\xaa\x19\x1d\x9c\xff\xff\xff\xff\xb5\xa3\x8c\xc0\x00\x00\x00\x00\x15'\x1b0\x00\x00\x00\x00\x16\x18O\xa0\x00\x00\x00" + + "\x00\x17\bN\xb0\x00\x00\x00\x00\x17\xf9\x910\x00\x00\x00\x00\x18\xe9\x90@\x00\x00\x00\x00\x19\xdaİ\x00\x00\x00\x00\x1a\xcc\x15@\x00\x00\x00\x00\x1b\xbc\"`\x00\x00\x00\x00\x1c\xac\x13`\x00\x00\x00\x00\x1d\x9c\x04" + + "`\x00\x00\x00\x00\x1e\x8b\xf5`\x00\x00\x00\x00\x1f{\xe6`\x00\x00\x00\x00 k\xd7`\x00\x00\x00\x00![\xc8`\x00\x00\x00\x00\"K\xb9`\x00\x00\x00\x00#;\xaa`\x00\x00\x00\x00$+\x9b`\x00\x00\x00" + + "\x00%\x1b\x8c`\x00\x00\x00\x00&\v}`\x00\x00\x00\x00'\x04\xa8\xe0\x00\x00\x00\x00'\xf4\x99\xe0\x00\x00\x00\x00(\xe4\x98\xf0\x00\x00\x00\x00)x@\xf0\x00\x00\x00\x00)\xd4{\xe0\x00\x00\x00\x00*\xc4l" + + "\xe0\x00\x00\x00\x00+\xb4]\xe0\x00\x00\x00\x00,\xa4N\xe0\x00\x00\x00\x00-\x94?\xe0\x00\x00\x00\x00.\x840\xe0\x00\x00\x00\x00/t!\xe0\x00\x00\x00\x000d\x12\xe0\x00\x00\x00\x001]>`\x00\x00\x00" + + "\x002r\x19`\x00\x00\x00\x003= `\x00\x00\x00\x004Q\xfb`\x00\x00\x00\x005\x1d\x02`\x00\x00\x00\x0061\xdd`\x00\x00\x00\x006\xfc\xe4`\x00\x00\x00\x008\x1a\xf9\xe0\x00\x00\x00\x008\xdc\xc6" + + "`\x00\x00\x00\x009\xfa\xdb\xe0\x00\x00\x00\x00:\xbc\xa8`\x00\x00\x00\x00;ڽ\xe0\x00\x00\x00\x00<\xa5\xc4\xe0\x00\x00\x00\x00=\xba\x9f\xe0\x00\x00\x00\x00>\x85\xa6\xe0\x00\x00\x00\x00?\x9a\x81\xe0\x00\x00\x00" + + "\x00@e\x88\xe0\x00\x00\x00\x00A\x83\x9e`\x00\x00\x00\x00BEj\xe0\x00\x00\x00\x00Cc\x80`\x00\x00\x00\x00D%L\xe0\x00\x00\x00\x00ECb`\x00\x00\x00\x00F\x05.\xe0\x00\x00\x00\x00G#D" + + "`\x00\x00\x00\x00G\xeeK`\x00\x00\x00\x00I\x03&`\x00\x00\x00\x00I\xce-`\x00\x00\x00\x00J\xe3\b`\x00\x00\x00\x00K\xae\x0f`\x00\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M\x8d\xffp\x00\x00\x00" + + "\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x04\x01\x04\x01\x04\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\b\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\a\b\x05\x05\x00\x00\xa6d\x00\x00\x00\x00\xa8\xc0\x00\x04\x00\x00\xc4\xe0\x01\b\x00\x00\xb6\xd0\x00\f\x00\x00\xb6\xd0\x01\f\x00\x00\xa8\xc0\x00\x04\x00\x00\xb6\xd0\x01\f\x00\x00\xa8\xc0\x01\x04\x00\x00" + + "\x9a\xb0\x00\x10\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00+14\x00+13\x00+11\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\n<+12>-12\nPK\x03\x04\n\x00\x00\x00\x00\x00" + + "\xf5F\x9cPSh\t\xd2\xd7\x03\x00\x00\xd7\x03\x00\x00\f\x00\x1c\x00Asia/BishkekUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00" + + "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00\b\x00\x00\x00\x10\xaa\x19~\x10\xb5\xa3\xef0\x15'}\xa0\x16\x18\xb2\x10" + + "\x17\b\xb1 \x17\xf9\xe5\x90\x18\xe9\xe4\xa0\x19\xdb\x19\x10\x1a\xcci\xa0\x1b\xbcv\xc0\x1c\xacg\xc0\x1d\x9cX\xc0\x1e\x8cI\xc0\x1f|:\xc0 l+\xc0!\\\x1c\xc0\"L\r\xc0#;\xfe\xc0$+\xef\xc0" + + "%\x1b\xe0\xc0&\v\xd1\xc0'\x04\xfd@'\xf4\xee@(\xbe\xa3\xc0)\xe770*ĥ +\xc7\x190,\xa4\x87 -\xa6\xfb0.\x84i /\x86\xdd00dK 1f\xbf02Mg\xa0" + + "3=\x89\xd84RV\xc85\x1dk\xd8628\xc86\xfdM\xd88\x1bUH8\xdd/\xd89\xfb7H:\xbd\x11\xd8;\xdb\x19H<\xa6.X=\xba\xfbH>\x86\x10X?\x9a\xddH@e\xf2X" + + "A\x83\xf9\xc8BE\xd4XB\xfb\x92 \u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\a\x01\a\x01\a\x01\a\x01\a\x01" + + "\a\x01\a\x01\a\x01\a\x03\x03\x00\x00E\xf0\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\b\x00\x00T`\x00\f\x00\x00T`\x00\f\x00\x00bp\x01\b\x00\x00T`\x01\f\x00\x00T`\x01\fLMT" + + "\x00+05\x00+07\x00+06\x00\x00\x00\x00\x00\x01\x01\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00" + + "\b\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19~\x10\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00\x00\x00\x00\x18\xe9\xe4" + + "\xa0\x00\x00\x00\x00\x19\xdb\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f|:\xc0\x00\x00\x00" + + "\x00 l+\xc0\x00\x00\x00\x00!\\\x1c\xc0\x00\x00\x00\x00\"L\r\xc0\x00\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\v\xd1\xc0\x00\x00\x00\x00'\x04\xfd" + + "@\x00\x00\x00\x00'\xf4\xee@\x00\x00\x00\x00(\xbe\xa3\xc0\x00\x00\x00\x00)\xe770\x00\x00\x00\x00*ĥ \x00\x00\x00\x00+\xc7\x190\x00\x00\x00\x00,\xa4\x87 \x00\x00\x00\x00-\xa6\xfb0\x00\x00\x00" + + "\x00.\x84i \x00\x00\x00\x00/\x86\xdd0\x00\x00\x00\x000dK \x00\x00\x00\x001f\xbf0\x00\x00\x00\x002Mg\xa0\x00\x00\x00\x003=\x89\xd8\x00\x00\x00\x004RV\xc8\x00\x00\x00\x005\x1dk" + + "\xd8\x00\x00\x00\x00628\xc8\x00\x00\x00\x006\xfdM\xd8\x00\x00\x00\x008\x1bUH\x00\x00\x00\x008\xdd/\xd8\x00\x00\x00\x009\xfb7H\x00\x00\x00\x00:\xbd\x11\xd8\x00\x00\x00\x00;\xdb\x19H\x00\x00\x00" + + "\x00<\xa6.X\x00\x00\x00\x00=\xba\xfbH\x00\x00\x00\x00>\x86\x10X\x00\x00\x00\x00?\x9a\xddH\x00\x00\x00\x00@e\xf2X\x00\x00\x00\x00A\x83\xf9\xc8\x00\x00\x00\x00BE\xd4X\x00\x00\x00\x00B\xfb\x92" + + " \x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\x06\x01\a\x01\a\x01\a\x01\a\x01\a\x01\a\x01\a\x01\a\x01\a" + + "\x03\x03\x00\x00E\xf0\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\b\x00\x00T`\x00\f\x00\x00T`\x00\f\x00\x00bp\x01\b\x00\x00T`\x01\f\x00\x00T`\x01\fLMT\x00+05\x00+0" + + "7\x00+06\x00\x00\x00\x00\x00\x01\x01\x01\x00\n<+06>-6\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x8e\"\x05\x94\xa5\x00\x00\x00\xa5\x00\x00\x00\n\x00\x1c\x00Asia/Du" + + "baiUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xa1\xf2\x99\xa8\u007f\xff\xff\xff\x01\x01\x00\x003\xd8\x00\x00\x00\x008@\x00\x04LMT\x00+04\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xa1\xf2\x99\xa8\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x003\xd8\x00\x00\x00\x008@\x00\x04L" + + "MT\x00+04\x00\n<+04>-4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPs\x92<\x8f\xa5\x00\x00\x00\xa5\x00\x00\x00\v\x00\x1c\x00Asia/RiyadhUT\t" + + "\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x02\x00\x00\x00\x02\x00\x00\x00\b\xd5\x1b6\xb4\u007f\xff\xff\xff\x01\x01\x00\x00+\xcc\x00\x00\x00\x00*0\x00\x04LMT\x00+03\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xd5\x1b6\xb4\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x00+\xcc\x00\x00\x00\x00*0\x00\x04LMT\x00+03" + + "\x00\n<+03>-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPC\xc55\xaf\x8d\x04\x00\x00\x8d\x04\x00\x00\x11\x00\x1c\x00Asia/NovokuznetskUT\t" + + "\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00" + + "A\x00\x00\x00\t\x00\x00\x00\x10\xaa\x18 \xc0\xb5\xa3\xe1 \x15'o\x90\x16\x18\xa4\x00\x17\b\xa3\x10\x17\xf9׀\x18\xe9\u0590\x19\xdb\v\x00\x1a\xcc[\x90\x1b\xbch\xb0\x1c\xacY\xb0\x1d\x9cJ\xb0\x1e\x8c;" + + "\xb0\x1f|,\xb0 l\x1d\xb0!\\\x0e\xb0\"K\xff\xb0#;\xf0\xb0$+\xe1\xb0%\x1bҰ&\vð'\x04\xef0'\xf4\xe00(\xe4\xdf@)x\x87@)\xd4\xc20*ij0+\xb4\xa4" + + "0,\xa4\x950-\x94\x860.\x84w0/th00dY01]\x84\xb02r_\xb03=f\xb04RA\xb05\x1dH\xb062#\xb06\xfd*\xb08\x1b@08\xdd\f\xb09\xfb\"" + + "0:\xbc\xee\xb0;\xdb\x040<\xa6\v0=\xba\xe60>\x85\xed0?\x9a\xc80@e\xcf0A\x83\xe4\xb0BE\xb10CcưD%\x930EC\xa8\xb0F\x05u0G#\x8a\xb0G\xee\x91" + + "\xb0I\x03l\xb0I\xces\xb0J\xe3N\xb0K\xaeU\xb0L\xccy@M\x8eE\xc0\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x04\x00\x00Q\xc0\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\f\x00\x00" + + "bp\x00\f\x00\x00p\x80\x01\b\x00\x00bp\x01\f\x00\x00T`\x00\x04\x00\x00bp\x00\fLMT\x00+06\x00+08\x00+07\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01TZif2\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x00\t\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x18 \xc0\xff\xff\xff\xff\xb5\xa3\xe1 \x00\x00\x00\x00\x15'o" + + "\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\b\xa3\x10\x00\x00\x00\x00\x17\xf9׀\x00\x00\x00\x00\x18\xe9\u0590\x00\x00\x00\x00\x19\xdb\v\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbch\xb0\x00\x00\x00" + + "\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00\x00\x00\x00 l\x1d\xb0\x00\x00\x00\x00!\\\x0e\xb0\x00\x00\x00\x00\"K\xff\xb0\x00\x00\x00\x00#;\xf0" + + "\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1bҰ\x00\x00\x00\x00&\vð\x00\x00\x00\x00'\x04\xef0\x00\x00\x00\x00'\xf4\xe00\x00\x00\x00\x00(\xe4\xdf@\x00\x00\x00\x00)x\x87@\x00\x00\x00" + + "\x00)\xd4\xc20\x00\x00\x00\x00*ij0\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00,\xa4\x950\x00\x00\x00\x00-\x94\x860\x00\x00\x00\x00.\x84w0\x00\x00\x00\x00/th0\x00\x00\x00\x000dY" + + "0\x00\x00\x00\x001]\x84\xb0\x00\x00\x00\x002r_\xb0\x00\x00\x00\x003=f\xb0\x00\x00\x00\x004RA\xb0\x00\x00\x00\x005\x1dH\xb0\x00\x00\x00\x0062#\xb0\x00\x00\x00\x006\xfd*\xb0\x00\x00\x00" + + "\x008\x1b@0\x00\x00\x00\x008\xdd\f\xb0\x00\x00\x00\x009\xfb\"0\x00\x00\x00\x00:\xbc\xee\xb0\x00\x00\x00\x00;\xdb\x040\x00\x00\x00\x00<\xa6\v0\x00\x00\x00\x00=\xba\xe60\x00\x00\x00\x00>\x85\xed" + + "0\x00\x00\x00\x00?\x9a\xc80\x00\x00\x00\x00@e\xcf0\x00\x00\x00\x00A\x83\xe4\xb0\x00\x00\x00\x00BE\xb10\x00\x00\x00\x00Ccư\x00\x00\x00\x00D%\x930\x00\x00\x00\x00EC\xa8\xb0\x00\x00\x00" + + "\x00F\x05u0\x00\x00\x00\x00G#\x8a\xb0\x00\x00\x00\x00G\ue470\x00\x00\x00\x00I\x03l\xb0\x00\x00\x00\x00I\xces\xb0\x00\x00\x00\x00J\xe3N\xb0\x00\x00\x00\x00K\xaeU\xb0\x00\x00\x00\x00L\xccy" + + "@\x00\x00\x00\x00M\x8eE\xc0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x04\x00\x00Q\xc0\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\f\x00\x00bp\x00\f\x00\x00p\x80\x01\b\x00\x00" + + "bp\x01\f\x00\x00T`\x00\x04\x00\x00bp\x00\fLMT\x00+06\x00+08\x00+07\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\n<+07>-7\nPK\x03\x04\n\x00\x00\x00\x00\x00" + + "\xf5F\x9cP$\xb3\xaf\x18\xd7\x03\x00\x00\xd7\x03\x00\x00\n\x00\x1c\x00Asia/AqtauUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZ" + + "if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\n\x00\x00\x00\x10\xaa\x19\x94ൣ\xfd@\x16\x18\xce0\x17\b\xb1 \x17\xf9" + + "\xf3\xa0\x18\xe9\xf2\xb0\x19\xdb' \x1a\xccw\xb0\x1b\xbc\x84\xd0\x1c\xacu\xd0\x1d\x9cf\xd0\x1e\x8cW\xd0\x1f|H\xd0 l9\xd0!\\*\xd0\"L\x1b\xd0#<\f\xd0$+\xfd\xd0%\x1b\xee\xd0&\v" + + "\xdf\xd0'\x05\vP'\xf4\xfcP(\xe4\xfb`)x\xa3`)\xd4\xdeP*\xc4\xcfP+\xb4\xc0P,\xa4\xb1P-\x94\xa2P.\x84\x93P/t\x92`0d\x83`1]\xae\xe02r\x89\xe03=" + + "\x90\xe04Rk\xe05\x1dr\xe062M\xe06\xfdT\xe08\x1bj`8\xdd6\xe09\xfbL`:\xbd\x18\xe0;\xdb.`<\xa65`=\xbb\x10`>\x86\x17`?\x9a\xf2`@e\xf9`A\x84" + + "\x0e\xe0\u007f\xff\xff\xff\x01\x02\x03\x04\x02\x04\x02\x04\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\b\x05\x06\x05\x06\x05\x06\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\x05\x05\x00\x00/" + + " \x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\b\x00\x00T`\x00\f\x00\x00T`\x01\f\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00FP\x01\b\x00\x008@\x00\x04\x00\x00FP\x00\bLMT" + + "\x00+04\x00+05\x00+06\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x003\x00" + + "\x00\x00\n\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x94\xe0\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19" + + "\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00" + + "\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'" + + "\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00" + + "\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000d\x83`\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r\x89\xe0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004Rk\xe0\x00\x00\x00\x005" + + "\x1dr\xe0\x00\x00\x00\x0062M\xe0\x00\x00\x00\x006\xfdT\xe0\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`\x00" + + "\x00\x00\x00<\xa65`\x00\x00\x00\x00=\xbb\x10`\x00\x00\x00\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x04\x02" + + "\x04\x02\x04\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\b\x05\x06\x05\x06\x05\x06\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\x05\x05\x00\x00/ \x00\x00\x00\x008@\x00\x04\x00\x00" + + "FP\x00\b\x00\x00T`\x00\f\x00\x00T`\x01\f\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00FP\x01\b\x00\x008@\x00\x04\x00\x00FP\x00\bLMT\x00+04\x00+05\x00+0" + + "6\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\n<+05>-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x90\x96\xc3\xf0\xb7\x04\x00\x00\xb7\x04\x00\x00\t\x00\x1c\x00Asia/Omsk" + + "UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00" + + "\x00\x00\x00B\x00\x00\x00\v\x00\x00\x00\x10\xa1\xb3@\xb6\xb5\xa3\xef0\x15'}\xa0\x16\x18\xb2\x10\x17\b\xb1 \x17\xf9\xe5\x90\x18\xe9\xe4\xa0\x19\xdb\x19\x10\x1a\xcci\xa0\x1b\xbcv\xc0\x1c\xacg\xc0\x1d\x9cX\xc0" + + "\x1e\x8cI\xc0\x1f|:\xc0 l+\xc0!\\\x1c\xc0\"L\r\xc0#;\xfe\xc0$+\xef\xc0%\x1b\xe0\xc0&\v\xd1\xc0'\x04\xfd@'\xf4\xee@(\xe4\xedP)x\x95P)\xd4\xd0@*\xc4\xc1@" + + "+\xb4\xb2@,\xa4\xa3@-\x94\x94@.\x84\x85@/tv@0dg@1]\x92\xc02rm\xc03=t\xc04RO\xc05\x1dV\xc0621\xc06\xfd8\xc08\x1bN@8\xdd\x1a\xc0" + + "9\xfb0@:\xbc\xfc\xc0;\xdb\x12@<\xa6\x19@=\xba\xf4@>\x85\xfb@?\x9a\xd6@@e\xdd@A\x83\xf2\xc0BE\xbf@Cc\xd4\xc0D%\xa1@EC\xb6\xc0F\x05\x83@G#\x98\xc0" + + "G\xee\x9f\xc0I\x03z\xc0I\u0381\xc0J\xe3\\\xc0K\xaec\xc0L\xccy@M\x8eE\xc0TK\xf30\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\b\x04\x04\x00\x00D\xca\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\b" + + "\x00\x00T`\x00\f\x00\x00T`\x00\f\x00\x00bp\x01\b\x00\x00T`\x01\f\x00\x00FP\x00\x04\x00\x00bp\x00\b\x00\x00bp\x01\b\x00\x00T`\x00\fLMT\x00+05\x00+07\x00" + + "+06\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\v\x00\x00\x00\x10\xff" + + "\xff\xff\xff\xa1\xb3@\xb6\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00\x00\x00\x00\x18\xe9\xe4\xa0\x00\x00\x00\x00\x19" + + "\xdb\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f|:\xc0\x00\x00\x00\x00 l+\xc0\x00" + + "\x00\x00\x00!\\\x1c\xc0\x00\x00\x00\x00\"L\r\xc0\x00\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\v\xd1\xc0\x00\x00\x00\x00'\x04\xfd@\x00\x00\x00\x00'" + + "\xf4\xee@\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)x\x95P\x00\x00\x00\x00)\xd4\xd0@\x00\x00\x00\x00*\xc4\xc1@\x00\x00\x00\x00+\xb4\xb2@\x00\x00\x00\x00,\xa4\xa3@\x00\x00\x00\x00-\x94\x94@\x00" + + "\x00\x00\x00.\x84\x85@\x00\x00\x00\x00/tv@\x00\x00\x00\x000dg@\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x002rm\xc0\x00\x00\x00\x003=t\xc0\x00\x00\x00\x004RO\xc0\x00\x00\x00\x005" + + "\x1dV\xc0\x00\x00\x00\x00621\xc0\x00\x00\x00\x006\xfd8\xc0\x00\x00\x00\x008\x1bN@\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb0@\x00\x00\x00\x00:\xbc\xfc\xc0\x00\x00\x00\x00;\xdb\x12@\x00" + + "\x00\x00\x00<\xa6\x19@\x00\x00\x00\x00=\xba\xf4@\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A\x83\xf2\xc0\x00\x00\x00\x00BE\xbf@\x00\x00\x00\x00C" + + "c\xd4\xc0\x00\x00\x00\x00D%\xa1@\x00\x00\x00\x00EC\xb6\xc0\x00\x00\x00\x00F\x05\x83@\x00\x00\x00\x00G#\x98\xc0\x00\x00\x00\x00G\xee\x9f\xc0\x00\x00\x00\x00I\x03z\xc0\x00\x00\x00\x00I\u0381\xc0\x00" + + "\x00\x00\x00J\xe3\\\xc0\x00\x00\x00\x00K\xaec\xc0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x00\x00\x00\x00TK\xf30\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\b\x04\x04\x00\x00D\xca\x00\x00\x00" + + "\x00FP\x00\x04\x00\x00bp\x01\b\x00\x00T`\x00\f\x00\x00T`\x00\f\x00\x00bp\x01\b\x00\x00T`\x01\f\x00\x00FP\x00\x04\x00\x00bp\x00\b\x00\x00bp\x01\b\x00\x00T`\x00\fL" + + "MT\x00+05\x00+07\x00+06\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\n<+06>-6\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x018\xf0Ik\x02\x00\x00k\x02\x00" + + "\x00\x0e\x00\x1c\x00Asia/AshkhabadUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00\t\x00\x00\x00\x10\xaa\x19\x8dD\xb5\xa3\xfd@\x15'\x8b\xb0\x16\x18\xc0 \x17\b\xbf0\x17\xf9\xf3\xa0\x18\xe9\xf2\xb0\x19" + + "\xdb' \x1a\xccw\xb0\x1b\xbc\x84\xd0\x1c\xacu\xd0\x1d\x9cf\xd0\x1e\x8cW\xd0\x1f|H\xd0 l9\xd0!\\*\xd0\"L\x1b\xd0#<\f\xd0$+\xfd\xd0%\x1b\xee\xd0&\v\xdf\xd0'\x05\vP'" + + "\xf4\xfcP(\xe4\xfb`)x\xa3`\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x03\x03\x00\x006\xbc\x00\x00\x00\x008@\x00\x04\x00\x00T`\x01\b\x00" + + "\x00FP\x00\f\x00\x00FP\x00\f\x00\x00T`\x01\b\x00\x00FP\x01\f\x00\x008@\x00\x04\x00\x00FP\x00\fLMT\x00+04\x00+06\x00+05\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00" + + "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00\t\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x8dD\xff\xff\xff\xff\xb5\xa3\xfd@" + + "\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xbf0\x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00" + + "\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0" + + "\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00" + + ")x\xa3`\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x03\x03\x00\x006\xbc\x00\x00\x00\x008@\x00\x04\x00\x00T`\x01\b\x00\x00FP" + + "\x00\f\x00\x00FP\x00\f\x00\x00T`\x01\b\x00\x00FP\x01\f\x00\x008@\x00\x04\x00\x00FP\x00\fLMT\x00+04\x00+06\x00+05\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\n<+" + + "05>-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xddF\x99G_\x01\x00\x00_\x01\x00\x00\v\x00\x1c\x00Asia/SaigonUT\t\x00\x03nӧ^nӧ^" + + "ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x06\x00\x00\x00\x15\x88" + + "\x8cC\x80\x91\xa3+\n\xcd5\xe6\x80\xd1Y\xcep\xd2;>\xf0\xd52\xbb\x10\xe4\xb6\xe4\x80\xed/\x98\x00\n=\xc7\x00\u007f\xff\xff\xff\x01\x02\x03\x04\x02\x03\x02\x03\x02\x02\x00\x00d\x00\x00\x00\x00\x00c\xf6\x00" + + "\x04\x00\x00bp\x00\t\x00\x00p\x80\x00\r\x00\x00~\x90\x00\x11\x00\x00bp\x00\tLMT\x00PLMT\x00+07\x00+08\x00+09\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x06\x00\x00\x00\x15\xff\xff\xff\xff\x88\x8cC\x80\xff\xff\xff\xff\x91\xa3+\n\xff\xff\xff\xff\xcd5\xe6\x80\xff\xff\xff\xff\xd1Y" + + "\xcep\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xff\xd52\xbb\x10\xff\xff\xff\xff\xe4\xb6\xe4\x80\xff\xff\xff\xff\xed/\x98\x00\x00\x00\x00\x00\n=\xc7\x00\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x04\x02\x03\x02\x03\x02\x02" + + "\x00\x00d\x00\x00\x00\x00\x00c\xf6\x00\x04\x00\x00bp\x00\t\x00\x00p\x80\x00\r\x00\x00~\x90\x00\x11\x00\x00bp\x00\tLMT\x00PLMT\x00+07\x00+08\x00+09\x00\n<+" + + "07>-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP1\x9d\xdf\x01\xb2\x04\x00\x00\xb2\x04\x00\x00\r\x00\x1c\x00Asia/SakhalinUT\t\x00\x03nӧ^n\xd3" + + "\xa7^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\t\x00\x00\x00" + + "\x14\x86\xf0\u0378\xd20\xb2\xf0\x15'7P\x16\x18k\xc0\x17\bj\xd0\x17\xf9\x9f@\x18\xe9\x9eP\x19\xda\xd2\xc0\x1a\xcc#P\x1b\xbc0p\x1c\xac!p\x1d\x9c\x12p\x1e\x8c\x03p\x1f{\xf4p k\xe5" + + "p![\xd6p\"K\xc7p#;\xb8p$+\xa9p%\x1b\x9ap&\v\x8bp'\x04\xb6\xf0'\xf4\xa7\xf0(\xe4\xa7\x00)xO\x00)ԉ\xf0*\xc4z\xf0+\xb4k\xf0,\xa4\\\xf0-\x94M" + + "\xf0.\x84>\xf0/t/\xf00d \xf01]Lp2r'p3=.p4R\x17\x805\x1d\x1e\x8061\xf9\x806\xfd\x00\x808\x1b\x16\x008\xdc\xe2\x809\xfa\xf8\x00:\xbcĀ;\xda\xda" + + "\x00<\xa5\xe1\x00=\xba\xbc\x00>\x85\xc3\x00?\x9a\x9e\x00@e\xa5\x00A\x83\xba\x80BE\x87\x00Cc\x9c\x80D%i\x00EC~\x80F\x05K\x00G#`\x80G\xeeg\x80I\x03B\x80I\xceI" + + "\x80J\xe3$\x80K\xae+\x80L\xccA\x00M\x8e\r\x80TK\xba\xf0V\xf6\xb2\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x04\a\x04\x04\x00\x00\x85\xc8\x00\x00\x00\x00~\x90\x00\x04\x00\x00\xa8\xc0\x01\b\x00\x00\x9a\xb0\x00\f" + + "\x00\x00\x9a\xb0\x00\f\x00\x00\xa8\xc0\x01\b\x00\x00\x9a\xb0\x01\f\x00\x00\x8c\xa0\x00\x10\x00\x00\x9a\xb0\x00\fLMT\x00+09\x00+12\x00+11\x00+10\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01T" + + "Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\t\x00\x00\x00\x14\xff\xff\xff\xff\x86\xf0\u0378\xff\xff\xff\xff\xd20\xb2\xf0\x00" + + "\x00\x00\x00\x15'7P\x00\x00\x00\x00\x16\x18k\xc0\x00\x00\x00\x00\x17\bj\xd0\x00\x00\x00\x00\x17\xf9\x9f@\x00\x00\x00\x00\x18\xe9\x9eP\x00\x00\x00\x00\x19\xda\xd2\xc0\x00\x00\x00\x00\x1a\xcc#P\x00\x00\x00\x00\x1b" + + "\xbc0p\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x03p\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xe5p\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\"K\xc7p\x00" + + "\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\v\x8bp\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xa7\xf0\x00\x00\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00)" + + "xO\x00\x00\x00\x00\x00)ԉ\xf0\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00,\xa4\\\xf0\x00\x00\x00\x00-\x94M\xf0\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t/\xf0\x00" + + "\x00\x00\x000d \xf0\x00\x00\x00\x001]Lp\x00\x00\x00\x002r'p\x00\x00\x00\x003=.p\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006" + + "\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xfa\xf8\x00\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00" + + "\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D%i\x00\x00\x00\x00\x00E" + + "C~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xeeg\x80\x00\x00\x00\x00I\x03B\x80\x00\x00\x00\x00I\xceI\x80\x00\x00\x00\x00J\xe3$\x80\x00\x00\x00\x00K\xae+\x80\x00" + + "\x00\x00\x00L\xccA\x00\x00\x00\x00\x00M\x8e\r\x80\x00\x00\x00\x00TK\xba\xf0\x00\x00\x00\x00V\xf6\xb2\x00\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x06\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x04\a\x04\x04\x00\x00\x85\xc8\x00\x00\x00\x00~\x90\x00\x04\x00\x00" + + "\xa8\xc0\x01\b\x00\x00\x9a\xb0\x00\f\x00\x00\x9a\xb0\x00\f\x00\x00\xa8\xc0\x01\b\x00\x00\x9a\xb0\x01\f\x00\x00\x8c\xa0\x00\x10\x00\x00\x9a\xb0\x00\fLMT\x00+09\x00+12\x00+11\x00+10\x00" + + "\x00\x00\x00\x00\x01\x01\x01\x01\x01\n<+11>-11\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf5Dk\x8d\xb3\x04\x00\x00\xb3\x04\x00\x00\x0e\x00\x1c\x00Asia/Hong_K" + + "ongUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00" + + "\x00\x00\x00\x00\x00\x00E\x00\x00\x00\a\x00\x00\x00\x16\x85ic\x90\xcaM10\xcaۓ0\xcbKqxҠސ\xd3k׀ԓX\xb8\xd5B\xb08\xd6s:\xb8\xd7>A\xb8\xd8.2\xb8\xd8" + + "\xf99\xb8\xda\x0e\x14\xb8\xda\xd9\x1b\xb8\xdb\xed\xf6\xb8ܸ\xfd\xb8\xdd\xcdظޢ\x1a8߶\xf58\xe0\x81\xfc8\xe1\x96\xc9(\xe2Oi8\xe3v\xab(\xe4/K8\xe5_Ǩ\xe6\x0f-8\xe7" + + "?\xa9\xa8\xe7\xf8I\xb8\xe9\x1f\x8b\xa8\xe9\xd8+\xb8\xea\xffm\xa8\xeb\xb8\r\xb8\xec\xdfO\xa8\xed\x97\xef\xb8\xee\xc8l(\xefwѸ\xf0\xa8N(\xf1W\xb3\xb8\xf2\x880(\xf3@\xd08\xf4h\x12(\xf5" + + " \xb28\xf6G\xf4(\xf7%~8\xf8\x15a(\xf9\x05`8\xf9\xf5C(\xfa\xe5B8\xfb\xde_\xa8\xfc\xce^\xb8\xfd\xbeA\xa8\xfe\xae@\xb8\xff\x9e#\xa8\x00\x8e\"\xb8\x01~\x05\xa8\x02n\x04\xb8\x03" + + "]\xe7\xa8\x04M\xe6\xb8\x05G\x04(\x067\x038\a&\xe6(\a\x83=8\t\x06\xc8(\t\xf6\xc78\n\xe6\xaa(\v֩8\fƌ(\x11\x9b98\x12ol\xa8\x01\x02\x03\x04\x01\x02\x05\x06\x05" + + "\x06\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x00\x00k\n\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x01\b\x00\x00w\x88\x01\r\x00\x00~\x90\x00\x12\x00\x00p\x80\x00\x04\x00\x00~\x90\x01\bLMT\x00HKT\x00HKST\x00HKWT\x00" + + "JST\x00\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00E\x00\x00\x00\a\x00\x00\x00\x16\xff\xff\xff\xff\x85" + + "ic\x90\xff\xff\xff\xff\xcaM10\xff\xff\xff\xff\xcaۓ0\xff\xff\xff\xff\xcbKqx\xff\xff\xff\xffҠސ\xff\xff\xff\xff\xd3k׀\xff\xff\xff\xffԓX\xb8\xff\xff\xff\xff\xd5B\xb08\xff" + + "\xff\xff\xff\xd6s:\xb8\xff\xff\xff\xff\xd7>A\xb8\xff\xff\xff\xff\xd8.2\xb8\xff\xff\xff\xff\xd8\xf99\xb8\xff\xff\xff\xff\xda\x0e\x14\xb8\xff\xff\xff\xff\xda\xd9\x1b\xb8\xff\xff\xff\xff\xdb\xed\xf6\xb8\xff\xff\xff\xff\xdc" + + "\xb8\xfd\xb8\xff\xff\xff\xff\xdd\xcdظ\xff\xff\xff\xffޢ\x1a8\xff\xff\xff\xff߶\xf58\xff\xff\xff\xff\xe0\x81\xfc8\xff\xff\xff\xff\xe1\x96\xc9(\xff\xff\xff\xff\xe2Oi8\xff\xff\xff\xff\xe3v\xab(\xff" + + "\xff\xff\xff\xe4/K8\xff\xff\xff\xff\xe5_Ǩ\xff\xff\xff\xff\xe6\x0f-8\xff\xff\xff\xff\xe7?\xa9\xa8\xff\xff\xff\xff\xe7\xf8I\xb8\xff\xff\xff\xff\xe9\x1f\x8b\xa8\xff\xff\xff\xff\xe9\xd8+\xb8\xff\xff\xff\xff\xea" + + "\xffm\xa8\xff\xff\xff\xff\xeb\xb8\r\xb8\xff\xff\xff\xff\xec\xdfO\xa8\xff\xff\xff\xff\xed\x97\xef\xb8\xff\xff\xff\xff\xee\xc8l(\xff\xff\xff\xff\xefwѸ\xff\xff\xff\xff\xf0\xa8N(\xff\xff\xff\xff\xf1W\xb3\xb8\xff" + + "\xff\xff\xff\xf2\x880(\xff\xff\xff\xff\xf3@\xd08\xff\xff\xff\xff\xf4h\x12(\xff\xff\xff\xff\xf5 \xb28\xff\xff\xff\xff\xf6G\xf4(\xff\xff\xff\xff\xf7%~8\xff\xff\xff\xff\xf8\x15a(\xff\xff\xff\xff\xf9" + + "\x05`8\xff\xff\xff\xff\xf9\xf5C(\xff\xff\xff\xff\xfa\xe5B8\xff\xff\xff\xff\xfb\xde_\xa8\xff\xff\xff\xff\xfc\xce^\xb8\xff\xff\xff\xff\xfd\xbeA\xa8\xff\xff\xff\xff\xfe\xae@\xb8\xff\xff\xff\xff\xff\x9e#\xa8\x00" + + "\x00\x00\x00\x00\x8e\"\xb8\x00\x00\x00\x00\x01~\x05\xa8\x00\x00\x00\x00\x02n\x04\xb8\x00\x00\x00\x00\x03]\xe7\xa8\x00\x00\x00\x00\x04M\xe6\xb8\x00\x00\x00\x00\x05G\x04(\x00\x00\x00\x00\x067\x038\x00\x00\x00\x00\a" + + "&\xe6(\x00\x00\x00\x00\a\x83=8\x00\x00\x00\x00\t\x06\xc8(\x00\x00\x00\x00\t\xf6\xc78\x00\x00\x00\x00\n\xe6\xaa(\x00\x00\x00\x00\v֩8\x00\x00\x00\x00\fƌ(\x00\x00\x00\x00\x11\x9b98\x00" + + "\x00\x00\x00\x12ol\xa8\x01\x02\x03\x04\x01\x02\x05\x06\x05\x06\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00k\n\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x01\b\x00\x00w\x88\x01\r\x00\x00~\x90\x00\x12\x00\x00p\x80\x00\x04\x00\x00~\x90\x01\bLM" + + "T\x00HKT\x00HKST\x00HKWT\x00JST\x00\x00\x00\x00\x00\x00\x01\x01\nHKT-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x90\xc4\xe3*\xc7\x00\x00\x00\xc7\x00\x00\x00" + + "\x0f\x00\x1c\x00Asia/Phnom_PenhUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\f\x80\x00\x00\x00\xa2jg\xc4\u007f\xff\xff\xff\x01\x02\x02\x00\x00^<\x00\x00\x00\x00^<\x00\x04\x00\x00" + + "bp\x00\bLMT\x00BMT\x00+07\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\f" + + "\xff\xff\xff\xffV\xb6\x85\xc4\xff\xff\xff\xff\xa2jg\xc4\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x02\x00\x00^<\x00\x00\x00\x00^<\x00\x04\x00\x00bp\x00\bLMT\x00BMT\x00+07\x00\n<+" + + "07>-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x83\xd5\x04\xbb\xd2\a\x00\x00\xd2\a\x00\x00\f\x00\x1c\x00Asia/NicosiaUT\t\x00\x03nӧ^nӧ" + + "^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\u007f\x00\x00\x00\x05\x00\x00\x00\r" + + "\xa5w\x1e\xb8\t\xed\xaf\xe0\nݒ\xd0\v\xfad\xe0\f\xbe\xc6P\r\xa49`\x0e\x8a\xe1\xd0\x0f\x84\x1b`\x10uO\xd0\x11c\xfd`\x12S\xe0P\x13M\x19\xe0\x143\xc2P\x15#\xc1`\x16\x13\xa4P" + + "\x17\x03\xa3`\x17\xf3\x86P\x18\xe3\x85`\x19\xd3hP\x1a\xc3g`\x1b\xbc\x84\xd0\x1c\xac\x83\xe0\x1d\x9cf\xd0\x1e\x8ce\xe0\x1f|H\xd0 lG\xe0!\\*\xd0\"L)\xe0#<\f\xd0$,\v\xe0" + + "%\x1b\xee\xd0&\v\xed\xe0'\x05\vP'\xf5\n`(\xe4\xedP)\xd4\xec`*\xc4\xcfP+\xb4\xce`,\xa4\xb1P-\x94\xb0`.\x84\x93P/t\x92`0duP1]\xae\xe02M\x91\xd0" + + "3=\x90\xe04-s\xd05\x1dr\xe062x\x106\xfd\u007f\x108\x1b\x94\x908\xdda\x109\xfbv\x90:\xbdC\x10;\xdbX\x90<\xa6_\x90=\xbb:\x90>\x86A\x90?\x9b\x1c\x90@f#\x90" + + "A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90" + + "Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10" + + "]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90" + + "k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10" + + "y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x1fH\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00\x1c \x00\t\x00" + + "\x00*0\x01\x04LMT\x00EEST\x00EET\x00\x00\x00\x00\x01\x01\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00" + + "\x00\x00\x00\u007f\x00\x00\x00\x05\x00\x00\x00\r\xff\xff\xff\xff\xa5w\x1e\xb8\x00\x00\x00\x00\t\xed\xaf\xe0\x00\x00\x00\x00\nݒ\xd0\x00\x00\x00\x00\v\xfad\xe0\x00\x00\x00\x00\f\xbe\xc6P\x00\x00\x00\x00\r\xa49`" + + "\x00\x00\x00\x00\x0e\x8a\xe1\xd0\x00\x00\x00\x00\x0f\x84\x1b`\x00\x00\x00\x00\x10uO\xd0\x00\x00\x00\x00\x11c\xfd`\x00\x00\x00\x00\x12S\xe0P\x00\x00\x00\x00\x13M\x19\xe0\x00\x00\x00\x00\x143\xc2P\x00\x00\x00\x00" + + "\x15#\xc1`\x00\x00\x00\x00\x16\x13\xa4P\x00\x00\x00\x00\x17\x03\xa3`\x00\x00\x00\x00\x17\xf3\x86P\x00\x00\x00\x00\x18\xe3\x85`\x00\x00\x00\x00\x19\xd3hP\x00\x00\x00\x00\x1a\xc3g`\x00\x00\x00\x00\x1b\xbc\x84\xd0" + + "\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00" + + "#<\f\xd0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)\xd4\xec`" + + "\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x00" + + "1]\xae\xe0\x00\x00\x00\x002M\x91\xd0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004-s\xd0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\u007f\x10\x00\x00\x00\x008\x1b\x94\x90" + + "\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00" + + "?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ" + + "\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00" + + "M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90" + + "\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00" + + "[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10" + + "\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00" + + "i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10" + + "\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00" + + "x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90" + + "\x00\x00\x00\x00\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x1fH\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00\x1c \x00\t\x00\x00*0\x01\x04LMT\x00EEST\x00EET\x00\x00\x00" + + "\x00\x01\x01\x00\x00\x00\x01\x01\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP8\xa9\x16m\xd7\x03\x00\x00" + + "\xd7\x03\x00\x00\f\x00\x1c\x00Asia/BaghdadUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x007\x00\x00\x00\x06\x00\x00\x00\x10\x80\x00\x00\x00\x9e0<\xe0\x170hP\x17\xfa\x0f\xc0\x18\xe8\xbdP\x19\xdbC@\x1a̓\xd0" + + "\x1b\xbd\xc8@\x1c\xad\xc7P\x1d\x9ct\xe0\x1e\x8ce\xe0\x1f|V\xe0 lG\xe0!\\8\xe0\"L)\xe0#<\x1a\xe0$,\v\xe0%\x1b\xfc\xe0&\v\xed\xe0'\x05\x19`'\xf6x\x00(纀" + + ")\xd8\xfd\x00*\xca?\x80+\xba0\x80,\xabs\x00-\x9bd\x00.\x8c\xa6\x80/|\x97\x800m\xda\x001_\x1c\x802P_\x003@P\x0041\x92\x805!\x83\x806\x12\xc6\x007\x02\xb7\x00" + + "7\xf3\xf9\x808\xe5<\x009\xd6~\x80:\xc6o\x80;\xb7\xb2\x00<\xa7\xa3\x00=\x98\xe5\x80>\x88ր?z\x19\x00@k[\x80A\\\x9e\x00BL\x8f\x00C=рD-\u0080E\x1f\x05\x00" + + "F\x0e\xf6\x00G\x008\x80\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x04\x00\x00)\xa4\x00\x00\x00\x00)\xa0\x00\x04\x00\x00*0\x00\b\x00\x008@\x01\f\x00\x00*0\x00\b\x00\x008@\x01\fLMT\x00BMT\x00+03\x00+04\x00\x00" + + "\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x007\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xffi\x86\xb1\xdc\xff\xff\xff" + + "\xff\x9e0<\xe0\x00\x00\x00\x00\x170hP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xe8\xbdP\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbd\xc8@\x00\x00\x00\x00\x1c\xad\xc7" + + "P\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00" + + "\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\x19`\x00\x00\x00\x00'\xf6x\x00\x00\x00\x00\x00(纀\x00\x00\x00\x00)\xd8\xfd\x00\x00\x00\x00\x00*\xca?" + + "\x80\x00\x00\x00\x00+\xba0\x80\x00\x00\x00\x00,\xabs\x00\x00\x00\x00\x00-\x9bd\x00\x00\x00\x00\x00.\x8c\xa6\x80\x00\x00\x00\x00/|\x97\x80\x00\x00\x00\x000m\xda\x00\x00\x00\x00\x001_\x1c\x80\x00\x00\x00" + + "\x002P_\x00\x00\x00\x00\x003@P\x00\x00\x00\x00\x0041\x92\x80\x00\x00\x00\x005!\x83\x80\x00\x00\x00\x006\x12\xc6\x00\x00\x00\x00\x007\x02\xb7\x00\x00\x00\x00\x007\xf3\xf9\x80\x00\x00\x00\x008\xe5<" + + "\x00\x00\x00\x00\x009\xd6~\x80\x00\x00\x00\x00:\xc6o\x80\x00\x00\x00\x00;\xb7\xb2\x00\x00\x00\x00\x00<\xa7\xa3\x00\x00\x00\x00\x00=\x98\xe5\x80\x00\x00\x00\x00>\x88ր\x00\x00\x00\x00?z\x19\x00\x00\x00\x00" + + "\x00@k[\x80\x00\x00\x00\x00A\\\x9e\x00\x00\x00\x00\x00BL\x8f\x00\x00\x00\x00\x00C=р\x00\x00\x00\x00D-\u0080\x00\x00\x00\x00E\x1f\x05\x00\x00\x00\x00\x00F\x0e\xf6\x00\x00\x00\x00\x00G\x008" + + "\x80\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x04\x00\x00)\xa4\x00\x00\x00\x00)\xa0\x00\x04\x00\x00*0\x00\b\x00\x008@\x01\f\x00\x00*0\x00\b\x00\x008@\x01\fLMT\x00BMT\x00+03\x00+04\x00\x00\x00\x00\x00" + + "\x01\x01\n<+03>-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfe\xc4M\xa4\xb8\x04\x00\x00\xb8\x04\x00\x00\x12\x00\x1c\x00Asia/SrednekolymskU" + + "T\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00" + + "\x00\x00B\x00\x00\x00\v\x00\x00\x00\x10\xaa\x193䵣\xa8\xe0\x15'7P\x16\x18k\xc0\x17\bj\xd0\x17\xf9\x9f@\x18\xe9\x9eP\x19\xda\xd2\xc0\x1a\xcc#P\x1b\xbc0p\x1c\xac!p\x1d\x9c\x12p\x1e" + + "\x8c\x03p\x1f{\xf4p k\xe5p![\xd6p\"K\xc7p#;\xb8p$+\xa9p%\x1b\x9ap&\v\x8bp'\x04\xb6\xf0'\xf4\xa7\xf0(\xe4\xa7\x00)xO\x00)ԉ\xf0*\xc4z\xf0+" + + "\xb4k\xf0,\xa4\\\xf0-\x94M\xf0.\x84>\xf0/t/\xf00d \xf01]Lp2r'p3=.p4R\tp5\x1d\x10p61\xebp6\xfc\xf2p8\x1b\a\xf08\xdc\xd4p9" + + "\xfa\xe9\xf0:\xbc\xb6p;\xda\xcb\xf0<\xa5\xd2\xf0=\xba\xad\xf0>\x85\xb4\xf0?\x9a\x8f\xf0@e\x96\xf0A\x83\xacpBEx\xf0Cc\x8epD%Z\xf0ECppF\x05<\xf0G#RpG" + + "\xeeYpI\x034pI\xce;pJ\xe3\x16pK\xae\x1dpL\xcc2\xf0M\x8d\xffpTK\xac\xe0\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\b\x04\x04\x00\x00\x90\x1c\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\xa8\xc0\x01\b\x00" + + "\x00\x9a\xb0\x00\f\x00\x00\x9a\xb0\x00\f\x00\x00\xa8\xc0\x01\b\x00\x00\x9a\xb0\x01\f\x00\x00\x8c\xa0\x00\x04\x00\x00\xa8\xc0\x00\b\x00\x00\xa8\xc0\x01\b\x00\x00\x9a\xb0\x00\fLMT\x00+10\x00+12\x00+" + + "11\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\v\x00\x00\x00\x10\xff\xff" + + "\xff\xff\xaa\x193\xe4\xff\xff\xff\xff\xb5\xa3\xa8\xe0\x00\x00\x00\x00\x15'7P\x00\x00\x00\x00\x16\x18k\xc0\x00\x00\x00\x00\x17\bj\xd0\x00\x00\x00\x00\x17\xf9\x9f@\x00\x00\x00\x00\x18\xe9\x9eP\x00\x00\x00\x00\x19\xda" + + "\xd2\xc0\x00\x00\x00\x00\x1a\xcc#P\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x03p\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xe5p\x00\x00" + + "\x00\x00![\xd6p\x00\x00\x00\x00\"K\xc7p\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\v\x8bp\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4" + + "\xa7\xf0\x00\x00\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00)xO\x00\x00\x00\x00\x00)ԉ\xf0\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00,\xa4\\\xf0\x00\x00\x00\x00-\x94M\xf0\x00\x00" + + "\x00\x00.\x84>\xf0\x00\x00\x00\x00/t/\xf0\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Lp\x00\x00\x00\x002r'p\x00\x00\x00\x003=.p\x00\x00\x00\x004R\tp\x00\x00\x00\x005\x1d" + + "\x10p\x00\x00\x00\x0061\xebp\x00\x00\x00\x006\xfc\xf2p\x00\x00\x00\x008\x1b\a\xf0\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xfa\xe9\xf0\x00\x00\x00\x00:\xbc\xb6p\x00\x00\x00\x00;\xda\xcb\xf0\x00\x00" + + "\x00\x00<\xa5\xd2\xf0\x00\x00\x00\x00=\xba\xad\xf0\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x8f\xf0\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xacp\x00\x00\x00\x00BEx\xf0\x00\x00\x00\x00Cc" + + "\x8ep\x00\x00\x00\x00D%Z\xf0\x00\x00\x00\x00ECpp\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Rp\x00\x00\x00\x00G\xeeYp\x00\x00\x00\x00I\x034p\x00\x00\x00\x00I\xce;p\x00\x00" + + "\x00\x00J\xe3\x16p\x00\x00\x00\x00K\xae\x1dp\x00\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M\x8d\xffp\x00\x00\x00\x00TK\xac\xe0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\b\x04\x04\x00\x00\x90\x1c\x00\x00\x00\x00" + + "\x8c\xa0\x00\x04\x00\x00\xa8\xc0\x01\b\x00\x00\x9a\xb0\x00\f\x00\x00\x9a\xb0\x00\f\x00\x00\xa8\xc0\x01\b\x00\x00\x9a\xb0\x01\f\x00\x00\x8c\xa0\x00\x04\x00\x00\xa8\xc0\x00\b\x00\x00\xa8\xc0\x01\b\x00\x00\x9a\xb0\x00\fLM" + + "T\x00+10\x00+12\x00+11\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\n<+11>-11\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x018\xf0Ik\x02\x00\x00k\x02\x00" + + "\x00\r\x00\x1c\x00Asia/AshgabatUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00\t\x00\x00\x00\x10\xaa\x19\x8dD\xb5\xa3\xfd@\x15'\x8b\xb0\x16\x18\xc0 \x17\b\xbf0\x17\xf9\xf3\xa0\x18\xe9\xf2\xb0\x19\xdb" + + "' \x1a\xccw\xb0\x1b\xbc\x84\xd0\x1c\xacu\xd0\x1d\x9cf\xd0\x1e\x8cW\xd0\x1f|H\xd0 l9\xd0!\\*\xd0\"L\x1b\xd0#<\f\xd0$+\xfd\xd0%\x1b\xee\xd0&\v\xdf\xd0'\x05\vP'\xf4" + + "\xfcP(\xe4\xfb`)x\xa3`\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x03\x03\x00\x006\xbc\x00\x00\x00\x008@\x00\x04\x00\x00T`\x01\b\x00\x00" + + "FP\x00\f\x00\x00FP\x00\f\x00\x00T`\x01\b\x00\x00FP\x01\f\x00\x008@\x00\x04\x00\x00FP\x00\fLMT\x00+04\x00+06\x00+05\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00T" + + "Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00\t\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x8dD\xff\xff\xff\xff\xb5\xa3\xfd@\x00" + + "\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xbf0\x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b" + + "\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00" + + "\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)" + + "x\xa3`\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x03\x03\x00\x006\xbc\x00\x00\x00\x008@\x00\x04\x00\x00T`\x01\b\x00\x00FP\x00" + + "\f\x00\x00FP\x00\f\x00\x00T`\x01\b\x00\x00FP\x01\f\x00\x008@\x00\x04\x00\x00FP\x00\fLMT\x00+04\x00+06\x00+05\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\n<+0" + + "5>-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP)\xfa\xf8j\xd4\x00\x00\x00\xd4\x00\x00\x00\x0e\x00\x1c\x00Asia/KathmanduUT\t\x00\x03nӧ^n\xd3" + + "\xa7^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00" + + "\x10\xa1\xf2}\x84\x1e\x180\xa8\u007f\xff\xff\xff\x01\x02\x02\x00\x00O\xfc\x00\x00\x00\x00MX\x00\x04\x00\x00P\xdc\x00\nLMT\x00+0530\x00+0545\x00TZif2\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xf2}\x84\x00\x00\x00\x00\x1e\x180\xa8\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02" + + "\x02\x00\x00O\xfc\x00\x00\x00\x00MX\x00\x04\x00\x00P\xdc\x00\nLMT\x00+0530\x00+0545\x00\n<+0545>-5:45\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5" + + "F\x9cP\x80\xb9Ԣ\xb5\x03\x00\x00\xb5\x03\x00\x00\x0f\x00\x1c\x00Asia/ChoibalsanUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00" + + "\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x004\x00\x00\x00\a\x00\x00\x00\x14\x86\xd3\xe7(\x0f\vܐ\x18\xe9Ȁ\x19\xda" + + "\xee\xe0\x1a\xcc?p\x1b\xbc\"`\x1c\xac!p\x1d\x9c\x04`\x1e\x8c\x03p\x1f{\xe6` k\xe5p![\xc8`\"K\xc7p#;\xaa`$+\xa9p%\x1b\x8c`&\v\x8bp'\x04\xa8\xe0'\xf4" + + "\xa7\xf0(\xe4\x8a\xe0)ԉ\xf0*\xc4l\xe0+\xb4k\xf0,\xa4N\xe0-\x94M\xf0.\x840\xe0/t/\xf00d\x12\xe01]Lp2M/`3=.p4-\x11`5\x1d\x10p6\f" + + "\xf3`:饐;\xb4\x9e\x80<\xa4\x9d\x90=\x94\x80\x80>\x84\u007f\x90?tb\x80@da\x90ATD\x80BDC\x90C4&\x80D$%\x90E\x1dC\x00G\xef\xaa\xf0U\x15\x9a\xa0V\x05" + + "apV\xf5|\xa0W\xe5Cp\u007f\xff\xff\xff\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x02\x05\x02\x05\x02\x02\x00\x00kX\x00\x00\x00\x00bp\x00\x04\x00\x00p\x80\x00\b\x00\x00~\x90\x00\f\x00\x00\x8c\xa0\x01\x10\x00\x00~\x90\x01\f\x00\x00p\x80\x00\bLMT\x00+07\x00+08\x00" + + "+09\x00+10\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x004\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xff\x86\xd3\xe7(" + + "\x00\x00\x00\x00\x0f\vܐ\x00\x00\x00\x00\x18\xe9Ȁ\x00\x00\x00\x00\x19\xda\xee\xe0\x00\x00\x00\x00\x1a\xcc?p\x00\x00\x00\x00\x1b\xbc\"`\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x04`\x00\x00\x00\x00" + + "\x1e\x8c\x03p\x00\x00\x00\x00\x1f{\xe6`\x00\x00\x00\x00 k\xe5p\x00\x00\x00\x00![\xc8`\x00\x00\x00\x00\"K\xc7p\x00\x00\x00\x00#;\xaa`\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x8c`" + + "\x00\x00\x00\x00&\v\x8bp\x00\x00\x00\x00'\x04\xa8\xe0\x00\x00\x00\x00'\xf4\xa7\xf0\x00\x00\x00\x00(\xe4\x8a\xe0\x00\x00\x00\x00)ԉ\xf0\x00\x00\x00\x00*\xc4l\xe0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00" + + ",\xa4N\xe0\x00\x00\x00\x00-\x94M\xf0\x00\x00\x00\x00.\x840\xe0\x00\x00\x00\x00/t/\xf0\x00\x00\x00\x000d\x12\xe0\x00\x00\x00\x001]Lp\x00\x00\x00\x002M/`\x00\x00\x00\x003=.p" + + "\x00\x00\x00\x004-\x11`\x00\x00\x00\x005\x1d\x10p\x00\x00\x00\x006\f\xf3`\x00\x00\x00\x00:饐\x00\x00\x00\x00;\xb4\x9e\x80\x00\x00\x00\x00<\xa4\x9d\x90\x00\x00\x00\x00=\x94\x80\x80\x00\x00\x00\x00" + + ">\x84\u007f\x90\x00\x00\x00\x00?tb\x80\x00\x00\x00\x00@da\x90\x00\x00\x00\x00ATD\x80\x00\x00\x00\x00BDC\x90\x00\x00\x00\x00C4&\x80\x00\x00\x00\x00D$%\x90\x00\x00\x00\x00E\x1dC\x00" + + "\x00\x00\x00\x00G\xef\xaa\xf0\x00\x00\x00\x00U\x15\x9a\xa0\x00\x00\x00\x00V\x05ap\x00\x00\x00\x00V\xf5|\xa0\x00\x00\x00\x00W\xe5Cp\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x02\x05\x02\x05\x02\x02\x00\x00kX\x00\x00\x00\x00bp\x00\x04\x00\x00p\x80\x00\b\x00\x00" + + "~\x90\x00\f\x00\x00\x8c\xa0\x01\x10\x00\x00~\x90\x01\f\x00\x00p\x80\x00\bLMT\x00+07\x00+08\x00+09\x00+10\x00\n<+08>-8\nPK\x03\x04\n\x00\x00\x00\x00" + + "\x00\xf5F\x9cP\x90\xc4\xe3*\xc7\x00\x00\x00\xc7\x00\x00\x00\f\x00\x1c\x00Asia/BangkokUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00" + + "\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\f\x80\x00\x00\x00\xa2jg\xc4\u007f\xff\xff\xff\x01\x02\x02" + + "\x00\x00^<\x00\x00\x00\x00^<\x00\x04\x00\x00bp\x00\bLMT\x00BMT\x00+07\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffV\xb6\x85\xc4\xff\xff\xff\xff\xa2jg\xc4\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x02\x00\x00^<\x00\x00\x00\x00^<\x00\x04\x00\x00bp\x00\bL" + + "MT\x00BMT\x00+07\x00\n<+07>-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPy\x84\xe1i1\x02\x00\x001\x02\x00\x00\x0e\x00\x1c\x00Asia/Chung" + + "kingUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x03\x00\x00\x00\f\x80\x00\x00\x00\xa0\x97\xa2\x80\xa1y\x04\xf0\xc8Y^\x80\xc9\t\xf9p\xc9ӽ\x00\xcb\x05\x8a\xf0\xcb|@\x00\xd2;>\xf0Ӌ{\x80\xd4B\xad\xf0" + + "\xd5E\"\x00\xd6L\xbf\xf0\xd7<\xbf\x00\xd8\x06fp\xd9\x1d\xf2\x80\xd9A|\xf0\x1e\xbaR \x1fi\x9b\x90 ~\x84\xa0!I}\x90\"g\xa1 #)_\x90$G\x83 %\x12|\x10&'e " + + "&\xf2^\x10(\aG (\xd2@\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\bL" + + "MT\x00CDT\x00CST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff~" + + "6C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff\xff\xa1y\x04\xf0\xff\xff\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9\t\xf9p\xff\xff\xff\xff\xc9ӽ\x00\xff\xff\xff\xff\xcb\x05\x8a\xf0\xff\xff\xff\xff\xcb|@\x00\xff" + + "\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xffӋ{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9" + + "\x1d\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00\x00\x1e\xbaR \x00\x00\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 ~\x84\xa0\x00\x00\x00\x00!I}\x90\x00\x00\x00\x00\"g\xa1 \x00\x00\x00\x00#)_\x90\x00" + + "\x00\x00\x00$G\x83 \x00\x00\x00\x00%\x12|\x10\x00\x00\x00\x00&'e \x00\x00\x00\x00&\xf2^\x10\x00\x00\x00\x00(\aG \x00\x00\x00\x00(\xd2@\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\bLMT\x00CDT\x00CST\x00\nCST-8\nPK\x03\x04\n\x00\x00" + + "\x00\x00\x00\xf5F\x9cP\x88\x98*\xc3\xc5\x04\x00\x00\xc5\x04\x00\x00\x10\x00\x1c\x00Asia/NovosibirskUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01" + + "\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00D\x00\x00\x00\n\x00\x00\x00\x10\xa1\xdb\x19$\xb5\xa3\xe1 \x15" + + "'o\x90\x16\x18\xa4\x00\x17\b\xa3\x10\x17\xf9׀\x18\xe9\u0590\x19\xdb\v\x00\x1a\xcc[\x90\x1b\xbch\xb0\x1c\xacY\xb0\x1d\x9cJ\xb0\x1e\x8c;\xb0\x1f|,\xb0 l\x1d\xb0!\\\x0e\xb0\"K\xff\xb0#" + + ";\xf0\xb0$+\xe1\xb0%\x1bҰ&\vð'\x04\xef0'\xf4\xe00(\xe4\xdf@)x\x87@)\xd4\xc20*ij0+\xb4\xa40+\xfeN\x00,\xa4\xa3@-\x94\x94@.\x84\x85@/" + + "tv@0dg@1]\x92\xc02rm\xc03=t\xc04RO\xc05\x1dV\xc0621\xc06\xfd8\xc08\x1bN@8\xdd\x1a\xc09\xfb0@:\xbc\xfc\xc0;\xdb\x12@<\xa6\x19@=" + + "\xba\xf4@>\x85\xfb@?\x9a\xd6@@e\xdd@A\x83\xf2\xc0BE\xbf@Cc\xd4\xc0D%\xa1@EC\xb6\xc0F\x05\x83@G#\x98\xc0G\xee\x9f\xc0I\x03z\xc0I\u0381\xc0J\xe3\\\xc0K" + + "\xaec\xc0L\xccy@M\x8eE\xc0TK\xf30W\x93\xcc\xc0\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\b\a\x06\a\x06\a\x06\a\x06" + + "\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x04\a\x04\x04\x00\x00M\xbc\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\f\x00\x00bp\x00" + + "\f\x00\x00p\x80\x01\b\x00\x00bp\x01\f\x00\x00T`\x00\x04\x00\x00bp\x01\f\x00\x00bp\x00\fLMT\x00+06\x00+08\x00+07\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x01TZi" + + "f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00D\x00\x00\x00\n\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xdb\x19$\xff\xff\xff\xff\xb5\xa3\xe1 \x00\x00\x00" + + "\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\b\xa3\x10\x00\x00\x00\x00\x17\xf9׀\x00\x00\x00\x00\x18\xe9\u0590\x00\x00\x00\x00\x19\xdb\v\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbch" + + "\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00\x00\x00\x00 l\x1d\xb0\x00\x00\x00\x00!\\\x0e\xb0\x00\x00\x00\x00\"K\xff\xb0\x00\x00\x00" + + "\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1bҰ\x00\x00\x00\x00&\vð\x00\x00\x00\x00'\x04\xef0\x00\x00\x00\x00'\xf4\xe00\x00\x00\x00\x00(\xe4\xdf@\x00\x00\x00\x00)x\x87" + + "@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*ij0\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00+\xfeN\x00\x00\x00\x00\x00,\xa4\xa3@\x00\x00\x00\x00-\x94\x94@\x00\x00\x00\x00.\x84\x85@\x00\x00\x00" + + "\x00/tv@\x00\x00\x00\x000dg@\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x002rm\xc0\x00\x00\x00\x003=t\xc0\x00\x00\x00\x004RO\xc0\x00\x00\x00\x005\x1dV\xc0\x00\x00\x00\x00621" + + "\xc0\x00\x00\x00\x006\xfd8\xc0\x00\x00\x00\x008\x1bN@\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb0@\x00\x00\x00\x00:\xbc\xfc\xc0\x00\x00\x00\x00;\xdb\x12@\x00\x00\x00\x00<\xa6\x19@\x00\x00\x00" + + "\x00=\xba\xf4@\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A\x83\xf2\xc0\x00\x00\x00\x00BE\xbf@\x00\x00\x00\x00Cc\xd4\xc0\x00\x00\x00\x00D%\xa1" + + "@\x00\x00\x00\x00EC\xb6\xc0\x00\x00\x00\x00F\x05\x83@\x00\x00\x00\x00G#\x98\xc0\x00\x00\x00\x00G\xee\x9f\xc0\x00\x00\x00\x00I\x03z\xc0\x00\x00\x00\x00I\u0381\xc0\x00\x00\x00\x00J\xe3\\\xc0\x00\x00\x00" + + "\x00K\xaec\xc0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x00\x00\x00\x00TK\xf30\x00\x00\x00\x00W\x93\xcc\xc0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x05\x04\x05\b\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x04\a\x04\x04\x00\x00M\xbc\x00\x00\x00" + + "\x00T`\x00\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\f\x00\x00bp\x00\f\x00\x00p\x80\x01\b\x00\x00bp\x01\f\x00\x00T`\x00\x04\x00\x00bp\x01\f\x00\x00bp\x00\fLMT\x00+06" + + "\x00+08\x00+07\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x01\n<+07>-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP?=\x188\xec\a\x00\x00\xec\a\x00\x00\x0e\x00\x1c\x00As" + + "ia/FamagustaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00~\x00\x00\x00\a\x00\x00\x00\x11\xa5w\x1e,\t\xed\xaf\xe0\nݒ\xd0\v\xfad\xe0\f\xbe\xc6P\r\xa49`\x0e\x8a\xe1\xd0\x0f\x84\x1b`\x10uO\xd0" + + "\x11c\xfd`\x12S\xe0P\x13M\x19\xe0\x143\xc2P\x15#\xc1`\x16\x13\xa4P\x17\x03\xa3`\x17\xf3\x86P\x18\xe3\x85`\x19\xd3hP\x1a\xc3g`\x1b\xbc\x84\xd0\x1c\xac\x83\xe0\x1d\x9cf\xd0\x1e\x8ce\xe0" + + "\x1f|H\xd0 lG\xe0!\\*\xd0\"L)\xe0#<\f\xd0$,\v\xe0%\x1b\xee\xd0&\v\xed\xe0'\x05\vP'\xf5\n`(\xe4\xedP)\xd4\xec`*\xc4\xcfP+\xb4\xce`,\xa4\xb1P" + + "-\x94\xb0`.\x84\x93P/t\x92`0duP1]\xae\xe02M\x91\xd03=\x90\xe04-s\xd05\x1dr\xe062x\x106\xfd\u007f\x108\x1b\x94\x908\xdda\x109\xfbv\x90:\xbdC\x10" + + ";\xdbX\x90<\xa6_\x90=\xbb:\x90>\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10" + + "I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90" + + "W\xd0\u007f\xd0Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90" + + "g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10" + + "u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x05\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x1f\xd4\x00\x00" + + "\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00\x1c \x00\t\x00\x00*0\x01\x04\x00\x00*0\x00\r\x00\x00\x1c \x00\tLMT\x00EEST\x00EET\x00+03\x00\x00\x00\x00\x01\x01\x00\x01" + + "\x00\x00\x00\x01\x01\x00\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00~\x00\x00\x00\a\x00\x00\x00\x11\xff\xff\xff\xff\xa5w\x1e,\x00" + + "\x00\x00\x00\t\xed\xaf\xe0\x00\x00\x00\x00\nݒ\xd0\x00\x00\x00\x00\v\xfad\xe0\x00\x00\x00\x00\f\xbe\xc6P\x00\x00\x00\x00\r\xa49`\x00\x00\x00\x00\x0e\x8a\xe1\xd0\x00\x00\x00\x00\x0f\x84\x1b`\x00\x00\x00\x00\x10" + + "uO\xd0\x00\x00\x00\x00\x11c\xfd`\x00\x00\x00\x00\x12S\xe0P\x00\x00\x00\x00\x13M\x19\xe0\x00\x00\x00\x00\x143\xc2P\x00\x00\x00\x00\x15#\xc1`\x00\x00\x00\x00\x16\x13\xa4P\x00\x00\x00\x00\x17\x03\xa3`\x00" + + "\x00\x00\x00\x17\xf3\x86P\x00\x00\x00\x00\x18\xe3\x85`\x00\x00\x00\x00\x19\xd3hP\x00\x00\x00\x00\x1a\xc3g`\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e" + + "\x8ce\xe0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xee\xd0\x00" + + "\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00," + + "\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002M\x91\xd0\x00\x00\x00\x003=\x90\xe0\x00" + + "\x00\x00\x004-s\xd0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\u007f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:" + + "\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00" + + "\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I" + + "\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00" + + "\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V" + + "\xf70\x90\x00\x00\x00\x00W\xd0\u007f\xd0\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00" + + "\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f" + + "\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00" + + "\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00t" + + "E\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00" + + "\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x05\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x1f\xd4\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c" + + " \x00\t\x00\x00\x1c \x00\t\x00\x00*0\x01\x04\x00\x00*0\x00\r\x00\x00\x1c \x00\tLMT\x00EEST\x00EET\x00+03\x00\x00\x00\x00\x01\x01\x00\x01\x00\x00\x00\x01\x01\x00\x01\nE" + + "ET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x1d`u\xd5\f\x01\x00\x00\f\x01\x00\x00\f\x00\x1c\x00As" + + "ia/RangoonUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x12\x80\x00\x00\x00\xa1\xf2sQ\xcb\xf2\xfc\x18њg\xf0\u007f\xff\xff\xff\x01\x02\x03\x02\x02\x00\x00Z/\x00\x00\x00\x00Z/\x00\x04\x00" + + "\x00[h\x00\b\x00\x00~\x90\x00\x0e\x00\x00[h\x00\bLMT\x00RMT\x00+0630\x00+09\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x12\xff\xff\xff\xffV\xb6\x89\xd1\xff\xff\xff\xff\xa1\xf2sQ\xff\xff\xff\xff\xcb\xf2\xfc\x18\xff\xff\xff\xffњg\xf0\x00\x00\x00\x00\u007f\xff\xff\xff\x01" + + "\x02\x03\x02\x02\x00\x00Z/\x00\x00\x00\x00Z/\x00\x04\x00\x00[h\x00\b\x00\x00~\x90\x00\x0e\x00\x00[h\x00\bLMT\x00RMT\x00+0630\x00+09\x00\n<+0630>" + + "-6:30\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xddF\x99G_\x01\x00\x00_\x01\x00\x00\x10\x00\x1c\x00Asia/Ho_Chi_MinhUT\t\x00\x03nӧ" + + "^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x06" + + "\x00\x00\x00\x15\x88\x8cC\x80\x91\xa3+\n\xcd5\xe6\x80\xd1Y\xcep\xd2;>\xf0\xd52\xbb\x10\xe4\xb6\xe4\x80\xed/\x98\x00\n=\xc7\x00\u007f\xff\xff\xff\x01\x02\x03\x04\x02\x03\x02\x03\x02\x02\x00\x00d\x00\x00\x00" + + "\x00\x00c\xf6\x00\x04\x00\x00bp\x00\t\x00\x00p\x80\x00\r\x00\x00~\x90\x00\x11\x00\x00bp\x00\tLMT\x00PLMT\x00+07\x00+08\x00+09\x00TZif2\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x06\x00\x00\x00\x15\xff\xff\xff\xff\x88\x8cC\x80\xff\xff\xff\xff\x91\xa3+\n\xff\xff\xff\xff\xcd5\xe6\x80\xff" + + "\xff\xff\xff\xd1Y\xcep\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xff\xd52\xbb\x10\xff\xff\xff\xff\xe4\xb6\xe4\x80\xff\xff\xff\xff\xed/\x98\x00\x00\x00\x00\x00\n=\xc7\x00\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x04\x02" + + "\x03\x02\x03\x02\x02\x00\x00d\x00\x00\x00\x00\x00c\xf6\x00\x04\x00\x00bp\x00\t\x00\x00p\x80\x00\r\x00\x00~\x90\x00\x11\x00\x00bp\x00\tLMT\x00PLMT\x00+07\x00+08\x00+0" + + "9\x00\n<+07>-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x1c\x00Atlantic/UT\t\x00\x03nӧ^n" + + "ӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP@\xea}\x98\x17\a\x00\x00\x17\a\x00\x00\x0e\x00\x1c\x00Atlantic/Far" + + "oeUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00" + + "\x00\x00\x00\x00\x00s\x00\x00\x00\x04\x00\x00\x00\r\x8bm\xa4X\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c" + + "\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03" + + "\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf7" + + "0\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=" + + "\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1" + + "\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xf9\xa8\x00\x00\x00\x00\x00\x00\x00" + + "\x04\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\x04LMT\x00WET\x00WEST\x00\x00\x00\x01\x01\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00" + + "\x00\x04\x00\x00\x00\x00\x00\x00\x00s\x00\x00\x00\x04\x00\x00\x00\r\xff\xff\xff\xff\x8bm\xa4X\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00" + + "\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|" + + "\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00" + + "\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce" + + "\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00" + + "\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15" + + "F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00" + + "\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b" + + "\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00" + + "\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE" + + "\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00" + + "\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xf9\xa8\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\x04LMT" + + "\x00WET\x00WEST\x00\x00\x00\x01\x01\x00\x00\x01\x01\nWET0WEST,M3.5.0/1,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x90" + + "\xc2N\xc0i\a\x00\x00i\a\x00\x00\x0f\x00\x1c\x00Atlantic/CanaryUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZ" + + "if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00v\x00\x00\x00\x06\x00\x00\x00\x11\xa6\x04\\\xf0\xd4A\xf7 \x13M6\x00\x143\xfa\x90\x15#" + + "\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#<" + + "E\x10$,6\x10%\x1c'\x10&\f\x18\x10'\x05C\x90'\xf54\x90(\xe5%\x90)\xd5\x16\x90*\xc5\a\x90+\xb4\xf8\x90,\xa4\xe9\x90-\x94ڐ.\x84ː/t\xbc\x900d\xad\x901]" + + "\xd9\x102r\xb4\x103=\xbb\x104R\x96\x105\x1d\x9d\x1062x\x106\xfd\u007f\x108\x1b\x94\x908\xdda\x109\xfbv\x90:\xbdC\x10;\xdbX\x90<\xa6_\x90=\xbb:\x90>\x86A\x90?\x9b" + + "\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e" + + "\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5" + + "\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8" + + "y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e" + + "\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\xff\xff\xf1\x90\x00\x00\xff\xff\xf1\xf0\x00\x04\x00\x00\x00\x00\x00\b\x00\x00\x0e\x10\x01\f\x00\x00\x00\x00" + + "\x00\b\x00\x00\x0e\x10\x01\fLMT\x00-01\x00WET\x00WEST\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00v\x00\x00\x00\x06\x00\x00\x00\x11\xff\xff\xff\xff\xa6\x04\\\xf0\xff\xff\xff\xff\xd4A\xf7 \x00\x00\x00\x00\x13M6\x00\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb" + + "\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00" + + "\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c" + + "\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00" + + "\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c" + + "\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00" + + "\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n" + + "\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00" + + "\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y" + + "\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00" + + "\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7" + + "\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00" + + "\x00\u007f\x8e\u007f\x90\x01\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\xff\xff\xf1\x90\x00\x00\xff\xff\xf1\xf0\x00\x04\x00\x00\x00\x00\x00\b\x00\x00\x0e\x10\x01\f\x00\x00\x00\x00\x00\b\x00\x00\x0e\x10\x01\fLMT\x00-01\x00WET\x00WEST\x00\x00\x00\x00\x01" + + "\x01\x01\x00\x00\x00\x00\x01\x01\nWET0WEST,M3.5.0/1,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPSf\xc4&\xbe\x04\x00\x00\xbe\x04\x00" + + "\x00\x10\x00\x1c\x00Atlantic/StanleyUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00G\x00\x00\x00\a\x00\x00\x00\x14\x80\x00\x00\x00\x93D_<\xc3OZ\xc0\xc46\x030\xc5/<\xc0\xc6\x15\xe50\xc7\x18Y" + + "@\xc7\xff\x01\xb0\xc8\xf8;@\xc9\xde\xe3\xb0\xca\xd8\x1d@˾Ű̷\xff@\xcd6\x810\x19\x11\xfe@\x19Ӽ\xb0\x1a\xf1\xc4 \x1b\xaad0\x1cѦ \x1d\x8aF0\x1e\xa8[\xb0\x1fj6" + + "@ \x88=\xb0!J\x18@\"h\x1f\xb0#)\xfa@$H\x01\xb0%\t\xdc@&1\x1e0&\xe9\xbe@(\x11\x000(\xd2\xda\xc0)\xf0\xe20*\xb2\xbc\xc0+\xd0\xc40,\x92\x9e\xc0-\xb0\xa6" + + "0.r\x80\xc0/\x90\x8800Rb\xc01y\xa4\xb02;\u007f@3Y\x86\xb04\x1ba@59h\xb05\xfbC@7\x19J\xb07\xdb%@8\xf9,\xb09\xbb\a@:\xd9*\xd0;\x91\xca" + + "\xe0<\xc2GP=q\xac\xe0>\xa2)P?Z\xc9`@\x82\vPA:\xab`Ba\xedPC\x1a\x8d`DA\xcfPD\xfao`F!\xb1PF\xdaQ`H\n\xcd\xd0H\xc3m\xe0I\xea\xaf" + + "\xd0J\xa3O\xe0Kʑ\xd0L\x831\xe0\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x04\x05\x04\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x05\xff\xff\xc9\xc4\x00\x00\xff\xff\xc9\xc4\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xc7\xc0\x00\f\xff\xff\xe3\xe0\x01\x10\xff\xff" + + "\xd5\xd0\x00\b\xff\xff\xd5\xd0\x01\bLMT\x00SMT\x00-03\x00-04\x00-02\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00G\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x11\xbc\xff\xff\xff\xff\x93D_<\xff\xff\xff\xff\xc3OZ\xc0\xff\xff\xff\xff\xc46\x030\xff\xff\xff\xff\xc5/<\xc0\xff\xff\xff\xff\xc6\x15" + + "\xe50\xff\xff\xff\xff\xc7\x18Y@\xff\xff\xff\xff\xc7\xff\x01\xb0\xff\xff\xff\xff\xc8\xf8;@\xff\xff\xff\xff\xc9\xde\xe3\xb0\xff\xff\xff\xff\xca\xd8\x1d@\xff\xff\xff\xff˾Ű\xff\xff\xff\xff̷\xff@\xff\xff" + + "\xff\xff\xcd6\x810\x00\x00\x00\x00\x19\x11\xfe@\x00\x00\x00\x00\x19Ӽ\xb0\x00\x00\x00\x00\x1a\xf1\xc4 \x00\x00\x00\x00\x1b\xaad0\x00\x00\x00\x00\x1cѦ \x00\x00\x00\x00\x1d\x8aF0\x00\x00\x00\x00\x1e\xa8" + + "[\xb0\x00\x00\x00\x00\x1fj6@\x00\x00\x00\x00 \x88=\xb0\x00\x00\x00\x00!J\x18@\x00\x00\x00\x00\"h\x1f\xb0\x00\x00\x00\x00#)\xfa@\x00\x00\x00\x00$H\x01\xb0\x00\x00\x00\x00%\t\xdc@\x00\x00" + + "\x00\x00&1\x1e0\x00\x00\x00\x00&\xe9\xbe@\x00\x00\x00\x00(\x11\x000\x00\x00\x00\x00(\xd2\xda\xc0\x00\x00\x00\x00)\xf0\xe20\x00\x00\x00\x00*\xb2\xbc\xc0\x00\x00\x00\x00+\xd0\xc40\x00\x00\x00\x00,\x92" + + "\x9e\xc0\x00\x00\x00\x00-\xb0\xa60\x00\x00\x00\x00.r\x80\xc0\x00\x00\x00\x00/\x90\x880\x00\x00\x00\x000Rb\xc0\x00\x00\x00\x001y\xa4\xb0\x00\x00\x00\x002;\u007f@\x00\x00\x00\x003Y\x86\xb0\x00\x00" + + "\x00\x004\x1ba@\x00\x00\x00\x0059h\xb0\x00\x00\x00\x005\xfbC@\x00\x00\x00\x007\x19J\xb0\x00\x00\x00\x007\xdb%@\x00\x00\x00\x008\xf9,\xb0\x00\x00\x00\x009\xbb\a@\x00\x00\x00\x00:\xd9" + + "*\xd0\x00\x00\x00\x00;\x91\xca\xe0\x00\x00\x00\x00<\xc2GP\x00\x00\x00\x00=q\xac\xe0\x00\x00\x00\x00>\xa2)P\x00\x00\x00\x00?Z\xc9`\x00\x00\x00\x00@\x82\vP\x00\x00\x00\x00A:\xab`\x00\x00" + + "\x00\x00Ba\xedP\x00\x00\x00\x00C\x1a\x8d`\x00\x00\x00\x00DA\xcfP\x00\x00\x00\x00D\xfao`\x00\x00\x00\x00F!\xb1P\x00\x00\x00\x00F\xdaQ`\x00\x00\x00\x00H\n\xcd\xd0\x00\x00\x00\x00H\xc3" + + "m\xe0\x00\x00\x00\x00I\xea\xaf\xd0\x00\x00\x00\x00J\xa3O\xe0\x00\x00\x00\x00Kʑ\xd0\x00\x00\x00\x00L\x831\xe0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x04\x05\x04" + + "\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x05\xff\xff\xc9\xc4\x00\x00\xff" + + "\xff\xc9\xc4\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xc7\xc0\x00\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\b\xff\xff\xd5\xd0\x01\bLMT\x00SMT\x00-03\x00-04\x00-02\x00\n<-03" + + ">3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb7F\x06L\xba\a\x00\x00\xba\a\x00\x00\x10\x00\x1c\x00Atlantic/BermudaUT\t\x00\x03nӧ^n\xd3" + + "\xa7^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x00\x00\x00\x03\x00\x00\x00" + + "\f\xb4\xc3\x1d\xe6\b \xb3`\t\x10\x96P\n\x00\x95`\n\xf0xP\v\xe0w`\fٔ\xd0\r\xc0Y`\x0e\xb9v\xd0\x0f\xa9u\xe0\x10\x99X\xd0\x11\x89W\xe0\x12y:\xd0\x13i9\xe0\x14Y\x1c" + + "\xd0\x15I\x1b\xe0\x168\xfe\xd0\x17(\xfd\xe0\x18\"\x1bP\x19\b\xdf\xe0\x1a\x01\xfdP\x1a\xf1\xfc`\x1b\xe1\xdfP\x1c\xd1\xde`\x1d\xc1\xc1P\x1e\xb1\xc0`\x1f\xa1\xa3P u\xf2\xe0!\x81\x85P\"U\xd4" + + "\xe0#j\xa1\xd0$5\xb6\xe0%J\x83\xd0&\x15\x98\xe0'*e\xd0'\xfe\xb5`)\nG\xd0)ޗ`*\xea)\xd0+\xbey`,\xd3FP-\x9e[`.\xb3(P/~=`0\x93\n" + + "P1gY\xe02r\xecP3G;\xe04R\xceP5'\x1d\xe062\xb0P7\x06\xff\xe08\x1b\xcc\xd08\xe6\xe1\xe09\xfb\xae\xd0:\xc6\xc3\xe0;ې\xd0<\xaf\xe0`=\xbbr\xd0>\x8f\xc2" + + "`?\x9bT\xd0@o\xa4`A\x84qPBO\x86`CdSPD/h`ED5PE\xf3\x9a\xe0G-Q\xd0G\xd3|\xe0I\r3\xd0I\xb3^\xe0J\xed\x15\xd0K\x9c{`L\xd62" + + "PM|]`N\xb6\x14PO\\?`P\x95\xf6PQ\x8f\xc2`" + + "\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@o\xa4`\x00\x00\x00\x00A\x84qP\x00\x00\x00\x00BO\x86`\x00\x00\x00\x00CdSP\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00" + + "E\xf3\x9a\xe0\x00\x00\x00\x00G-Q\xd0\x00\x00\x00\x00G\xd3|\xe0\x00\x00\x00\x00I\r3\xd0\x00\x00\x00\x00I\xb3^\xe0\x00\x00\x00\x00J\xed\x15\xd0\x00\x00\x00\x00K\x9c{`\x00\x00\x00\x00L\xd62P" + + "\x00\x00\x00\x00M|]`\x00\x00\x00\x00N\xb6\x14P\x00\x00\x00\x00O\\?`\x00\x00\x00\x00P\x95\xf6P\x00\x00\x00\x00Q2\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xae\x18\x88\x94\x00\x00\x00\x94\x00\x00\x00\x12\x00\x1c\x00Atlantic/St" + + "_HelenaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGM" + + "T0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa7\x99\x04[\xb4\b\x00\x00\xb4\b\x00\x00\x12\x00\x1c\x00Atlantic/Jan_MayenUT\t\x00\x03nӧ^" + + "nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x8d\x00\x00\x00\a\x00" + + "\x00\x00\r\x80\x00\x00\x00\x9b'\xe3\x00\x9b\xd4{`ȷM`\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10Ђ%\x10\xd1r\x16\x10\xd2b\a\x10\xeb\xaf \x90\xec\xa8L\x10\xed\x98=\x10\xee" + + "\x88.\x10\xefx\x1f\x10\xf0h\x10\x10\xf1X\x01\x10\xf2G\xf2\x10\xf37\xe3\x10\xf4'\xd4\x10\xf5\x17\xc5\x10\xf6\x10\xf0\x90\xf7/\x06\x10\xf7\xf0Ґ\x13MD\x10\x143\xfa\x90\x15#\xeb\x90\x16\x13ܐ\x17" + + "\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A" + + "\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90O" + + "nn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]" + + "\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k" + + "\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y" + + "\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\n\x14\x00\x00\x00\x00\x1c \x01\x04" + + "\x00\x00\x0e\x10\x00\t\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x01\x01TZi" + + "f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x8d\x00\x00\x00\a\x00\x00\x00\r\xff\xff\xff\xffr\xee$l\xff\xff\xff\xff\x9b'\xe3\x00\xff\xff\xff" + + "\xff\x9b\xd4{`\xff\xff\xff\xffȷM`\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16" + + "\x10\xff\xff\xff\xff\xd2b\a\x10\xff\xff\xff\xff\xeb\xaf \x90\xff\xff\xff\xff\xec\xa8L\x10\xff\xff\xff\xff\xed\x98=\x10\xff\xff\xff\xff\xee\x88.\x10\xff\xff\xff\xff\xefx\x1f\x10\xff\xff\xff\xff\xf0h\x10\x10\xff\xff\xff" + + "\xff\xf1X\x01\x10\xff\xff\xff\xff\xf2G\xf2\x10\xff\xff\xff\xff\xf37\xe3\x10\xff\xff\xff\xff\xf4'\xd4\x10\xff\xff\xff\xff\xf5\x17\xc5\x10\xff\xff\xff\xff\xf6\x10\xf0\x90\xff\xff\xff\xff\xf7/\x06\x10\xff\xff\xff\xff\xf7\xf0\xd2" + + "\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00" + + "\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr" + + "\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00" + + "\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3" + + "\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00" + + "\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12" + + "\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00" + + "\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90" + + "\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00" + + "\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00" + + "\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00" + + "\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\n\x14\x00\x00\x00\x00\x1c " + + "\x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x01\x01\n" + + "CET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP@\xea}\x98\x17\a\x00\x00\x17\a\x00\x00\x0f\x00\x1c\x00Atl" + + "antic/FaeroeUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00s\x00\x00\x00\x04\x00\x00\x00\r\x8bm\xa4X\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10" + + "\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐ" + + "G#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90" + + "U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10" + + "c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10" + + "qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90" + + "\u007f\x8e\u007f\x90\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff" + + "\xff\xf9\xa8\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\x04LMT\x00WET\x00WEST\x00\x00\x00\x01\x01\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00s\x00\x00\x00\x04\x00\x00\x00\r\xff\xff\xff\xff\x8bm\xa4X\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐" + + "\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00" + + "\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10" + + "\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00" + + "I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10" + + "\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00" + + "V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10" + + "\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00" + + "e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90" + + "\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00" + + "s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ" + + "\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xf9\xa8\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x01" + + "\b\x00\x00\x00\x00\x00\x04LMT\x00WET\x00WEST\x00\x00\x00\x01\x01\x00\x00\x01\x01\nWET0WEST,M3.5.0/1,M10.5.0\nPK\x03\x04\n" + + "\x00\x00\x00\x00\x00\xf5F\x9cP-\x84\xb1)\x8a\x04\x00\x00\x8a\x04\x00\x00\x12\x00\x1c\x00Atlantic/ReykjavikUT\t\x00\x03nӧ^nӧ^ux\v\x00" + + "\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00D\x00\x00\x00\x06\x00\x00\x00\x10\x8b`\x83\xa0\x9c" + + "\x91\x1e\x00\x9dш\x90\x9erQ\x80\x9f\xd5\x03\x10\xa0S\x85\x00\xa1\xb66\x90\xa4<'\x80\xa4\xb9t\x10\xc6M\x1a\x00\xc7=' \xc7\xda\x17\xb0\xc9&C\xa0\xc9\xc3& \xcb\x06%\xa0ˬB\xa0\xcc" + + "\xdc\xcd ͌$\xa0μ\xaf \xcfl\x06\xa0М\x91 \xd1K\xe8\xa0҅\xad\xa0\xd3+ʠ\xd4e\x8f\xa0\xd59\xd1 \xd6Eq\xa0\xd7\x19\xb3 \xd8%S\xa0\xd8\xf9\x95 \xda\x0ep \xda" + + "\xd9w \xdb\xe5\x17\xa0ܹY \xdd\xce4 ޢu\xa0߮\x16 \xe0\x82W\xa0\xe1\x8d\xf8 \xe2b9\xa0\xe3m\xda \xe4B\x1b\xa0\xe5M\xbc \xe6!\xfd\xa0\xe76ؠ\xe8\v\x1a \xe9" + + "\x16\xba\xa0\xe9\xea\xfc \xea\xf6\x9c\xa0\xeb\xca\xde \xec\xd6~\xa0\xed\xaa\xc0 \xee\xb6`\xa0\uf2a2 \xf0\x96B\xa0\xf1j\x84 \xf2\u007f_ \xf3S\xa0\xa0\xf4_A \xf53\x82\xa0\xf6?# \xf7" + + "\x13d\xa0\xf8\x1f\x05 \xf8\xf3F\xa0\xf9\xfe\xe7 \xfa\xd3(\xa0\xfb\xe8\x03\xa0\xfc\xbcE \x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\xff\xff\xeb`\x00\x00\x00\x00\x00\x00\x01\x04\xff\xff\xf1\xf0\x00\b\xff\xff\xf1\xf0\x00\b\x00" + + "\x00\x00\x00\x01\x04\x00\x00\x00\x00\x00\fLMT\x00+00\x00-01\x00GMT\x00\x00\x00\x00\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x06\x00\x00\x00\x00\x00\x00\x00D\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\x8b`\x83\xa0\xff\xff\xff\xff\x9c\x91\x1e\x00\xff\xff\xff\xff\x9dш\x90\xff\xff\xff\xff\x9erQ\x80\xff\xff\xff\xff\x9f\xd5\x03\x10\xff\xff\xff" + + "\xff\xa0S\x85\x00\xff\xff\xff\xff\xa1\xb66\x90\xff\xff\xff\xff\xa4<'\x80\xff\xff\xff\xff\xa4\xb9t\x10\xff\xff\xff\xff\xc6M\x1a\x00\xff\xff\xff\xff\xc7=' \xff\xff\xff\xff\xc7\xda\x17\xb0\xff\xff\xff\xff\xc9&C" + + "\xa0\xff\xff\xff\xff\xc9\xc3& \xff\xff\xff\xff\xcb\x06%\xa0\xff\xff\xff\xffˬB\xa0\xff\xff\xff\xff\xcc\xdc\xcd \xff\xff\xff\xff͌$\xa0\xff\xff\xff\xffμ\xaf \xff\xff\xff\xff\xcfl\x06\xa0\xff\xff\xff" + + "\xffМ\x91 \xff\xff\xff\xff\xd1K\xe8\xa0\xff\xff\xff\xff҅\xad\xa0\xff\xff\xff\xff\xd3+ʠ\xff\xff\xff\xff\xd4e\x8f\xa0\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd6Eq\xa0\xff\xff\xff\xff\xd7\x19\xb3" + + " \xff\xff\xff\xff\xd8%S\xa0\xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xd9w \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xce4 \xff\xff\xff" + + "\xffޢu\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x82W\xa0\xff\xff\xff\xff\xe1\x8d\xf8 \xff\xff\xff\xff\xe2b9\xa0\xff\xff\xff\xff\xe3m\xda \xff\xff\xff\xff\xe4B\x1b\xa0\xff\xff\xff\xff\xe5M\xbc" + + " \xff\xff\xff\xff\xe6!\xfd\xa0\xff\xff\xff\xff\xe76ؠ\xff\xff\xff\xff\xe8\v\x1a \xff\xff\xff\xff\xe9\x16\xba\xa0\xff\xff\xff\xff\xe9\xea\xfc \xff\xff\xff\xff\xea\xf6\x9c\xa0\xff\xff\xff\xff\xeb\xca\xde \xff\xff\xff" + + "\xff\xec\xd6~\xa0\xff\xff\xff\xff\xed\xaa\xc0 \xff\xff\xff\xff\xee\xb6`\xa0\xff\xff\xff\xff\uf2a2 \xff\xff\xff\xff\xf0\x96B\xa0\xff\xff\xff\xff\xf1j\x84 \xff\xff\xff\xff\xf2\u007f_ \xff\xff\xff\xff\xf3S\xa0" + + "\xa0\xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf53\x82\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x13d\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xf3F\xa0\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff" + + "\xff\xfa\xd3(\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc\xbcE \x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\xff\xff\xeb`\x00\x00\x00\x00\x00\x00\x01\x04\xff\xff\xf1\xf0\x00\b\xff\xff\xf1\xf0\x00\b\x00\x00\x00\x00\x01\x04\x00" + + "\x00\x00\x00\x00\fLMT\x00+00\x00-01\x00GMT\x00\x00\x00\x00\x01\x01\x01\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPNs\x84\xac\x0e\x01\x00\x00\x0e\x01\x00\x00\x13" + + "\x00\x1c\x00Atlantic/Cape_VerdeUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\f\x92檠̕\x9c \xd2t|\x10\v\x17\xf7@\u007f\xff\xff\xff\x01\x02\x03\x04\x04\xff" + + "\xff\xe9\xf4\x00\x00\xff\xff\xe3\xe0\x00\x04\xff\xff\xf1\xf0\x01\b\xff\xff\xe3\xe0\x00\x04\xff\xff\xf1\xf0\x00\bLMT\x00-02\x00-01\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x00TZif2\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\f\xff\xff\xff\xff\x92檠\xff\xff\xff\xff̕\x9c \xff\xff\xff\xff\xd2t|\x10\x00" + + "\x00\x00\x00\v\x17\xf7@\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x04\x04\xff\xff\xe9\xf4\x00\x00\xff\xff\xe3\xe0\x00\x04\xff\xff\xf1\xf0\x01\b\xff\xff\xe3\xe0\x00\x04\xff\xff\xf1\xf0\x00\bLMT\x00-02\x00-0" + + "1\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x00\n<-01>1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x1e\x92\x85ޜ\r\x00\x00\x9c\r\x00\x00\x0f\x00\x1c\x00Atlantic/A" + + "zoresUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00" + + "\r\x00\x00\x00\x00\x00\x00\x00\xde\x00\x00\x00\r\x00\x00\x00\x18\x80\x00\x00\x00\x92檠\x9bK\x89\x90\x9b\xfe㠜\x9d\t\x90\x9dɟ\x90\x9e\u007f\x8e\x90\x9f\xaa\xd3\x10\xa0_p\x90\xa1\x8c\x06\x90\xa2A\xf5" + + "\x90\xa3n\x8b\x90\xa4#)\x10\xa5O\xbf\x10\xaa\x06\v\x90\xaa\xf4\xab\x10\xad\xc9\xc4\x10\xae\xa7@\x10\xaf\xa0k\x90\xb0\x87\"\x10\xb1\x89\x88\x10\xb2p>\x90\xb3r\xa4\x90\xb4P \x90\xb72h\x90\xb8\x0f\xe4" + + "\x90\xb8\xffՐ\xb9\xefƐ\xbc\xc8\xd4\x10\xbd\xb8\xc5\x10\xbe\x9f{\x90\xbf\x98\xa7\x10\xc0\x9b\r\x10\xc1x\x89\x10\xc2hz\x10\xc3Xk\x10\xc4?!\x90\xc58M\x10\xc6:\xb3\x10\xc7XȐ\xc7\xd9\xfb" + + "\x90\xc9\x01K\x90\xc9\xf1<\x90\xca\xe2\u007f\x10˵o\x10\xcb\xec\xc0\x00̀h\x00\xccܿ\x10͕Q\x10\xcd\xc3g\x80\xcer\xbf\x00\xce\xc5ې\xcfu3\x10Ϭ\x84\x00\xd0R\xa1\x00Х\xbd" + + "\x90\xd1U\x15\x10ьf\x00\xd22\x83\x00҅\x9f\x90\xd3Y\xe1\x10\xd4I\xd2\x10\xd59\xed@\xd6)\xde@\xd7\x19\xcf@\xd8\t\xc0@\xd8\xf9\xb1@\xd9\xe9\xa2@ܹu@ݲ\xa0\xc0ޢ\x91" + + "\xc0ߒ\x82\xc0\xe0\x82s\xc0\xe1rd\xc0\xe2bU\xc0\xe3RF\xc0\xe4B7\xc0\xe52(\xc0\xe6\"\x19\xc0\xe7\x1bE@\xe8\v6@\xe8\xfb'@\xe9\xeb\x18@\xea\xdb\t@\xeb\xca\xfa@\xec\xba\xeb" + + "@\xed\xaa\xdc@\xee\x9a\xcd@\uf2be@\xf0z\xaf@\xf1j\xa0@\xf2c\xcb\xc0\xf3S\xbc\xc0\xf4C\xad\xc0\xf53\x9e\xc0\xf6#\x8f\xc0\xf7\x13\x80\xc0\xf8\x03q\xc0\xf8\xf3b\xc0\r\x9b)\x10\x0e\x8b\x1a" + + "\x10\x0f\x84E\x90\x10t6\x90\x11d'\x90\x12T&\xa0\x13D\t\x90\x144\b\xa0\x15#\xf9\xa0\x16\x13\xea\xa0\x17\x03۠\x17\xf3̠\x18\xe3˰\x19Ӯ\xa0\x1aß\xa0\x1b\xbc\xcb \x1c\xac\xbc" + + " \x1d\x9c\xad \x1e\x8c\x9e \x1f|\x8f l\x80 !\\q \"Lb #\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf" + + "\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N" + + "\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]\xcc" + + "\x90d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<" + + "\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f" + + "\x90\u007f\xff\xff\xff\x01\x06\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\a\x04\x05\x04\a\x04\x05\x04\a\x04" + + "\x05\x04\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\t\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b" + + "\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\n\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f" + + "\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\f\xff\xff\xe7\xf0\x00\x00\xff\xff\xe5(\x00\x04\xff" + + "\xff\xf1\xf0\x01\b\xff\xff\xe3\xe0\x00\f\xff\xff\xf1\xf0\x01\b\xff\xff\xe3\xe0\x00\f\xff\xff\xe3\xe0\x00\f\x00\x00\x00\x00\x01\x10\xff\xff\xf1\xf0\x00\b\xff\xff\xf1\xf0\x00\b\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x01\x10\xff" + + "\xff\xf1\xf0\x00\bLMT\x00HMT\x00-01\x00-02\x00+00\x00WET\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x01TZif2" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\xde\x00\x00\x00\r\x00\x00\x00\x18\xff\xff\xff\xff^=\x1b\x90\xff\xff\xff\xff\x92檠\xff\xff\xff\xff\x9b" + + "K\x89\x90\xff\xff\xff\xff\x9b\xfe\xe3\xa0\xff\xff\xff\xff\x9c\x9d\t\x90\xff\xff\xff\xff\x9dɟ\x90\xff\xff\xff\xff\x9e\u007f\x8e\x90\xff\xff\xff\xff\x9f\xaa\xd3\x10\xff\xff\xff\xff\xa0_p\x90\xff\xff\xff\xff\xa1\x8c\x06\x90\xff" + + "\xff\xff\xff\xa2A\xf5\x90\xff\xff\xff\xff\xa3n\x8b\x90\xff\xff\xff\xff\xa4#)\x10\xff\xff\xff\xff\xa5O\xbf\x10\xff\xff\xff\xff\xaa\x06\v\x90\xff\xff\xff\xff\xaa\xf4\xab\x10\xff\xff\xff\xff\xad\xc9\xc4\x10\xff\xff\xff\xff\xae" + + "\xa7@\x10\xff\xff\xff\xff\xaf\xa0k\x90\xff\xff\xff\xff\xb0\x87\"\x10\xff\xff\xff\xff\xb1\x89\x88\x10\xff\xff\xff\xff\xb2p>\x90\xff\xff\xff\xff\xb3r\xa4\x90\xff\xff\xff\xff\xb4P \x90\xff\xff\xff\xff\xb72h\x90\xff" + + "\xff\xff\xff\xb8\x0f\xe4\x90\xff\xff\xff\xff\xb8\xffՐ\xff\xff\xff\xff\xb9\xefƐ\xff\xff\xff\xff\xbc\xc8\xd4\x10\xff\xff\xff\xff\xbd\xb8\xc5\x10\xff\xff\xff\xff\xbe\x9f{\x90\xff\xff\xff\xff\xbf\x98\xa7\x10\xff\xff\xff\xff\xc0" + + "\x9b\r\x10\xff\xff\xff\xff\xc1x\x89\x10\xff\xff\xff\xff\xc2hz\x10\xff\xff\xff\xff\xc3Xk\x10\xff\xff\xff\xff\xc4?!\x90\xff\xff\xff\xff\xc58M\x10\xff\xff\xff\xff\xc6:\xb3\x10\xff\xff\xff\xff\xc7XȐ\xff" + + "\xff\xff\xff\xc7\xd9\xfb\x90\xff\xff\xff\xff\xc9\x01K\x90\xff\xff\xff\xff\xc9\xf1<\x90\xff\xff\xff\xff\xca\xe2\u007f\x10\xff\xff\xff\xff˵o\x10\xff\xff\xff\xff\xcb\xec\xc0\x00\xff\xff\xff\xff̀h\x00\xff\xff\xff\xff\xcc" + + "ܿ\x10\xff\xff\xff\xff͕Q\x10\xff\xff\xff\xff\xcd\xc3g\x80\xff\xff\xff\xff\xcer\xbf\x00\xff\xff\xff\xff\xce\xc5ې\xff\xff\xff\xff\xcfu3\x10\xff\xff\xff\xffϬ\x84\x00\xff\xff\xff\xff\xd0R\xa1\x00\xff" + + "\xff\xff\xffХ\xbd\x90\xff\xff\xff\xff\xd1U\x15\x10\xff\xff\xff\xffьf\x00\xff\xff\xff\xff\xd22\x83\x00\xff\xff\xff\xff҅\x9f\x90\xff\xff\xff\xff\xd3Y\xe1\x10\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd5" + + "9\xed@\xff\xff\xff\xff\xd6)\xde@\xff\xff\xff\xff\xd7\x19\xcf@\xff\xff\xff\xff\xd8\t\xc0@\xff\xff\xff\xff\xd8\xf9\xb1@\xff\xff\xff\xff\xd9\xe9\xa2@\xff\xff\xff\xffܹu@\xff\xff\xff\xffݲ\xa0\xc0\xff" + + "\xff\xff\xffޢ\x91\xc0\xff\xff\xff\xffߒ\x82\xc0\xff\xff\xff\xff\xe0\x82s\xc0\xff\xff\xff\xff\xe1rd\xc0\xff\xff\xff\xff\xe2bU\xc0\xff\xff\xff\xff\xe3RF\xc0\xff\xff\xff\xff\xe4B7\xc0\xff\xff\xff\xff\xe5" + + "2(\xc0\xff\xff\xff\xff\xe6\"\x19\xc0\xff\xff\xff\xff\xe7\x1bE@\xff\xff\xff\xff\xe8\v6@\xff\xff\xff\xff\xe8\xfb'@\xff\xff\xff\xff\xe9\xeb\x18@\xff\xff\xff\xff\xea\xdb\t@\xff\xff\xff\xff\xeb\xca\xfa@\xff" + + "\xff\xff\xff\xec\xba\xeb@\xff\xff\xff\xff\xed\xaa\xdc@\xff\xff\xff\xff\xee\x9a\xcd@\xff\xff\xff\xff\uf2be@\xff\xff\xff\xff\xf0z\xaf@\xff\xff\xff\xff\xf1j\xa0@\xff\xff\xff\xff\xf2c\xcb\xc0\xff\xff\xff\xff\xf3" + + "S\xbc\xc0\xff\xff\xff\xff\xf4C\xad\xc0\xff\xff\xff\xff\xf53\x9e\xc0\xff\xff\xff\xff\xf6#\x8f\xc0\xff\xff\xff\xff\xf7\x13\x80\xc0\xff\xff\xff\xff\xf8\x03q\xc0\xff\xff\xff\xff\xf8\xf3b\xc0\x00\x00\x00\x00\r\x9b)\x10\x00" + + "\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T&\xa0\x00\x00\x00\x00\x13D\t\x90\x00\x00\x00\x00\x144\b\xa0\x00\x00\x00\x00\x15" + + "#\xf9\xa0\x00\x00\x00\x00\x16\x13\xea\xa0\x00\x00\x00\x00\x17\x03۠\x00\x00\x00\x00\x17\xf3̠\x00\x00\x00\x00\x18\xe3˰\x00\x00\x00\x00\x19Ӯ\xa0\x00\x00\x00\x00\x1aß\xa0\x00\x00\x00\x00\x1b\xbc\xcb \x00" + + "\x00\x00\x00\x1c\xac\xbc \x00\x00\x00\x00\x1d\x9c\xad \x00\x00\x00\x00\x1e\x8c\x9e \x00\x00\x00\x00\x1f|\x8f \x00\x00\x00\x00 l\x80 \x00\x00\x00\x00!\\q \x00\x00\x00\x00\"Lb \x00\x00\x00\x00#" + + "\x86A\x90\x00\x00\x00\x00?" + + "\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00" + + "\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M" + + "\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00" + + "\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[" + + "\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00" + + "\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i" + + "\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00" + + "\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x" + + "\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00" + + "\x00\x00\x00\u007f\x8e\u007f\x90\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x06\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\a\x04\x05\x04\a\x04\x05\x04\a\x04\x05\x04\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\t\a\b\a\b\a\b" + + "\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\n\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f" + + "\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\f\xff\xff\xe7" + + "\xf0\x00\x00\xff\xff\xe5(\x00\x04\xff\xff\xf1\xf0\x01\b\xff\xff\xe3\xe0\x00\f\xff\xff\xf1\xf0\x01\b\xff\xff\xe3\xe0\x00\f\xff\xff\xe3\xe0\x00\f\x00\x00\x00\x00\x01\x10\xff\xff\xf1\xf0\x00\b\xff\xff\xf1\xf0\x00\b\x00\x00\x00" + + "\x00\x00\x14\x00\x00\x00\x00\x01\x10\xff\xff\xf1\xf0\x00\bLMT\x00HMT\x00-01\x00-02\x00+00\x00WET\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x01\x00" + + "\x00\x00\x00\x01\x01\n<-01>1<+00>,M3.5.0/0,M10.5.0/1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPG\xd5'\xe1\x93\r\x00\x00\x93" + + "\r\x00\x00\x10\x00\x1c\x00Atlantic/MadeiraUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\xdd\x00\x00\x00\r\x00\x00\x00\x1d\x80\x00\x00\x00\x92朐\x9bK{\x80\x9b\xfeՐ\x9c\x9c\xfb\x80\x9dɑ\x80\x9e" + + "\u007f\x80\x80\x9f\xaa\xc5\x00\xa0_b\x80\xa1\x8b\xf8\x80\xa2A瀣n}\x80\xa4#\x1b\x00\xa5O\xb1\x00\xaa\x05\xfd\x80\xaa\xf4\x9d\x00\xadɶ\x00\xae\xa72\x00\xaf\xa0]\x80\xb0\x87\x14\x00\xb1\x89z\x00\xb2" + + "p0\x80\xb3r\x96\x80\xb4P\x12\x80\xb72Z\x80\xb8\x0fր\xb8\xffǀ\xb9︀\xbc\xc8\xc6\x00\xbd\xb8\xb7\x00\xbe\x9fm\x80\xbf\x98\x99\x00\xc0\x9a\xff\x00\xc1x{\x00\xc2hl\x00\xc3X]\x00\xc4" + + "?\x13\x80\xc58?\x00\xc6:\xa5\x00\xc7X\xba\x80\xc7\xd9\xed\x80\xc9\x01=\x80\xc9\xf1.\x80\xca\xe2q\x00˵a\x00\xcb\xec\xb1\xf0̀Y\xf0\xccܱ\x00͕C\x00\xcd\xc3Yp\xcer\xb0\xf0\xce" + + "\xc5̀\xcfu%\x00Ϭu\xf0\xd0R\x92\xf0Х\xaf\x80\xd1U\a\x00ьW\xf0\xd22t\xf0҅\x91\x80\xd3Y\xd3\x00\xd4I\xc4\x00\xd59\xdf0\xd6)\xd00\xd7\x19\xc10\xd8\t\xb20\xd8" + + "\xf9\xa30\xd9\xe9\x940ܹg0ݲ\x92\xb0ޢ\x83\xb0ߒt\xb0\xe0\x82e\xb0\xe1rV\xb0\xe2bG\xb0\xe3R8\xb0\xe4B)\xb0\xe52\x1a\xb0\xe6\"\v\xb0\xe7\x1b70\xe8\v(0\xe8" + + "\xfb\x190\xe9\xeb\n0\xea\xda\xfb0\xeb\xca\xec0\xec\xba\xdd0\xed\xaa\xce0\ue6bf0\uf2b00\xf0z\xa10\xf1j\x920\xf2c\xbd\xb0\xf3S\xae\xb0\xf4C\x9f\xb0\xf53\x90\xb0\xf6#\x81\xb0\xf7" + + "\x13r\xb0\xf8\x03c\xb0\xf8\xf3T\xb0\r\x9b\x1b\x00\x0e\x8b\f\x00\x0f\x847\x80\x10t(\x80\x11d\x19\x80\x12T\x18\x90\x13C\xfb\x80\x143\xfa\x90\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18" + + "㽠\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90C" + + "d\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90Q" + + "W\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_" + + "\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m" + + "\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{" + + "λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x06\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\a\x04\x05\x04\a\x04\x05\x04\a\x04\x05\x04\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\n\b\t" + + "\b\t\b\t\b\t\b\t\b\t\b\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v" + + "\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v" + + "\xff\xff\xf0(\x00\x00\xff\xff\xf0(\x00\x04\x00\x00\x00\x00\x01\b\xff\xff\xf1\xf0\x00\f\x00\x00\x00\x00\x01\b\xff\xff\xf1\xf0\x00\f\xff\xff\xf1\xf0\x00\f\x00\x00\x0e\x10\x01\x10\x00\x00\x0e\x10\x01\x14\x00\x00\x00\x00\x00\x19" + + "\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00\x19\x00\x00\x0e\x10\x01\x14LMT\x00FMT\x00+00\x00-01\x00+01\x00WEST\x00WET\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x00\x01\x01" + + "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\xdd\x00\x00\x00\r\x00\x00\x00\x1d\xff\xff\xff" + + "\xff^=\x13X\xff\xff\xff\xff\x92朐\xff\xff\xff\xff\x9bK{\x80\xff\xff\xff\xff\x9b\xfeՐ\xff\xff\xff\xff\x9c\x9c\xfb\x80\xff\xff\xff\xff\x9dɑ\x80\xff\xff\xff\xff\x9e\u007f\x80\x80\xff\xff\xff\xff\x9f\xaa\xc5" + + "\x00\xff\xff\xff\xff\xa0_b\x80\xff\xff\xff\xff\xa1\x8b\xf8\x80\xff\xff\xff\xff\xa2A\xe7\x80\xff\xff\xff\xff\xa3n}\x80\xff\xff\xff\xff\xa4#\x1b\x00\xff\xff\xff\xff\xa5O\xb1\x00\xff\xff\xff\xff\xaa\x05\xfd\x80\xff\xff\xff" + + "\xff\xaa\xf4\x9d\x00\xff\xff\xff\xff\xadɶ\x00\xff\xff\xff\xff\xae\xa72\x00\xff\xff\xff\xff\xaf\xa0]\x80\xff\xff\xff\xff\xb0\x87\x14\x00\xff\xff\xff\xff\xb1\x89z\x00\xff\xff\xff\xff\xb2p0\x80\xff\xff\xff\xff\xb3r\x96" + + "\x80\xff\xff\xff\xff\xb4P\x12\x80\xff\xff\xff\xff\xb72Z\x80\xff\xff\xff\xff\xb8\x0fր\xff\xff\xff\xff\xb8\xffǀ\xff\xff\xff\xff\xb9︀\xff\xff\xff\xff\xbc\xc8\xc6\x00\xff\xff\xff\xff\xbd\xb8\xb7\x00\xff\xff\xff" + + "\xff\xbe\x9fm\x80\xff\xff\xff\xff\xbf\x98\x99\x00\xff\xff\xff\xff\xc0\x9a\xff\x00\xff\xff\xff\xff\xc1x{\x00\xff\xff\xff\xff\xc2hl\x00\xff\xff\xff\xff\xc3X]\x00\xff\xff\xff\xff\xc4?\x13\x80\xff\xff\xff\xff\xc58?" + + "\x00\xff\xff\xff\xff\xc6:\xa5\x00\xff\xff\xff\xff\xc7X\xba\x80\xff\xff\xff\xff\xc7\xd9\xed\x80\xff\xff\xff\xff\xc9\x01=\x80\xff\xff\xff\xff\xc9\xf1.\x80\xff\xff\xff\xff\xca\xe2q\x00\xff\xff\xff\xff˵a\x00\xff\xff\xff" + + "\xff\xcb\xec\xb1\xf0\xff\xff\xff\xff̀Y\xf0\xff\xff\xff\xff\xccܱ\x00\xff\xff\xff\xff͕C\x00\xff\xff\xff\xff\xcd\xc3Yp\xff\xff\xff\xff\xcer\xb0\xf0\xff\xff\xff\xff\xce\xc5̀\xff\xff\xff\xff\xcfu%" + + "\x00\xff\xff\xff\xffϬu\xf0\xff\xff\xff\xff\xd0R\x92\xf0\xff\xff\xff\xffХ\xaf\x80\xff\xff\xff\xff\xd1U\a\x00\xff\xff\xff\xffьW\xf0\xff\xff\xff\xff\xd22t\xf0\xff\xff\xff\xff҅\x91\x80\xff\xff\xff" + + "\xff\xd3Y\xd3\x00\xff\xff\xff\xff\xd4I\xc4\x00\xff\xff\xff\xff\xd59\xdf0\xff\xff\xff\xff\xd6)\xd00\xff\xff\xff\xff\xd7\x19\xc10\xff\xff\xff\xff\xd8\t\xb20\xff\xff\xff\xff\xd8\xf9\xa30\xff\xff\xff\xff\xd9\xe9\x94" + + "0\xff\xff\xff\xffܹg0\xff\xff\xff\xffݲ\x92\xb0\xff\xff\xff\xffޢ\x83\xb0\xff\xff\xff\xffߒt\xb0\xff\xff\xff\xff\xe0\x82e\xb0\xff\xff\xff\xff\xe1rV\xb0\xff\xff\xff\xff\xe2bG\xb0\xff\xff\xff" + + "\xff\xe3R8\xb0\xff\xff\xff\xff\xe4B)\xb0\xff\xff\xff\xff\xe52\x1a\xb0\xff\xff\xff\xff\xe6\"\v\xb0\xff\xff\xff\xff\xe7\x1b70\xff\xff\xff\xff\xe8\v(0\xff\xff\xff\xff\xe8\xfb\x190\xff\xff\xff\xff\xe9\xeb\n" + + "0\xff\xff\xff\xff\xea\xda\xfb0\xff\xff\xff\xff\xeb\xca\xec0\xff\xff\xff\xff\xec\xba\xdd0\xff\xff\xff\xff\xed\xaa\xce0\xff\xff\xff\xff\ue6bf0\xff\xff\xff\xff\uf2b00\xff\xff\xff\xff\xf0z\xa10\xff\xff\xff" + + "\xff\xf1j\x920\xff\xff\xff\xff\xf2c\xbd\xb0\xff\xff\xff\xff\xf3S\xae\xb0\xff\xff\xff\xff\xf4C\x9f\xb0\xff\xff\xff\xff\xf53\x90\xb0\xff\xff\xff\xff\xf6#\x81\xb0\xff\xff\xff\xff\xf7\x13r\xb0\xff\xff\xff\xff\xf8\x03c" + + "\xb0\xff\xff\xff\xff\xf8\xf3T\xb0\x00\x00\x00\x00\r\x9b\x1b\x00\x00\x00\x00\x00\x0e\x8b\f\x00\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11d\x19\x80\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00" + + "\x00\x13C\xfb\x80\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㽠\x00\x00\x00\x00\x19Ӡ" + + "\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00" + + "\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7" + + "\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00" + + "\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle" + + "\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00" + + "\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5" + + "\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00" + + "\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S" + + "\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00" + + "\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\xc2" + + "\x90\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x06\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\a\x04\x05\x04\a\x04\x05\x04\a\x04\x05\x04\a\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\n\b\t\b\t\b\t\b\t\b\t\b\t\b\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v" + + "\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v" + + "\f\v\f\v\f\v\xff\xff\xf0(\x00\x00\xff\xff\xf0(\x00\x04\x00\x00\x00\x00\x01\b\xff\xff\xf1\xf0\x00\f\x00\x00\x00\x00\x01\b\xff\xff\xf1\xf0\x00\f\xff\xff\xf1\xf0\x00\f\x00\x00\x0e\x10\x01\x10\x00\x00\x0e\x10\x01\x14" + + "\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00\x19\x00\x00\x0e\x10\x01\x14LMT\x00FMT\x00+00\x00-01\x00+01\x00WEST\x00WET\x00\x00\x00\x00\x00\x01\x01\x01" + + "\x01\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x01\nWET0WEST,M3.5.0/1,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x1c\x00Australia/UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x03\x04\n\x00" + + "\x00\x00\x00\x00\xf5F\x9cP\xbeY\xcc?\x9c\b\x00\x00\x9c\b\x00\x00\x13\x00\x1c\x00Australia/MelbourneUT\t\x00\x03nӧ^nӧ^ux\v\x00" + + "\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x8e\x00\x00\x00\x05\x00\x00\x00\x0e\x80\x00\x00\x00\x9c" + + "N\xa6\x9c\x9c\xbc \xf0\xcbT\xb3\x00\xcb\xc7Wp̷V\x80ͧ9pΠs\x00χ\x1bp\x03p9\x80\x04\r\x1c\x00\x05P\x1b\x80\x05\xf68\x80\a/\xfd\x80\a\xd6\x1a\x80\t\x0f߀\t" + + "\xb5\xfc\x80\n\xef\xc1\x80\v\x9f\x19\x00\f\xd8\xde\x00\r~\xfb\x00\x0e\xb8\xc0\x00\x0f^\xdd\x00\x10\x98\xa2\x00\x11>\xbf\x00\x12x\x84\x00\x13\x1e\xa1\x00\x14Xf\x00\x14\xfe\x83\x00\x168H\x00\x16矀\x18" + + "!d\x80\x18ǁ\x80\x1a\x01F\x80\x1a\xa7c\x80\x1b\xe1(\x80\x1c\x87E\x80\x1d\xc1\n\x80\x1ey\x9c\x80\x1f\x97\xb2\x00 Y~\x80!w\x94\x00\"B\x9b\x00#i\xeb\x00$\"}\x00%I\xcd\x00&" + + "\x02_\x00')\xaf\x00'\xcf\xcc\x00)\t\x91\x00)\xaf\xae\x00*\xe9s\x00+\x98ʀ,ҏ\x80-x\xac\x80.\xb2q\x80/t>\x000\x92S\x801]Z\x802r5\x803=<\x804" + + "R\x17\x805\x1d\x1e\x8061\xf9\x806\xfd\x00\x808\x1b\x16\x008\xdc\xe2\x809\xa7\xe9\x80:\xbcĀ;\xda\xda\x00<\xa5\xe1\x00=\xba\xbc\x00>\x85\xc3\x00?\x9a\x9e\x00@e\xa5\x00A\x83\xba\x80B" + + "E\x87\x00Cc\x9c\x80D.\xa3\x80EC~\x80F\x05K\x00G#`\x80G\xf7\xa2\x00H\xe7\x93\x00Iׄ\x00J\xc7u\x00K\xb7f\x00L\xa7W\x00M\x97H\x00N\x879\x00Ow*\x00P" + + "pU\x80Q`F\x80RP7\x80S@(\x80T0\x19\x80U \n\x80V\x0f\xfb\x80V\xff\xec\x80W\xef݀X\xdf\u0380YϿ\x80Z\xbf\xb0\x80[\xb8\xdc\x00\\\xa8\xcd\x00]\x98\xbe\x00^" + + "\x88\xaf\x00_x\xa0\x00`h\x91\x00aX\x82\x00bHs\x00c8d\x00d(U\x00e\x18F\x00f\x11q\x80g\x01b\x80g\xf1S\x80h\xe1D\x80i\xd15\x80j\xc1&\x80k\xb1\x17\x80l" + + "\xa1\b\x80m\x90\xf9\x80n\x80\xea\x80opۀpj\a\x00qY\xf8\x00rI\xe9\x00s9\xda\x00t)\xcb\x00u\x19\xbc\x00v\t\xad\x00v\xf9\x9e\x00w\xe9\x8f\x00xـ\x00y\xc9q\x00z" + + "\xb9b\x00{\xb2\x8d\x80|\xa2~\x80}\x92o\x80~\x82`\x80\u007frQ\x80\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x87\xe8\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c" + + "\xa0\x00\t\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x05\x00\x00\x00\x00\x00\x00\x00\x8e\x00\x00\x00\x05\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x85\x18\xff\xff\xff\xff\x9cN\xa6\x9c\xff\xff\xff\xff\x9c\xbc \xf0\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7Wp\xff\xff" + + "\xff\xff̷V\x80\xff\xff\xff\xffͧ9p\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ\x1bp\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf6" + + "8\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00" + + "\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14X" + + "f\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x16矀\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18ǁ\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00" + + "\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!w\x94\x00\x00\x00\x00\x00\"B" + + "\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00" + + "\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00\x00\x00,ҏ\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000\x92" + + "S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00" + + "\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85" + + "\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC~\x80\x00\x00" + + "\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\x00\x00\x00\x00H\xe7\x93\x00\x00\x00\x00\x00Iׄ\x00\x00\x00\x00\x00J\xc7u\x00\x00\x00\x00\x00K\xb7f\x00\x00\x00\x00\x00L\xa7" + + "W\x00\x00\x00\x00\x00M\x97H\x00\x00\x00\x00\x00N\x879\x00\x00\x00\x00\x00Ow*\x00\x00\x00\x00\x00PpU\x80\x00\x00\x00\x00Q`F\x80\x00\x00\x00\x00RP7\x80\x00\x00\x00\x00S@(\x80\x00\x00" + + "\x00\x00T0\x19\x80\x00\x00\x00\x00U \n\x80\x00\x00\x00\x00V\x0f\xfb\x80\x00\x00\x00\x00V\xff\xec\x80\x00\x00\x00\x00W\xef݀\x00\x00\x00\x00X\xdf\u0380\x00\x00\x00\x00YϿ\x80\x00\x00\x00\x00Z\xbf" + + "\xb0\x80\x00\x00\x00\x00[\xb8\xdc\x00\x00\x00\x00\x00\\\xa8\xcd\x00\x00\x00\x00\x00]\x98\xbe\x00\x00\x00\x00\x00^\x88\xaf\x00\x00\x00\x00\x00_x\xa0\x00\x00\x00\x00\x00`h\x91\x00\x00\x00\x00\x00aX\x82\x00\x00\x00" + + "\x00\x00bHs\x00\x00\x00\x00\x00c8d\x00\x00\x00\x00\x00d(U\x00\x00\x00\x00\x00e\x18F\x00\x00\x00\x00\x00f\x11q\x80\x00\x00\x00\x00g\x01b\x80\x00\x00\x00\x00g\xf1S\x80\x00\x00\x00\x00h\xe1" + + "D\x80\x00\x00\x00\x00i\xd15\x80\x00\x00\x00\x00j\xc1&\x80\x00\x00\x00\x00k\xb1\x17\x80\x00\x00\x00\x00l\xa1\b\x80\x00\x00\x00\x00m\x90\xf9\x80\x00\x00\x00\x00n\x80\xea\x80\x00\x00\x00\x00opۀ\x00\x00" + + "\x00\x00pj\a\x00\x00\x00\x00\x00qY\xf8\x00\x00\x00\x00\x00rI\xe9\x00\x00\x00\x00\x00s9\xda\x00\x00\x00\x00\x00t)\xcb\x00\x00\x00\x00\x00u\x19\xbc\x00\x00\x00\x00\x00v\t\xad\x00\x00\x00\x00\x00v\xf9" + + "\x9e\x00\x00\x00\x00\x00w\xe9\x8f\x00\x00\x00\x00\x00xـ\x00\x00\x00\x00\x00y\xc9q\x00\x00\x00\x00\x00z\xb9b\x00\x00\x00\x00\x00{\xb2\x8d\x80\x00\x00\x00\x00|\xa2~\x80\x00\x00\x00\x00}\x92o\x80\x00\x00" + + "\x00\x00~\x82`\x80\x00\x00\x00\x00\u007frQ\x80\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x87\xe8\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\t\x00\x00\x9a\xb0\x01\x04" + + "\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\x00\x00\x00\x01\x01\nAEST-10AEDT,M10.1.0,M4.1.0/3\nPK\x03\x04\n" + + "\x00\x00\x00\x00\x00\xf5F\x9cPW\xd6\xfd\x19\xb1\x01\x00\x00\xb1\x01\x00\x00\x14\x00\x1c\x00Australia/QueenslandUT\t\x00\x03nӧ^nӧ^ux" + + "\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x05\x00\x00\x00\x0e\x80\x00\x00" + + "\x00\x9cN\xa6\x9c\x9c\xbc \xf0\xcbT\xb3\x00\xcb\xc7Wp̷V\x80ͧ9pΠs\x00χ\x1bp\x03p9\x80\x04\r\x1c\x00%I\xcd\x00%\xef\xea\x00')\xaf\x00'\xcf\xcc\x00)\t\x91" + + "\x00)\xaf\xae\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x8fx\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\t\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT" + + "\x00AEST\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x05\x00\x00\x00\x0e\xff\xff\xff\xffr" + + "\xed\x9f\b\xff\xff\xff\xff\x9cN\xa6\x9c\xff\xff\xff\xff\x9c\xbc \xf0\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7Wp\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧ9p\xff\xff\xff\xffΠs\x00\xff" + + "\xff\xff\xffχ\x1bp\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)" + + "\t\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x8fx\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\t\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLM" + + "T\x00AEDT\x00AEST\x00\x00\x00\x00\x01\x01\nAEST-10\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP(\xd2\xc7k0\x01\x00\x000\x01\x00\x00\x0f\x00\x1c\x00Aust" + + "ralia/NorthUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x03\x00\x00\x00\x0e\x80\x00\x00\x00\x9cN\xad\xa4\x9c\xbc'\xf8\xcbT\xba\b\xcb\xc7^x̷]\x88ͧ@xΠz\bχ\"x\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00z\xa8\x00\x00\x00\x00\x93\xa8\x01\x04\x00\x00\x85\x98\x00\tLMT\x00ACDT\x00ACST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x04\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x92X\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cN\xad\xa4\xff\xff\xff\xff\x9c\xbc'\xf8\xff\xff\xff\xff" + + "\xcbT\xba\b\xff\xff\xff\xff\xcb\xc7^x\xff\xff\xff\xff̷]\x88\xff\xff\xff\xffͧ@x\xff\xff\xff\xffΠz\b\xff\xff\xff\xffχ\"x\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00z\xa8\x00\x00" + + "\x00\x00~\x90\x00\x04\x00\x00\x93\xa8\x01\t\x00\x00\x85\x98\x00\x04LMT\x00ACST\x00ACDT\x00\nACST-9:30\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP!v\xa5" + + "*D\a\x00\x00D\a\x00\x00\x13\x00\x1c\x00Australia/Lord_HoweUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00" + + "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\x00\x00\x00\x05\x00\x00\x00\x19\x80\x00\x00\x00\x14\xfef\xe0\x168@\xf8\x16\xe7\x8ah" + + "\x18!]x\x18\xc7lh\x1a\x01?x\x1a\xa7Nh\x1b\xe1!x\x1c\x870h\x1d\xc1\x03x\x1ey\x8ep\x1f\x97\xaa\xf8 Ypp!\x80\xc7x\"B\x8c\xf0#i\xe3\xf8$\"n\xf0%I\xc5\xf8" + + "%\xef\xdb\xf0')\xa7\xf8'Ͻ\xf0)\t\x89\xf8)\xaf\x9f\xf0*\xe9k\xf8+\x98\xbcp,҈x-x\x9ep.\xb2jx/X\x80p0\x92Lx1]Lp2r.x3=.p" + + "4R\x10x5\x1d\x10p61\xf2x6\xfc\xf2p8\x1b\x0e\xf88\xdc\xd4p9\xa7\xe2x:\xbc\xb6p;\xda\xd2\xf8<\xa5\xd2\xf0=\xba\xb4\xf8>\x85\xb4\xf0?\x9a\x96\xf8@e\x96\xf0A\x83\xb3x" + + "BEx\xf0Cc\x95xD.\x95pECwxF\x05<\xf0G#YxG\xf7\x93\xf0H\xe7\x8b\xf8I\xd7u\xf0J\xc7m\xf8K\xb7W\xf0L\xa7O\xf8M\x979\xf0N\x871\xf8Ow\x1b\xf0" + + "PpNxQ`8pRP0xS@\x1apT0\x12xU\x1f\xfcpV\x0f\xf4xV\xff\xdepW\xef\xd6xX\xdf\xc0pYϸxZ\xbf\xa2p[\xb8\xd4\xf8\\\xa8\xbe\xf0]\x98\xb6\xf8" + + "^\x88\xa0\xf0_x\x98\xf8`h\x82\xf0aXz\xf8bHd\xf0c8\\\xf8d(F\xf0e\x18>\xf8f\x11cpg\x01[xg\xf1Eph\xe1=xi\xd1'pj\xc1\x1fxk\xb1\tp" + + "l\xa1\x01xm\x90\xebpn\x80\xe3xop\xcdppi\xff\xf8qY\xe9\xf0rI\xe1\xf8s9\xcb\xf0t)\xc3\xf8u\x19\xad\xf0v\t\xa5\xf8v\xf9\x8f\xf0w\xe9\x87\xf8x\xd9q\xf0y\xc9i\xf8" + + "z\xb9S\xf0{\xb2\x86x|\xa2pp}\x92hx~\x82Rp\u007frJx\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x04\x00\x00\x95$\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\xa1\xb8\x01\t\x00\x00\x93\xa8\x00\x0f\x00\x00\x9a\xb0\x01\x15LMT\x00AE" + + "ST\x00+1130\x00+1030\x00+11\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\x00\x00\x00\x05\x00" + + "\x00\x00\x19\xff\xff\xff\xffs\x16w\xdc\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168@\xf8\x00\x00\x00\x00\x16\xe7\x8ah\x00\x00\x00\x00\x18!]x\x00\x00\x00\x00\x18\xc7lh\x00\x00\x00\x00\x1a\x01?x\x00" + + "\x00\x00\x00\x1a\xa7Nh\x00\x00\x00\x00\x1b\xe1!x\x00\x00\x00\x00\x1c\x870h\x00\x00\x00\x00\x1d\xc1\x03x\x00\x00\x00\x00\x1ey\x8ep\x00\x00\x00\x00\x1f\x97\xaa\xf8\x00\x00\x00\x00 Ypp\x00\x00\x00\x00!" + + "\x80\xc7x\x00\x00\x00\x00\"B\x8c\xf0\x00\x00\x00\x00#i\xe3\xf8\x00\x00\x00\x00$\"n\xf0\x00\x00\x00\x00%I\xc5\xf8\x00\x00\x00\x00%\xef\xdb\xf0\x00\x00\x00\x00')\xa7\xf8\x00\x00\x00\x00'Ͻ\xf0\x00" + + "\x00\x00\x00)\t\x89\xf8\x00\x00\x00\x00)\xaf\x9f\xf0\x00\x00\x00\x00*\xe9k\xf8\x00\x00\x00\x00+\x98\xbcp\x00\x00\x00\x00,҈x\x00\x00\x00\x00-x\x9ep\x00\x00\x00\x00.\xb2jx\x00\x00\x00\x00/" + + "X\x80p\x00\x00\x00\x000\x92Lx\x00\x00\x00\x001]Lp\x00\x00\x00\x002r.x\x00\x00\x00\x003=.p\x00\x00\x00\x004R\x10x\x00\x00\x00\x005\x1d\x10p\x00\x00\x00\x0061\xf2x\x00" + + "\x00\x00\x006\xfc\xf2p\x00\x00\x00\x008\x1b\x0e\xf8\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xa7\xe2x\x00\x00\x00\x00:\xbc\xb6p\x00\x00\x00\x00;\xda\xd2\xf8\x00\x00\x00\x00<\xa5\xd2\xf0\x00\x00\x00\x00=" + + "\xba\xb4\xf8\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x96\xf8\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xb3x\x00\x00\x00\x00BEx\xf0\x00\x00\x00\x00Cc\x95x\x00\x00\x00\x00D.\x95p\x00" + + "\x00\x00\x00ECwx\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Yx\x00\x00\x00\x00G\xf7\x93\xf0\x00\x00\x00\x00H\xe7\x8b\xf8\x00\x00\x00\x00I\xd7u\xf0\x00\x00\x00\x00J\xc7m\xf8\x00\x00\x00\x00K" + + "\xb7W\xf0\x00\x00\x00\x00L\xa7O\xf8\x00\x00\x00\x00M\x979\xf0\x00\x00\x00\x00N\x871\xf8\x00\x00\x00\x00Ow\x1b\xf0\x00\x00\x00\x00PpNx\x00\x00\x00\x00Q`8p\x00\x00\x00\x00RP0x\x00" + + "\x00\x00\x00S@\x1ap\x00\x00\x00\x00T0\x12x\x00\x00\x00\x00U\x1f\xfcp\x00\x00\x00\x00V\x0f\xf4x\x00\x00\x00\x00V\xff\xdep\x00\x00\x00\x00W\xef\xd6x\x00\x00\x00\x00X\xdf\xc0p\x00\x00\x00\x00Y" + + "ϸx\x00\x00\x00\x00Z\xbf\xa2p\x00\x00\x00\x00[\xb8\xd4\xf8\x00\x00\x00\x00\\\xa8\xbe\xf0\x00\x00\x00\x00]\x98\xb6\xf8\x00\x00\x00\x00^\x88\xa0\xf0\x00\x00\x00\x00_x\x98\xf8\x00\x00\x00\x00`h\x82\xf0\x00" + + "\x00\x00\x00aXz\xf8\x00\x00\x00\x00bHd\xf0\x00\x00\x00\x00c8\\\xf8\x00\x00\x00\x00d(F\xf0\x00\x00\x00\x00e\x18>\xf8\x00\x00\x00\x00f\x11cp\x00\x00\x00\x00g\x01[x\x00\x00\x00\x00g" + + "\xf1Ep\x00\x00\x00\x00h\xe1=x\x00\x00\x00\x00i\xd1'p\x00\x00\x00\x00j\xc1\x1fx\x00\x00\x00\x00k\xb1\tp\x00\x00\x00\x00l\xa1\x01x\x00\x00\x00\x00m\x90\xebp\x00\x00\x00\x00n\x80\xe3x\x00" + + "\x00\x00\x00op\xcdp\x00\x00\x00\x00pi\xff\xf8\x00\x00\x00\x00qY\xe9\xf0\x00\x00\x00\x00rI\xe1\xf8\x00\x00\x00\x00s9\xcb\xf0\x00\x00\x00\x00t)\xc3\xf8\x00\x00\x00\x00u\x19\xad\xf0\x00\x00\x00\x00v" + + "\t\xa5\xf8\x00\x00\x00\x00v\xf9\x8f\xf0\x00\x00\x00\x00w\xe9\x87\xf8\x00\x00\x00\x00x\xd9q\xf0\x00\x00\x00\x00y\xc9i\xf8\x00\x00\x00\x00z\xb9S\xf0\x00\x00\x00\x00{\xb2\x86x\x00\x00\x00\x00|\xa2pp\x00" + + "\x00\x00\x00}\x92hx\x00\x00\x00\x00~\x82Rp\x00\x00\x00\x00\u007frJx\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x04\x00\x00\x95$\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\xa1\xb8\x01\t\x00\x00\x93\xa8\x00\x0f\x00\x00\x9a\xb0\x01\x15LMT" + + "\x00AEST\x00+1130\x00+1030\x00+11\x00\n<+1030>-10:30<+11>-11,M10.1.0,M4.1.0\n" + + "PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPJ\x04\x18\x99\xae\b\x00\x00\xae\b\x00\x00\x12\x00\x1c\x00Australia/AdelaideUT\t\x00\x03nӧ^nӧ" + + "^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x8e\x00\x00\x00\x05\x00\x00\x00\x0e" + + "\x80\x00\x00\x00\x9cN\xad\xa4\x9c\xbc'\xf8\xcbT\xba\b\xcb\xc7^x̷]\x88ͧ@xΠz\bχ\"x\x03p@\x88\x04\r#\b\x05P\"\x88\x05\xf6?\x88\a0\x04\x88\a\xd6!\x88" + + "\t\x0f\xe6\x88\t\xb6\x03\x88\n\xefȈ\v\x9f \b\f\xd8\xe5\b\r\u007f\x02\b\x0e\xb8\xc7\b\x0f^\xe4\b\x10\x98\xa9\b\x11>\xc6\b\x12x\x8b\b\x13\x1e\xa8\b\x14Xm\b\x14\xfe\x8a\b\x168O\b" + + "\x16禈\x18!k\x88\x18Lj\x88\x1a\x01M\x88\x1a\xa7j\x88\x1b\xe1/\x88\x1c\x87L\x88\x1d\xc1\x11\x88\x1ey\xa3\x88\x1f\x97\xb9\b Y\x85\x88!\x80Ո\"B\xa2\b#i\xf2\b$\"\x84\b" + + "%I\xd4\b&\x02f\b')\xb6\b'\xcf\xd3\b)\t\x98\b)\xcbd\x88*\xe9z\b+\x98ш,Җ\x88-\x8b(\x88.\xb2x\x88/tE\b0\x92Z\x881]a\x882r<\x88" + + "3=C\x884R\x1e\x885\x1d%\x8862\x00\x886\xfd\a\x888\x1b\x1d\b8\xdc\xe9\x889\xfa\xff\b:\xbcˈ;\xda\xe1\b<\xa5\xe8\b=\xba\xc3\b>\x85\xca\b?\x9a\xa5\b@e\xac\b" + + "A\x83\xc1\x88BE\x8e\bCc\xa3\x88D.\xaa\x88EC\x85\x88F\x05R\bG#g\x88G\xf7\xa9\bH\xe7\x9a\bI\u05cb\bJ\xc7|\bK\xb7m\bL\xa7^\bM\x97O\bN\x87@\b" + + "Ow1\bPp\\\x88Q`M\x88RP>\x88S@/\x88T0 \x88U \x11\x88V\x10\x02\x88V\xff\xf3\x88W\xef\xe4\x88X\xdfՈY\xcfƈZ\xbf\xb7\x88[\xb8\xe3\b\\\xa8\xd4\b" + + "]\x98\xc5\b^\x88\xb6\b_x\xa7\b`h\x98\baX\x89\bbHz\bc8k\bd(\\\be\x18M\bf\x11x\x88g\x01i\x88g\xf1Z\x88h\xe1K\x88i\xd1<\x88j\xc1-\x88" + + "k\xb1\x1e\x88l\xa1\x0f\x88m\x91\x00\x88n\x80\xf1\x88op\xe2\x88pj\x0e\bqY\xff\brI\xf0\bs9\xe1\bt)\xd2\bu\x19\xc3\bv\t\xb4\bv\xf9\xa5\bw\xe9\x96\bxه\b" + + "y\xc9x\bz\xb9i\b{\xb2\x94\x88|\xa2\x85\x88}\x92v\x88~\x82g\x88\u007frX\x88\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x81\xec\x00\x00\x00\x00\x93\xa8" + + "\x01\x04\x00\x00\x85\x98\x00\t\x00\x00\x93\xa8\x01\x04\x00\x00\x85\x98\x00\tLMT\x00ACDT\x00ACST\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x8f\x00\x00\x00\x06\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x8b\x14\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cN\xad\xa4\xff\xff\xff\xff\x9c\xbc'\xf8\xff\xff\xff\xff\xcb" + + "T\xba\b\xff\xff\xff\xff\xcb\xc7^x\xff\xff\xff\xff̷]\x88\xff\xff\xff\xffͧ@x\xff\xff\xff\xffΠz\b\xff\xff\xff\xffχ\"x\x00\x00\x00\x00\x03p@\x88\x00\x00\x00\x00\x04\r#\b\x00" + + "\x00\x00\x00\x05P\"\x88\x00\x00\x00\x00\x05\xf6?\x88\x00\x00\x00\x00\a0\x04\x88\x00\x00\x00\x00\a\xd6!\x88\x00\x00\x00\x00\t\x0f\xe6\x88\x00\x00\x00\x00\t\xb6\x03\x88\x00\x00\x00\x00\n\xefȈ\x00\x00\x00\x00\v" + + "\x9f \b\x00\x00\x00\x00\f\xd8\xe5\b\x00\x00\x00\x00\r\u007f\x02\b\x00\x00\x00\x00\x0e\xb8\xc7\b\x00\x00\x00\x00\x0f^\xe4\b\x00\x00\x00\x00\x10\x98\xa9\b\x00\x00\x00\x00\x11>\xc6\b\x00\x00\x00\x00\x12x\x8b\b\x00" + + "\x00\x00\x00\x13\x1e\xa8\b\x00\x00\x00\x00\x14Xm\b\x00\x00\x00\x00\x14\xfe\x8a\b\x00\x00\x00\x00\x168O\b\x00\x00\x00\x00\x16禈\x00\x00\x00\x00\x18!k\x88\x00\x00\x00\x00\x18Lj\x88\x00\x00\x00\x00\x1a" + + "\x01M\x88\x00\x00\x00\x00\x1a\xa7j\x88\x00\x00\x00\x00\x1b\xe1/\x88\x00\x00\x00\x00\x1c\x87L\x88\x00\x00\x00\x00\x1d\xc1\x11\x88\x00\x00\x00\x00\x1ey\xa3\x88\x00\x00\x00\x00\x1f\x97\xb9\b\x00\x00\x00\x00 Y\x85\x88\x00" + + "\x00\x00\x00!\x80Ո\x00\x00\x00\x00\"B\xa2\b\x00\x00\x00\x00#i\xf2\b\x00\x00\x00\x00$\"\x84\b\x00\x00\x00\x00%I\xd4\b\x00\x00\x00\x00&\x02f\b\x00\x00\x00\x00')\xb6\b\x00\x00\x00\x00'" + + "\xcf\xd3\b\x00\x00\x00\x00)\t\x98\b\x00\x00\x00\x00)\xcbd\x88\x00\x00\x00\x00*\xe9z\b\x00\x00\x00\x00+\x98ш\x00\x00\x00\x00,Җ\x88\x00\x00\x00\x00-\x8b(\x88\x00\x00\x00\x00.\xb2x\x88\x00" + + "\x00\x00\x00/tE\b\x00\x00\x00\x000\x92Z\x88\x00\x00\x00\x001]a\x88\x00\x00\x00\x002r<\x88\x00\x00\x00\x003=C\x88\x00\x00\x00\x004R\x1e\x88\x00\x00\x00\x005\x1d%\x88\x00\x00\x00\x006" + + "2\x00\x88\x00\x00\x00\x006\xfd\a\x88\x00\x00\x00\x008\x1b\x1d\b\x00\x00\x00\x008\xdc\xe9\x88\x00\x00\x00\x009\xfa\xff\b\x00\x00\x00\x00:\xbcˈ\x00\x00\x00\x00;\xda\xe1\b\x00\x00\x00\x00<\xa5\xe8\b\x00" + + "\x00\x00\x00=\xba\xc3\b\x00\x00\x00\x00>\x85\xca\b\x00\x00\x00\x00?\x9a\xa5\b\x00\x00\x00\x00@e\xac\b\x00\x00\x00\x00A\x83\xc1\x88\x00\x00\x00\x00BE\x8e\b\x00\x00\x00\x00Cc\xa3\x88\x00\x00\x00\x00D" + + ".\xaa\x88\x00\x00\x00\x00EC\x85\x88\x00\x00\x00\x00F\x05R\b\x00\x00\x00\x00G#g\x88\x00\x00\x00\x00G\xf7\xa9\b\x00\x00\x00\x00H\xe7\x9a\b\x00\x00\x00\x00I\u05cb\b\x00\x00\x00\x00J\xc7|\b\x00" + + "\x00\x00\x00K\xb7m\b\x00\x00\x00\x00L\xa7^\b\x00\x00\x00\x00M\x97O\b\x00\x00\x00\x00N\x87@\b\x00\x00\x00\x00Ow1\b\x00\x00\x00\x00Pp\\\x88\x00\x00\x00\x00Q`M\x88\x00\x00\x00\x00R" + + "P>\x88\x00\x00\x00\x00S@/\x88\x00\x00\x00\x00T0 \x88\x00\x00\x00\x00U \x11\x88\x00\x00\x00\x00V\x10\x02\x88\x00\x00\x00\x00V\xff\xf3\x88\x00\x00\x00\x00W\xef\xe4\x88\x00\x00\x00\x00X\xdfՈ\x00" + + "\x00\x00\x00Y\xcfƈ\x00\x00\x00\x00Z\xbf\xb7\x88\x00\x00\x00\x00[\xb8\xe3\b\x00\x00\x00\x00\\\xa8\xd4\b\x00\x00\x00\x00]\x98\xc5\b\x00\x00\x00\x00^\x88\xb6\b\x00\x00\x00\x00_x\xa7\b\x00\x00\x00\x00`" + + "h\x98\b\x00\x00\x00\x00aX\x89\b\x00\x00\x00\x00bHz\b\x00\x00\x00\x00c8k\b\x00\x00\x00\x00d(\\\b\x00\x00\x00\x00e\x18M\b\x00\x00\x00\x00f\x11x\x88\x00\x00\x00\x00g\x01i\x88\x00" + + "\x00\x00\x00g\xf1Z\x88\x00\x00\x00\x00h\xe1K\x88\x00\x00\x00\x00i\xd1<\x88\x00\x00\x00\x00j\xc1-\x88\x00\x00\x00\x00k\xb1\x1e\x88\x00\x00\x00\x00l\xa1\x0f\x88\x00\x00\x00\x00m\x91\x00\x88\x00\x00\x00\x00n" + + "\x80\xf1\x88\x00\x00\x00\x00op\xe2\x88\x00\x00\x00\x00pj\x0e\b\x00\x00\x00\x00qY\xff\b\x00\x00\x00\x00rI\xf0\b\x00\x00\x00\x00s9\xe1\b\x00\x00\x00\x00t)\xd2\b\x00\x00\x00\x00u\x19\xc3\b\x00" + + "\x00\x00\x00v\t\xb4\b\x00\x00\x00\x00v\xf9\xa5\b\x00\x00\x00\x00w\xe9\x96\b\x00\x00\x00\x00xه\b\x00\x00\x00\x00y\xc9x\b\x00\x00\x00\x00z\xb9i\b\x00\x00\x00\x00{\xb2\x94\x88\x00\x00\x00\x00|" + + "\xa2\x85\x88\x00\x00\x00\x00}\x92v\x88\x00\x00\x00\x00~\x82g\x88\x00\x00\x00\x00\u007frX\x88\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x00\x00\x81\xec\x00\x00\x00\x00~\x90" + + "\x00\x04\x00\x00\x93\xa8\x01\t\x00\x00\x85\x98\x00\x04\x00\x00\x93\xa8\x01\t\x00\x00\x85\x98\x00\x04LMT\x00ACST\x00ACDT\x00\x00\x00\x00\x00\x01\x01\nACST-9:30ACDT" + + ",M10.1.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x8f\xdbK\xf0\xc3\b\x00\x00\xc3\b\x00\x00\x14\x00\x1c\x00Australia/Ya" + + "ncowinnaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x8e\x00\x00\x00\x05\x00\x00\x00\x0e\x80\x00\x00\x00\x9cN\xad\xa4\x9c\xbc'\xf8\xcbT\xba\b\xcb\xc7^x̷]\x88ͧ@xΠz\bχ\"x\x03p@\x88" + + "\x04\r#\b\x05P\"\x88\x05\xf6?\x88\a0\x04\x88\a\xd6!\x88\t\x0f\xe6\x88\t\xb6\x03\x88\n\xefȈ\v\x9f \b\f\xd8\xe5\b\r\u007f\x02\b\x0e\xb8\xc7\b\x0f^\xe4\b\x10\x98\xa9\b\x11>\xc6\b" + + "\x12x\x8b\b\x13\x1e\xa8\b\x14Xm\b\x14\xfe\x8a\b\x168O\b\x17\f\x90\x88\x18!k\x88\x18Lj\x88\x1a\x01M\x88\x1a\xa7j\x88\x1b\xe1/\x88\x1c\x87L\x88\x1d\xc1\x11\x88\x1ey\xa3\x88\x1f\x97\xb9\b" + + " Y\x85\x88!\x80Ո\"B\xa2\b#i\xf2\b$\"\x84\b%I\xd4\b%\xef\xf1\b')\xb6\b'\xcf\xd3\b)\t\x98\b)\xaf\xb5\b*\xe9z\b+\x98ш,Җ\x88-x\xb3\x88" + + ".\xb2x\x88/X\x95\x880\x92Z\x881]a\x882r<\x883=C\x884R\x1e\x885\x1d%\x8862\x00\x886\xfd\a\x888\x1b\x1d\b8\xdc\xe9\x889\xfa\xff\b:\xbcˈ;\xda\xe1\b" + + "<\xa5\xe8\b=\xba\xc3\b>\x85\xca\b?\x9a\xa5\b@e\xac\bA\x83\xc1\x88BE\x8e\bCc\xa3\x88D.\xaa\x88EC\x85\x88F\x05R\bG#g\x88G\xf7\xa9\bH\xe7\x9a\bI\u05cb\b" + + "J\xc7|\bK\xb7m\bL\xa7^\bM\x97O\bN\x87@\bOw1\bPp\\\x88Q`M\x88RP>\x88S@/\x88T0 \x88U \x11\x88V\x10\x02\x88V\xff\xf3\x88W\xef\xe4\x88" + + "X\xdfՈY\xcfƈZ\xbf\xb7\x88[\xb8\xe3\b\\\xa8\xd4\b]\x98\xc5\b^\x88\xb6\b_x\xa7\b`h\x98\baX\x89\bbHz\bc8k\bd(\\\be\x18M\bf\x11x\x88" + + "g\x01i\x88g\xf1Z\x88h\xe1K\x88i\xd1<\x88j\xc1-\x88k\xb1\x1e\x88l\xa1\x0f\x88m\x91\x00\x88n\x80\xf1\x88op\xe2\x88pj\x0e\bqY\xff\brI\xf0\bs9\xe1\bt)\xd2\b" + + "u\x19\xc3\bv\t\xb4\bv\xf9\xa5\bw\xe9\x96\bxه\by\xc9x\bz\xb9i\b{\xb2\x94\x88|\xa2\x85\x88}\x92v\x88~\x82g\x88\u007frX\x88\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x84\x9c\x00\x00\x00\x00\x93\xa8\x01\x04\x00\x00\x85\x98\x00\t\x00\x00\x93\xa8\x01\x04\x00\x00\x85\x98\x00\tLMT\x00ACDT\x00ACST\x00\x00\x00\x00\x01\x01T" + + "Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00\x00\a\x00\x00\x00\x13\xff\xff\xff\xffs\x16\x88d\xff\xff\xff\xffv\x04\xa5\xe0\xff" + + "\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cN\xad\xa4\xff\xff\xff\xff\x9c\xbc'\xf8\xff\xff\xff\xff\xcbT\xba\b\xff\xff\xff\xff\xcb\xc7^x\xff\xff\xff\xff̷]\x88\xff\xff\xff\xffͧ@x\xff\xff\xff\xff\xce" + + "\xa0z\b\xff\xff\xff\xffχ\"x\x00\x00\x00\x00\x03p@\x88\x00\x00\x00\x00\x04\r#\b\x00\x00\x00\x00\x05P\"\x88\x00\x00\x00\x00\x05\xf6?\x88\x00\x00\x00\x00\a0\x04\x88\x00\x00\x00\x00\a\xd6!\x88\x00" + + "\x00\x00\x00\t\x0f\xe6\x88\x00\x00\x00\x00\t\xb6\x03\x88\x00\x00\x00\x00\n\xefȈ\x00\x00\x00\x00\v\x9f \b\x00\x00\x00\x00\f\xd8\xe5\b\x00\x00\x00\x00\r\u007f\x02\b\x00\x00\x00\x00\x0e\xb8\xc7\b\x00\x00\x00\x00\x0f" + + "^\xe4\b\x00\x00\x00\x00\x10\x98\xa9\b\x00\x00\x00\x00\x11>\xc6\b\x00\x00\x00\x00\x12x\x8b\b\x00\x00\x00\x00\x13\x1e\xa8\b\x00\x00\x00\x00\x14Xm\b\x00\x00\x00\x00\x14\xfe\x8a\b\x00\x00\x00\x00\x168O\b\x00" + + "\x00\x00\x00\x17\f\x90\x88\x00\x00\x00\x00\x18!k\x88\x00\x00\x00\x00\x18Lj\x88\x00\x00\x00\x00\x1a\x01M\x88\x00\x00\x00\x00\x1a\xa7j\x88\x00\x00\x00\x00\x1b\xe1/\x88\x00\x00\x00\x00\x1c\x87L\x88\x00\x00\x00\x00\x1d" + + "\xc1\x11\x88\x00\x00\x00\x00\x1ey\xa3\x88\x00\x00\x00\x00\x1f\x97\xb9\b\x00\x00\x00\x00 Y\x85\x88\x00\x00\x00\x00!\x80Ո\x00\x00\x00\x00\"B\xa2\b\x00\x00\x00\x00#i\xf2\b\x00\x00\x00\x00$\"\x84\b\x00" + + "\x00\x00\x00%I\xd4\b\x00\x00\x00\x00%\xef\xf1\b\x00\x00\x00\x00')\xb6\b\x00\x00\x00\x00'\xcf\xd3\b\x00\x00\x00\x00)\t\x98\b\x00\x00\x00\x00)\xaf\xb5\b\x00\x00\x00\x00*\xe9z\b\x00\x00\x00\x00+" + + "\x98ш\x00\x00\x00\x00,Җ\x88\x00\x00\x00\x00-x\xb3\x88\x00\x00\x00\x00.\xb2x\x88\x00\x00\x00\x00/X\x95\x88\x00\x00\x00\x000\x92Z\x88\x00\x00\x00\x001]a\x88\x00\x00\x00\x002r<\x88\x00" + + "\x00\x00\x003=C\x88\x00\x00\x00\x004R\x1e\x88\x00\x00\x00\x005\x1d%\x88\x00\x00\x00\x0062\x00\x88\x00\x00\x00\x006\xfd\a\x88\x00\x00\x00\x008\x1b\x1d\b\x00\x00\x00\x008\xdc\xe9\x88\x00\x00\x00\x009" + + "\xfa\xff\b\x00\x00\x00\x00:\xbcˈ\x00\x00\x00\x00;\xda\xe1\b\x00\x00\x00\x00<\xa5\xe8\b\x00\x00\x00\x00=\xba\xc3\b\x00\x00\x00\x00>\x85\xca\b\x00\x00\x00\x00?\x9a\xa5\b\x00\x00\x00\x00@e\xac\b\x00" + + "\x00\x00\x00A\x83\xc1\x88\x00\x00\x00\x00BE\x8e\b\x00\x00\x00\x00Cc\xa3\x88\x00\x00\x00\x00D.\xaa\x88\x00\x00\x00\x00EC\x85\x88\x00\x00\x00\x00F\x05R\b\x00\x00\x00\x00G#g\x88\x00\x00\x00\x00G" + + "\xf7\xa9\b\x00\x00\x00\x00H\xe7\x9a\b\x00\x00\x00\x00I\u05cb\b\x00\x00\x00\x00J\xc7|\b\x00\x00\x00\x00K\xb7m\b\x00\x00\x00\x00L\xa7^\b\x00\x00\x00\x00M\x97O\b\x00\x00\x00\x00N\x87@\b\x00" + + "\x00\x00\x00Ow1\b\x00\x00\x00\x00Pp\\\x88\x00\x00\x00\x00Q`M\x88\x00\x00\x00\x00RP>\x88\x00\x00\x00\x00S@/\x88\x00\x00\x00\x00T0 \x88\x00\x00\x00\x00U \x11\x88\x00\x00\x00\x00V" + + "\x10\x02\x88\x00\x00\x00\x00V\xff\xf3\x88\x00\x00\x00\x00W\xef\xe4\x88\x00\x00\x00\x00X\xdfՈ\x00\x00\x00\x00Y\xcfƈ\x00\x00\x00\x00Z\xbf\xb7\x88\x00\x00\x00\x00[\xb8\xe3\b\x00\x00\x00\x00\\\xa8\xd4\b\x00" + + "\x00\x00\x00]\x98\xc5\b\x00\x00\x00\x00^\x88\xb6\b\x00\x00\x00\x00_x\xa7\b\x00\x00\x00\x00`h\x98\b\x00\x00\x00\x00aX\x89\b\x00\x00\x00\x00bHz\b\x00\x00\x00\x00c8k\b\x00\x00\x00\x00d" + + "(\\\b\x00\x00\x00\x00e\x18M\b\x00\x00\x00\x00f\x11x\x88\x00\x00\x00\x00g\x01i\x88\x00\x00\x00\x00g\xf1Z\x88\x00\x00\x00\x00h\xe1K\x88\x00\x00\x00\x00i\xd1<\x88\x00\x00\x00\x00j\xc1-\x88\x00" + + "\x00\x00\x00k\xb1\x1e\x88\x00\x00\x00\x00l\xa1\x0f\x88\x00\x00\x00\x00m\x91\x00\x88\x00\x00\x00\x00n\x80\xf1\x88\x00\x00\x00\x00op\xe2\x88\x00\x00\x00\x00pj\x0e\b\x00\x00\x00\x00qY\xff\b\x00\x00\x00\x00r" + + "I\xf0\b\x00\x00\x00\x00s9\xe1\b\x00\x00\x00\x00t)\xd2\b\x00\x00\x00\x00u\x19\xc3\b\x00\x00\x00\x00v\t\xb4\b\x00\x00\x00\x00v\xf9\xa5\b\x00\x00\x00\x00w\xe9\x96\b\x00\x00\x00\x00xه\b\x00" + + "\x00\x00\x00y\xc9x\b\x00\x00\x00\x00z\xb9i\b\x00\x00\x00\x00{\xb2\x94\x88\x00\x00\x00\x00|\xa2\x85\x88\x00\x00\x00\x00}\x92v\x88\x00\x00\x00\x00~\x82g\x88\x00\x00\x00\x00\u007frX\x88\x01\x02\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x00\x00\x84\x9c\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\t\x00\x00\x93\xa8\x01\x0e\x00\x00\x85\x98\x00\t\x00\x00\x93\xa8\x01\x0e\x00\x00\x85\x98\x00" + + "\tLMT\x00AEST\x00ACST\x00ACDT\x00\x00\x00\x00\x00\x00\x01\x01\nACST-9:30ACDT,M10.1.0,M4.1.0/3\nP" + + "K\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xbeY\xcc?\x9c\b\x00\x00\x9c\b\x00\x00\x12\x00\x1c\x00Australia/VictoriaUT\t\x00\x03nӧ^nӧ^" + + "ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x8e\x00\x00\x00\x05\x00\x00\x00\x0e\x80" + + "\x00\x00\x00\x9cN\xa6\x9c\x9c\xbc \xf0\xcbT\xb3\x00\xcb\xc7Wp̷V\x80ͧ9pΠs\x00χ\x1bp\x03p9\x80\x04\r\x1c\x00\x05P\x1b\x80\x05\xf68\x80\a/\xfd\x80\a\xd6\x1a\x80\t" + + "\x0f߀\t\xb5\xfc\x80\n\xef\xc1\x80\v\x9f\x19\x00\f\xd8\xde\x00\r~\xfb\x00\x0e\xb8\xc0\x00\x0f^\xdd\x00\x10\x98\xa2\x00\x11>\xbf\x00\x12x\x84\x00\x13\x1e\xa1\x00\x14Xf\x00\x14\xfe\x83\x00\x168H\x00\x16" + + "矀\x18!d\x80\x18ǁ\x80\x1a\x01F\x80\x1a\xa7c\x80\x1b\xe1(\x80\x1c\x87E\x80\x1d\xc1\n\x80\x1ey\x9c\x80\x1f\x97\xb2\x00 Y~\x80!w\x94\x00\"B\x9b\x00#i\xeb\x00$\"}\x00%" + + "I\xcd\x00&\x02_\x00')\xaf\x00'\xcf\xcc\x00)\t\x91\x00)\xaf\xae\x00*\xe9s\x00+\x98ʀ,ҏ\x80-x\xac\x80.\xb2q\x80/t>\x000\x92S\x801]Z\x802r5\x803" + + "=<\x804R\x17\x805\x1d\x1e\x8061\xf9\x806\xfd\x00\x808\x1b\x16\x008\xdc\xe2\x809\xa7\xe9\x80:\xbcĀ;\xda\xda\x00<\xa5\xe1\x00=\xba\xbc\x00>\x85\xc3\x00?\x9a\x9e\x00@e\xa5\x00A" + + "\x83\xba\x80BE\x87\x00Cc\x9c\x80D.\xa3\x80EC~\x80F\x05K\x00G#`\x80G\xf7\xa2\x00H\xe7\x93\x00Iׄ\x00J\xc7u\x00K\xb7f\x00L\xa7W\x00M\x97H\x00N\x879\x00O" + + "w*\x00PpU\x80Q`F\x80RP7\x80S@(\x80T0\x19\x80U \n\x80V\x0f\xfb\x80V\xff\xec\x80W\xef݀X\xdf\u0380YϿ\x80Z\xbf\xb0\x80[\xb8\xdc\x00\\\xa8\xcd\x00]" + + "\x98\xbe\x00^\x88\xaf\x00_x\xa0\x00`h\x91\x00aX\x82\x00bHs\x00c8d\x00d(U\x00e\x18F\x00f\x11q\x80g\x01b\x80g\xf1S\x80h\xe1D\x80i\xd15\x80j\xc1&\x80k" + + "\xb1\x17\x80l\xa1\b\x80m\x90\xf9\x80n\x80\xea\x80opۀpj\a\x00qY\xf8\x00rI\xe9\x00s9\xda\x00t)\xcb\x00u\x19\xbc\x00v\t\xad\x00v\xf9\x9e\x00w\xe9\x8f\x00xـ\x00y" + + "\xc9q\x00z\xb9b\x00{\xb2\x8d\x80|\xa2~\x80}\x92o\x80~\x82`\x80\u007frQ\x80\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x87\xe8\x00\x00\x00\x00\x9a\xb0\x01" + + "\x04\x00\x00\x8c\xa0\x00\t\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x8e\x00\x00\x00\x05\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x85\x18\xff\xff\xff\xff\x9cN\xa6\x9c\xff\xff\xff\xff\x9c\xbc \xf0\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7" + + "Wp\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧ9p\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ\x1bp\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00" + + "\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8" + + "\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00" + + "\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x16矀\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18ǁ\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7" + + "c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!w\x94\x00\x00\x00" + + "\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t" + + "\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00\x00\x00,ҏ\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/t>\x00\x00\x00" + + "\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd" + + "\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00" + + "\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC" + + "~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\x00\x00\x00\x00H\xe7\x93\x00\x00\x00\x00\x00Iׄ\x00\x00\x00\x00\x00J\xc7u\x00\x00\x00\x00\x00K\xb7f\x00\x00\x00" + + "\x00\x00L\xa7W\x00\x00\x00\x00\x00M\x97H\x00\x00\x00\x00\x00N\x879\x00\x00\x00\x00\x00Ow*\x00\x00\x00\x00\x00PpU\x80\x00\x00\x00\x00Q`F\x80\x00\x00\x00\x00RP7\x80\x00\x00\x00\x00S@" + + "(\x80\x00\x00\x00\x00T0\x19\x80\x00\x00\x00\x00U \n\x80\x00\x00\x00\x00V\x0f\xfb\x80\x00\x00\x00\x00V\xff\xec\x80\x00\x00\x00\x00W\xef݀\x00\x00\x00\x00X\xdf\u0380\x00\x00\x00\x00YϿ\x80\x00\x00" + + "\x00\x00Z\xbf\xb0\x80\x00\x00\x00\x00[\xb8\xdc\x00\x00\x00\x00\x00\\\xa8\xcd\x00\x00\x00\x00\x00]\x98\xbe\x00\x00\x00\x00\x00^\x88\xaf\x00\x00\x00\x00\x00_x\xa0\x00\x00\x00\x00\x00`h\x91\x00\x00\x00\x00\x00aX" + + "\x82\x00\x00\x00\x00\x00bHs\x00\x00\x00\x00\x00c8d\x00\x00\x00\x00\x00d(U\x00\x00\x00\x00\x00e\x18F\x00\x00\x00\x00\x00f\x11q\x80\x00\x00\x00\x00g\x01b\x80\x00\x00\x00\x00g\xf1S\x80\x00\x00" + + "\x00\x00h\xe1D\x80\x00\x00\x00\x00i\xd15\x80\x00\x00\x00\x00j\xc1&\x80\x00\x00\x00\x00k\xb1\x17\x80\x00\x00\x00\x00l\xa1\b\x80\x00\x00\x00\x00m\x90\xf9\x80\x00\x00\x00\x00n\x80\xea\x80\x00\x00\x00\x00op" + + "ۀ\x00\x00\x00\x00pj\a\x00\x00\x00\x00\x00qY\xf8\x00\x00\x00\x00\x00rI\xe9\x00\x00\x00\x00\x00s9\xda\x00\x00\x00\x00\x00t)\xcb\x00\x00\x00\x00\x00u\x19\xbc\x00\x00\x00\x00\x00v\t\xad\x00\x00\x00" + + "\x00\x00v\xf9\x9e\x00\x00\x00\x00\x00w\xe9\x8f\x00\x00\x00\x00\x00xـ\x00\x00\x00\x00\x00y\xc9q\x00\x00\x00\x00\x00z\xb9b\x00\x00\x00\x00\x00{\xb2\x8d\x80\x00\x00\x00\x00|\xa2~\x80\x00\x00\x00\x00}\x92" + + "o\x80\x00\x00\x00\x00~\x82`\x80\x00\x00\x00\x00\u007frQ\x80\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x87\xe8\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\t\x00\x00" + + "\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\x00\x00\x00\x01\x01\nAEST-10AEDT,M10.1.0,M4.1.0/3\nP" + + "K\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPF\xc7\x15h\x9c\b\x00\x00\x9c\b\x00\x00\x12\x00\x1c\x00Australia/CanberraUT\t\x00\x03nӧ^nӧ^" + + "ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x8e\x00\x00\x00\x05\x00\x00\x00\x0e\x80" + + "\x00\x00\x00\x9cN\xa6\x9c\x9c\xbc \xf0\xcbT\xb3\x00\xcb\xc7Wp̷V\x80ͧ9pΠs\x00χ\x1bp\x03p9\x80\x04\r\x1c\x00\x05P\x1b\x80\x05\xf68\x80\a/\xfd\x80\a\xd6\x1a\x80\t" + + "\x0f߀\t\xb5\xfc\x80\n\xef\xc1\x80\v\x9f\x19\x00\f\xd8\xde\x00\r~\xfb\x00\x0e\xb8\xc0\x00\x0f^\xdd\x00\x10\x98\xa2\x00\x11>\xbf\x00\x12x\x84\x00\x13\x1e\xa1\x00\x14Xf\x00\x14\xfe\x83\x00\x168H\x00\x17" + + "\f\x89\x80\x18!d\x80\x18ǁ\x80\x1a\x01F\x80\x1a\xa7c\x80\x1b\xe1(\x80\x1c\x87E\x80\x1d\xc1\n\x80\x1ey\x9c\x80\x1f\x97\xb2\x00 Y~\x80!\x80\u0380\"B\x9b\x00#i\xeb\x00$\"}\x00%" + + "I\xcd\x00%\xef\xea\x00')\xaf\x00'\xcf\xcc\x00)\t\x91\x00)\xaf\xae\x00*\xe9s\x00+\x98ʀ,ҏ\x80-x\xac\x80.\xb2q\x80/X\x8e\x800\x92S\x801]Z\x802r5\x803" + + "=<\x804R\x17\x805\x1d\x1e\x8061\xf9\x806\xfd\x00\x808\x1b\x16\x008\xdc\xe2\x809\xa7\xe9\x80:\xbcĀ;\xda\xda\x00<\xa5\xe1\x00=\xba\xbc\x00>\x85\xc3\x00?\x9a\x9e\x00@e\xa5\x00A" + + "\x83\xba\x80BE\x87\x00Cc\x9c\x80D.\xa3\x80EC~\x80F\x05K\x00G#`\x80G\xf7\xa2\x00H\xe7\x93\x00Iׄ\x00J\xc7u\x00K\xb7f\x00L\xa7W\x00M\x97H\x00N\x879\x00O" + + "w*\x00PpU\x80Q`F\x80RP7\x80S@(\x80T0\x19\x80U \n\x80V\x0f\xfb\x80V\xff\xec\x80W\xef݀X\xdf\u0380YϿ\x80Z\xbf\xb0\x80[\xb8\xdc\x00\\\xa8\xcd\x00]" + + "\x98\xbe\x00^\x88\xaf\x00_x\xa0\x00`h\x91\x00aX\x82\x00bHs\x00c8d\x00d(U\x00e\x18F\x00f\x11q\x80g\x01b\x80g\xf1S\x80h\xe1D\x80i\xd15\x80j\xc1&\x80k" + + "\xb1\x17\x80l\xa1\b\x80m\x90\xf9\x80n\x80\xea\x80opۀpj\a\x00qY\xf8\x00rI\xe9\x00s9\xda\x00t)\xcb\x00u\x19\xbc\x00v\t\xad\x00v\xf9\x9e\x00w\xe9\x8f\x00xـ\x00y" + + "\xc9q\x00z\xb9b\x00{\xb2\x8d\x80|\xa2~\x80}\x92o\x80~\x82`\x80\u007frQ\x80\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0\x01" + + "\x04\x00\x00\x8c\xa0\x00\t\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x8e\x00\x00\x00\x05\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\u007f<\xff\xff\xff\xff\x9cN\xa6\x9c\xff\xff\xff\xff\x9c\xbc \xf0\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7" + + "Wp\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧ9p\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ\x1bp\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00" + + "\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8" + + "\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00" + + "\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\f\x89\x80\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18ǁ\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7" + + "c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00" + + "\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t" + + "\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00\x00\x00,ҏ\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/X\x8e\x80\x00\x00" + + "\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd" + + "\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00" + + "\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC" + + "~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\x00\x00\x00\x00H\xe7\x93\x00\x00\x00\x00\x00Iׄ\x00\x00\x00\x00\x00J\xc7u\x00\x00\x00\x00\x00K\xb7f\x00\x00\x00" + + "\x00\x00L\xa7W\x00\x00\x00\x00\x00M\x97H\x00\x00\x00\x00\x00N\x879\x00\x00\x00\x00\x00Ow*\x00\x00\x00\x00\x00PpU\x80\x00\x00\x00\x00Q`F\x80\x00\x00\x00\x00RP7\x80\x00\x00\x00\x00S@" + + "(\x80\x00\x00\x00\x00T0\x19\x80\x00\x00\x00\x00U \n\x80\x00\x00\x00\x00V\x0f\xfb\x80\x00\x00\x00\x00V\xff\xec\x80\x00\x00\x00\x00W\xef݀\x00\x00\x00\x00X\xdf\u0380\x00\x00\x00\x00YϿ\x80\x00\x00" + + "\x00\x00Z\xbf\xb0\x80\x00\x00\x00\x00[\xb8\xdc\x00\x00\x00\x00\x00\\\xa8\xcd\x00\x00\x00\x00\x00]\x98\xbe\x00\x00\x00\x00\x00^\x88\xaf\x00\x00\x00\x00\x00_x\xa0\x00\x00\x00\x00\x00`h\x91\x00\x00\x00\x00\x00aX" + + "\x82\x00\x00\x00\x00\x00bHs\x00\x00\x00\x00\x00c8d\x00\x00\x00\x00\x00d(U\x00\x00\x00\x00\x00e\x18F\x00\x00\x00\x00\x00f\x11q\x80\x00\x00\x00\x00g\x01b\x80\x00\x00\x00\x00g\xf1S\x80\x00\x00" + + "\x00\x00h\xe1D\x80\x00\x00\x00\x00i\xd15\x80\x00\x00\x00\x00j\xc1&\x80\x00\x00\x00\x00k\xb1\x17\x80\x00\x00\x00\x00l\xa1\b\x80\x00\x00\x00\x00m\x90\xf9\x80\x00\x00\x00\x00n\x80\xea\x80\x00\x00\x00\x00op" + + "ۀ\x00\x00\x00\x00pj\a\x00\x00\x00\x00\x00qY\xf8\x00\x00\x00\x00\x00rI\xe9\x00\x00\x00\x00\x00s9\xda\x00\x00\x00\x00\x00t)\xcb\x00\x00\x00\x00\x00u\x19\xbc\x00\x00\x00\x00\x00v\t\xad\x00\x00\x00" + + "\x00\x00v\xf9\x9e\x00\x00\x00\x00\x00w\xe9\x8f\x00\x00\x00\x00\x00xـ\x00\x00\x00\x00\x00y\xc9q\x00\x00\x00\x00\x00z\xb9b\x00\x00\x00\x00\x00{\xb2\x8d\x80\x00\x00\x00\x00|\xa2~\x80\x00\x00\x00\x00}\x92" + + "o\x80\x00\x00\x00\x00~\x82`\x80\x00\x00\x00\x00\u007frQ\x80\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\t\x00\x00" + + "\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\x00\x00\x00\x01\x01\nAEST-10AEDT,M10.1.0,M4.1.0/3\nP" + + "K\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPF\xc7\x15h\x9c\b\x00\x00\x9c\b\x00\x00\x10\x00\x1c\x00Australia/SydneyUT\t\x00\x03nӧ^nӧ^ux" + + "\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x8e\x00\x00\x00\x05\x00\x00\x00\x0e\x80\x00\x00" + + "\x00\x9cN\xa6\x9c\x9c\xbc \xf0\xcbT\xb3\x00\xcb\xc7Wp̷V\x80ͧ9pΠs\x00χ\x1bp\x03p9\x80\x04\r\x1c\x00\x05P\x1b\x80\x05\xf68\x80\a/\xfd\x80\a\xd6\x1a\x80\t\x0f\xdf" + + "\x80\t\xb5\xfc\x80\n\xef\xc1\x80\v\x9f\x19\x00\f\xd8\xde\x00\r~\xfb\x00\x0e\xb8\xc0\x00\x0f^\xdd\x00\x10\x98\xa2\x00\x11>\xbf\x00\x12x\x84\x00\x13\x1e\xa1\x00\x14Xf\x00\x14\xfe\x83\x00\x168H\x00\x17\f\x89" + + "\x80\x18!d\x80\x18ǁ\x80\x1a\x01F\x80\x1a\xa7c\x80\x1b\xe1(\x80\x1c\x87E\x80\x1d\xc1\n\x80\x1ey\x9c\x80\x1f\x97\xb2\x00 Y~\x80!\x80\u0380\"B\x9b\x00#i\xeb\x00$\"}\x00%I\xcd" + + "\x00%\xef\xea\x00')\xaf\x00'\xcf\xcc\x00)\t\x91\x00)\xaf\xae\x00*\xe9s\x00+\x98ʀ,ҏ\x80-x\xac\x80.\xb2q\x80/X\x8e\x800\x92S\x801]Z\x802r5\x803=<" + + "\x804R\x17\x805\x1d\x1e\x8061\xf9\x806\xfd\x00\x808\x1b\x16\x008\xdc\xe2\x809\xa7\xe9\x80:\xbcĀ;\xda\xda\x00<\xa5\xe1\x00=\xba\xbc\x00>\x85\xc3\x00?\x9a\x9e\x00@e\xa5\x00A\x83\xba" + + "\x80BE\x87\x00Cc\x9c\x80D.\xa3\x80EC~\x80F\x05K\x00G#`\x80G\xf7\xa2\x00H\xe7\x93\x00Iׄ\x00J\xc7u\x00K\xb7f\x00L\xa7W\x00M\x97H\x00N\x879\x00Ow*" + + "\x00PpU\x80Q`F\x80RP7\x80S@(\x80T0\x19\x80U \n\x80V\x0f\xfb\x80V\xff\xec\x80W\xef݀X\xdf\u0380YϿ\x80Z\xbf\xb0\x80[\xb8\xdc\x00\\\xa8\xcd\x00]\x98\xbe" + + "\x00^\x88\xaf\x00_x\xa0\x00`h\x91\x00aX\x82\x00bHs\x00c8d\x00d(U\x00e\x18F\x00f\x11q\x80g\x01b\x80g\xf1S\x80h\xe1D\x80i\xd15\x80j\xc1&\x80k\xb1\x17" + + "\x80l\xa1\b\x80m\x90\xf9\x80n\x80\xea\x80opۀpj\a\x00qY\xf8\x00rI\xe9\x00s9\xda\x00t)\xcb\x00u\x19\xbc\x00v\t\xad\x00v\xf9\x9e\x00w\xe9\x8f\x00xـ\x00y\xc9q" + + "\x00z\xb9b\x00{\xb2\x8d\x80|\xa2~\x80}\x92o\x80~\x82`\x80\u007frQ\x80\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0\x01\x04\x00" + + "\x00\x8c\xa0\x00\t\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x8e\x00\x00\x00\x05\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\u007f<\xff\xff\xff\xff\x9cN\xa6\x9c\xff\xff\xff\xff\x9c\xbc \xf0\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7Wp" + + "\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧ9p\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ\x1bp\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00" + + "\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00" + + "\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00" + + "\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\f\x89\x80\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18ǁ\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80" + + "\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00" + + "\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00" + + "\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00\x00\x00,ҏ\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/X\x8e\x80\x00\x00\x00\x00" + + "0\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80" + + "\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00" + + ">\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC~\x80" + + "\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\x00\x00\x00\x00H\xe7\x93\x00\x00\x00\x00\x00Iׄ\x00\x00\x00\x00\x00J\xc7u\x00\x00\x00\x00\x00K\xb7f\x00\x00\x00\x00\x00" + + "L\xa7W\x00\x00\x00\x00\x00M\x97H\x00\x00\x00\x00\x00N\x879\x00\x00\x00\x00\x00Ow*\x00\x00\x00\x00\x00PpU\x80\x00\x00\x00\x00Q`F\x80\x00\x00\x00\x00RP7\x80\x00\x00\x00\x00S@(\x80" + + "\x00\x00\x00\x00T0\x19\x80\x00\x00\x00\x00U \n\x80\x00\x00\x00\x00V\x0f\xfb\x80\x00\x00\x00\x00V\xff\xec\x80\x00\x00\x00\x00W\xef݀\x00\x00\x00\x00X\xdf\u0380\x00\x00\x00\x00YϿ\x80\x00\x00\x00\x00" + + "Z\xbf\xb0\x80\x00\x00\x00\x00[\xb8\xdc\x00\x00\x00\x00\x00\\\xa8\xcd\x00\x00\x00\x00\x00]\x98\xbe\x00\x00\x00\x00\x00^\x88\xaf\x00\x00\x00\x00\x00_x\xa0\x00\x00\x00\x00\x00`h\x91\x00\x00\x00\x00\x00aX\x82\x00" + + "\x00\x00\x00\x00bHs\x00\x00\x00\x00\x00c8d\x00\x00\x00\x00\x00d(U\x00\x00\x00\x00\x00e\x18F\x00\x00\x00\x00\x00f\x11q\x80\x00\x00\x00\x00g\x01b\x80\x00\x00\x00\x00g\xf1S\x80\x00\x00\x00\x00" + + "h\xe1D\x80\x00\x00\x00\x00i\xd15\x80\x00\x00\x00\x00j\xc1&\x80\x00\x00\x00\x00k\xb1\x17\x80\x00\x00\x00\x00l\xa1\b\x80\x00\x00\x00\x00m\x90\xf9\x80\x00\x00\x00\x00n\x80\xea\x80\x00\x00\x00\x00opۀ" + + "\x00\x00\x00\x00pj\a\x00\x00\x00\x00\x00qY\xf8\x00\x00\x00\x00\x00rI\xe9\x00\x00\x00\x00\x00s9\xda\x00\x00\x00\x00\x00t)\xcb\x00\x00\x00\x00\x00u\x19\xbc\x00\x00\x00\x00\x00v\t\xad\x00\x00\x00\x00\x00" + + "v\xf9\x9e\x00\x00\x00\x00\x00w\xe9\x8f\x00\x00\x00\x00\x00xـ\x00\x00\x00\x00\x00y\xc9q\x00\x00\x00\x00\x00z\xb9b\x00\x00\x00\x00\x00{\xb2\x8d\x80\x00\x00\x00\x00|\xa2~\x80\x00\x00\x00\x00}\x92o\x80" + + "\x00\x00\x00\x00~\x82`\x80\x00\x00\x00\x00\u007frQ\x80\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\t\x00\x00\x9a\xb0" + + "\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\x00\x00\x00\x01\x01\nAEST-10AEDT,M10.1.0,M4.1.0/3\nPK\x03" + + "\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPF\xc7\x15h\x9c\b\x00\x00\x9c\b\x00\x00\r\x00\x1c\x00Australia/ACTUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5" + + "\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x8e\x00\x00\x00\x05\x00\x00\x00\x0e\x80\x00\x00\x00\x9cN\xa6\x9c" + + "\x9c\xbc \xf0\xcbT\xb3\x00\xcb\xc7Wp̷V\x80ͧ9pΠs\x00χ\x1bp\x03p9\x80\x04\r\x1c\x00\x05P\x1b\x80\x05\xf68\x80\a/\xfd\x80\a\xd6\x1a\x80\t\x0f߀\t\xb5\xfc\x80" + + "\n\xef\xc1\x80\v\x9f\x19\x00\f\xd8\xde\x00\r~\xfb\x00\x0e\xb8\xc0\x00\x0f^\xdd\x00\x10\x98\xa2\x00\x11>\xbf\x00\x12x\x84\x00\x13\x1e\xa1\x00\x14Xf\x00\x14\xfe\x83\x00\x168H\x00\x17\f\x89\x80\x18!d\x80" + + "\x18ǁ\x80\x1a\x01F\x80\x1a\xa7c\x80\x1b\xe1(\x80\x1c\x87E\x80\x1d\xc1\n\x80\x1ey\x9c\x80\x1f\x97\xb2\x00 Y~\x80!\x80\u0380\"B\x9b\x00#i\xeb\x00$\"}\x00%I\xcd\x00%\xef\xea\x00" + + "')\xaf\x00'\xcf\xcc\x00)\t\x91\x00)\xaf\xae\x00*\xe9s\x00+\x98ʀ,ҏ\x80-x\xac\x80.\xb2q\x80/X\x8e\x800\x92S\x801]Z\x802r5\x803=<\x804R\x17\x80" + + "5\x1d\x1e\x8061\xf9\x806\xfd\x00\x808\x1b\x16\x008\xdc\xe2\x809\xa7\xe9\x80:\xbcĀ;\xda\xda\x00<\xa5\xe1\x00=\xba\xbc\x00>\x85\xc3\x00?\x9a\x9e\x00@e\xa5\x00A\x83\xba\x80BE\x87\x00" + + "Cc\x9c\x80D.\xa3\x80EC~\x80F\x05K\x00G#`\x80G\xf7\xa2\x00H\xe7\x93\x00Iׄ\x00J\xc7u\x00K\xb7f\x00L\xa7W\x00M\x97H\x00N\x879\x00Ow*\x00PpU\x80" + + "Q`F\x80RP7\x80S@(\x80T0\x19\x80U \n\x80V\x0f\xfb\x80V\xff\xec\x80W\xef݀X\xdf\u0380YϿ\x80Z\xbf\xb0\x80[\xb8\xdc\x00\\\xa8\xcd\x00]\x98\xbe\x00^\x88\xaf\x00" + + "_x\xa0\x00`h\x91\x00aX\x82\x00bHs\x00c8d\x00d(U\x00e\x18F\x00f\x11q\x80g\x01b\x80g\xf1S\x80h\xe1D\x80i\xd15\x80j\xc1&\x80k\xb1\x17\x80l\xa1\b\x80" + + "m\x90\xf9\x80n\x80\xea\x80opۀpj\a\x00qY\xf8\x00rI\xe9\x00s9\xda\x00t)\xcb\x00u\x19\xbc\x00v\t\xad\x00v\xf9\x9e\x00w\xe9\x8f\x00xـ\x00y\xc9q\x00z\xb9b\x00" + + "{\xb2\x8d\x80|\xa2~\x80}\x92o\x80~\x82`\x80\u007frQ\x80\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\t" + + "\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00" + + "\x00\x00\x00\x00\x00\x00\x8e\x00\x00\x00\x05\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\u007f<\xff\xff\xff\xff\x9cN\xa6\x9c\xff\xff\xff\xff\x9c\xbc \xf0\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7Wp\xff\xff\xff\xff\xcc" + + "\xb7V\x80\xff\xff\xff\xffͧ9p\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ\x1bp\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00" + + "\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r" + + "~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00" + + "\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\f\x89\x80\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18ǁ\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b" + + "\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00" + + "\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)" + + "\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00\x00\x00,ҏ\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/X\x8e\x80\x00\x00\x00\x000\x92S\x80\x00" + + "\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008" + + "\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00" + + "\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F" + + "\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\x00\x00\x00\x00H\xe7\x93\x00\x00\x00\x00\x00Iׄ\x00\x00\x00\x00\x00J\xc7u\x00\x00\x00\x00\x00K\xb7f\x00\x00\x00\x00\x00L\xa7W\x00\x00" + + "\x00\x00\x00M\x97H\x00\x00\x00\x00\x00N\x879\x00\x00\x00\x00\x00Ow*\x00\x00\x00\x00\x00PpU\x80\x00\x00\x00\x00Q`F\x80\x00\x00\x00\x00RP7\x80\x00\x00\x00\x00S@(\x80\x00\x00\x00\x00T" + + "0\x19\x80\x00\x00\x00\x00U \n\x80\x00\x00\x00\x00V\x0f\xfb\x80\x00\x00\x00\x00V\xff\xec\x80\x00\x00\x00\x00W\xef݀\x00\x00\x00\x00X\xdf\u0380\x00\x00\x00\x00YϿ\x80\x00\x00\x00\x00Z\xbf\xb0\x80\x00" + + "\x00\x00\x00[\xb8\xdc\x00\x00\x00\x00\x00\\\xa8\xcd\x00\x00\x00\x00\x00]\x98\xbe\x00\x00\x00\x00\x00^\x88\xaf\x00\x00\x00\x00\x00_x\xa0\x00\x00\x00\x00\x00`h\x91\x00\x00\x00\x00\x00aX\x82\x00\x00\x00\x00\x00b" + + "Hs\x00\x00\x00\x00\x00c8d\x00\x00\x00\x00\x00d(U\x00\x00\x00\x00\x00e\x18F\x00\x00\x00\x00\x00f\x11q\x80\x00\x00\x00\x00g\x01b\x80\x00\x00\x00\x00g\xf1S\x80\x00\x00\x00\x00h\xe1D\x80\x00" + + "\x00\x00\x00i\xd15\x80\x00\x00\x00\x00j\xc1&\x80\x00\x00\x00\x00k\xb1\x17\x80\x00\x00\x00\x00l\xa1\b\x80\x00\x00\x00\x00m\x90\xf9\x80\x00\x00\x00\x00n\x80\xea\x80\x00\x00\x00\x00opۀ\x00\x00\x00\x00p" + + "j\a\x00\x00\x00\x00\x00qY\xf8\x00\x00\x00\x00\x00rI\xe9\x00\x00\x00\x00\x00s9\xda\x00\x00\x00\x00\x00t)\xcb\x00\x00\x00\x00\x00u\x19\xbc\x00\x00\x00\x00\x00v\t\xad\x00\x00\x00\x00\x00v\xf9\x9e\x00\x00" + + "\x00\x00\x00w\xe9\x8f\x00\x00\x00\x00\x00xـ\x00\x00\x00\x00\x00y\xc9q\x00\x00\x00\x00\x00z\xb9b\x00\x00\x00\x00\x00{\xb2\x8d\x80\x00\x00\x00\x00|\xa2~\x80\x00\x00\x00\x00}\x92o\x80\x00\x00\x00\x00~" + + "\x82`\x80\x00\x00\x00\x00\u007frQ\x80\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\t\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c" + + "\xa0\x00\tLMT\x00AEDT\x00AEST\x00\x00\x00\x00\x01\x01\nAEST-10AEDT,M10.1.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00" + + "\x00\x00\xf5F\x9cP\x8f\x87~\xa8\xe4\x01\x00\x00\xe4\x01\x00\x00\x0f\x00\x1c\x00Australia/EuclaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00" + + "\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x05\x00\x00\x00\x10\x80\x00\x00\x00\x9cN\xb80\x9c\xbc2" + + "\x84\xcbTĔ\xcb\xc7i\x04̷h\x14ͧK\x04\t\x0f\xf1\x14\t\xb6\x0e\x14\x1a\x01X\x14\x1a\xa7u\x14)%R\x14)\xaf\xbf\x94Eq\xb4\x94F\x05\\\x94G#r\x14G\xeey\x14I\x03T" + + "\x14I\xce[\x14\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x04\x00\x00x\xd0\x00\x00\x00\x00\x89\x1c\x01\x04\x00\x00{\f\x00\n\x00\x00\x89\x1c\x01\x04\x00\x00{\f\x00\nL" + + "MT\x00+0945\x00+0845\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x05" + + "\x00\x00\x00\x10\xff\xff\xff\xfft\xa6\n\xb0\xff\xff\xff\xff\x9cN\xb80\xff\xff\xff\xff\x9c\xbc2\x84\xff\xff\xff\xff\xcbTĔ\xff\xff\xff\xff\xcb\xc7i\x04\xff\xff\xff\xff̷h\x14\xff\xff\xff\xffͧK\x04" + + "\x00\x00\x00\x00\t\x0f\xf1\x14\x00\x00\x00\x00\t\xb6\x0e\x14\x00\x00\x00\x00\x1a\x01X\x14\x00\x00\x00\x00\x1a\xa7u\x14\x00\x00\x00\x00)%R\x14\x00\x00\x00\x00)\xaf\xbf\x94\x00\x00\x00\x00Eq\xb4\x94\x00\x00\x00\x00" + + "F\x05\\\x94\x00\x00\x00\x00G#r\x14\x00\x00\x00\x00G\xeey\x14\x00\x00\x00\x00I\x03T\x14\x00\x00\x00\x00I\xce[\x14\x00\x00\x00\x00\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x04\x00\x00x\xd0\x00\x00\x00\x00\x89\x1c\x01\x04\x00\x00{\f\x00\n\x00\x00\x89\x1c\x01\x04\x00\x00{\f\x00\nLMT\x00+0945\x00+0845\x00\x00\x00\x00\x01\x01\n<+08" + + "45>-8:45\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPW\xd6\xfd\x19\xb1\x01\x00\x00\xb1\x01\x00\x00\x12\x00\x1c\x00Australia/BrisbaneUT\t" + + "\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00" + + "\x11\x00\x00\x00\x05\x00\x00\x00\x0e\x80\x00\x00\x00\x9cN\xa6\x9c\x9c\xbc \xf0\xcbT\xb3\x00\xcb\xc7Wp̷V\x80ͧ9pΠs\x00χ\x1bp\x03p9\x80\x04\r\x1c\x00%I\xcd\x00%\xef\xea" + + "\x00')\xaf\x00'\xcf\xcc\x00)\t\x91\x00)\xaf\xae\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x8fx\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\t\x00\x00\x9a\xb0\x01\x04\x00\x00" + + "\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x11\x00" + + "\x00\x00\x05\x00\x00\x00\x0e\xff\xff\xff\xffr\xed\x9f\b\xff\xff\xff\xff\x9cN\xa6\x9c\xff\xff\xff\xff\x9c\xbc \xf0\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7Wp\xff\xff\xff\xff̷V\x80\xff\xff\xff\xff\xcd" + + "\xa79p\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ\x1bp\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00" + + "\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x8fx\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\t\x00\x00" + + "\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\x00\x00\x00\x01\x01\nAEST-10\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc1#\xa1o\f\t\x00\x00" + + "\f\t\x00\x00\x12\x00\x1c\x00Australia/TasmaniaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x96\x00\x00\x00\x05\x00\x00\x00\x0e\x80\x00\x00\x00\x9b\xd5x\x80\x9c\xbc \xf0\xcbT\xb3\x00\xcb\xc7Wp̷" + + "V\x80ͧ9pΠs\x00χ\x1bp\xfb\u008d\x00\xfc\xb2~\x00\xfd\xc7Y\x00\xfev\xb0\x80\xff\xa7;\x00\x00V\x92\x80\x01\x87\x1d\x00\x02?\xaf\x00\x03p9\x80\x04\r\x1c\x00\x05P\x1b\x80\x05\xf6" + + "8\x80\a/\xfd\x80\a\xd6\x1a\x80\t\x0f߀\t\xb5\xfc\x80\n\xef\xc1\x80\v\x9f\x19\x00\f\xd8\xde\x00\r~\xfb\x00\x0e\xb8\xc0\x00\x0f^\xdd\x00\x10\x98\xa2\x00\x11>\xbf\x00\x12x\x84\x00\x13\x1e\xa1\x00\x14X" + + "f\x00\x14\xfe\x83\x00\x168H\x00\x17\x03O\x00\x18!d\x80\x18\xe31\x00\x1a\x01F\x80\x1a\xa7c\x80\x1b\xe1(\x80\x1c\x87E\x80\x1d\xc1\n\x80\x1eg'\x80\x1f\x97\xb2\x00 Y~\x80!\x80\u0380\"B" + + "\x9b\x00#i\xeb\x00$\"}\x00%I\xcd\x00&\x02_\x00')\xaf\x00'\xf4\xb6\x00(\xed\xe1\x80)Ԙ\x00*\xcdÀ+\xb4z\x00,\xad\xa5\x80-\x94\\\x00.\x8d\x87\x80/t>\x000m" + + "i\x801]Z\x802V\x86\x003=<\x8046h\x005\x1d\x1e\x806\x16J\x006\xfd\x00\x807\xf6,\x008\xdc\xe2\x809\xa7\xe9\x80:\xbcĀ;\xbf*\x80<\xa5\xe1\x00=\x9f\f\x80>\x85" + + "\xc3\x00?~\xee\x80@e\xa5\x00A^ЀBE\x87\x00C>\xb2\x80D.\xa3\x80E\x1e\x94\x80F\x05K\x00G\a\xb1\x00G\xf7\xa2\x00H\xe7\x93\x00Iׄ\x00J\xc7u\x00K\xb7f\x00L\xa7" + + "W\x00M\x97H\x00N\x879\x00Ow*\x00PpU\x80Q`F\x80RP7\x80S@(\x80T0\x19\x80U \n\x80V\x0f\xfb\x80V\xff\xec\x80W\xef݀X\xdf\u0380YϿ\x80Z\xbf" + + "\xb0\x80[\xb8\xdc\x00\\\xa8\xcd\x00]\x98\xbe\x00^\x88\xaf\x00_x\xa0\x00`h\x91\x00aX\x82\x00bHs\x00c8d\x00d(U\x00e\x18F\x00f\x11q\x80g\x01b\x80g\xf1S\x80h\xe1" + + "D\x80i\xd15\x80j\xc1&\x80k\xb1\x17\x80l\xa1\b\x80m\x90\xf9\x80n\x80\xea\x80opۀpj\a\x00qY\xf8\x00rI\xe9\x00s9\xda\x00t)\xcb\x00u\x19\xbc\x00v\t\xad\x00v\xf9" + + "\x9e\x00w\xe9\x8f\x00xـ\x00y\xc9q\x00z\xb9b\x00{\xb2\x8d\x80|\xa2~\x80}\x92o\x80~\x82`\x80\u007frQ\x80\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x8a\x1c\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\x9a\xb0\x01\t\x00\x00\x9a\xb0\x01\t\x00\x00\x8c\xa0\x00\x04LMT\x00AEST\x00AEDT\x00\x00\x00\x00\x01\x01TZi" + + "f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x96\x00\x00\x00\x05\x00\x00\x00\x0e\xff\xff\xff\xfft.\x00\xe4\xff\xff\xff\xff\x9b\xd5x\x80\xff\xff\xff" + + "\xff\x9c\xbc \xf0\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7Wp\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧ9p\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ\x1bp\xff\xff\xff\xff\xfb\u008d" + + "\x00\xff\xff\xff\xff\xfc\xb2~\x00\xff\xff\xff\xff\xfd\xc7Y\x00\xff\xff\xff\xff\xfev\xb0\x80\xff\xff\xff\xff\xff\xa7;\x00\x00\x00\x00\x00\x00V\x92\x80\x00\x00\x00\x00\x01\x87\x1d\x00\x00\x00\x00\x00\x02?\xaf\x00\x00\x00\x00" + + "\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc" + + "\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00" + + "\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x03O\x00\x00\x00\x00\x00\x18!d" + + "\x80\x00\x00\x00\x00\x18\xe31\x00\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1eg'\x80\x00\x00\x00" + + "\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_" + + "\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xed\xe1\x80\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*\xcdÀ\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xad\xa5\x80\x00\x00\x00" + + "\x00-\x94\\\x00\x00\x00\x00\x00.\x8d\x87\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000mi\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002V\x86\x00\x00\x00\x00\x003=<\x80\x00\x00\x00\x0046h" + + "\x00\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\x16J\x00\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x007\xf6,\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00" + + "\x00;\xbf*\x80\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\x9f\f\x80\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?~\xee\x80\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A^Ѐ\x00\x00\x00\x00BE\x87" + + "\x00\x00\x00\x00\x00C>\xb2\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00E\x1e\x94\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G\a\xb1\x00\x00\x00\x00\x00G\xf7\xa2\x00\x00\x00\x00\x00H\xe7\x93\x00\x00\x00\x00" + + "\x00Iׄ\x00\x00\x00\x00\x00J\xc7u\x00\x00\x00\x00\x00K\xb7f\x00\x00\x00\x00\x00L\xa7W\x00\x00\x00\x00\x00M\x97H\x00\x00\x00\x00\x00N\x879\x00\x00\x00\x00\x00Ow*\x00\x00\x00\x00\x00PpU" + + "\x80\x00\x00\x00\x00Q`F\x80\x00\x00\x00\x00RP7\x80\x00\x00\x00\x00S@(\x80\x00\x00\x00\x00T0\x19\x80\x00\x00\x00\x00U \n\x80\x00\x00\x00\x00V\x0f\xfb\x80\x00\x00\x00\x00V\xff\xec\x80\x00\x00\x00" + + "\x00W\xef݀\x00\x00\x00\x00X\xdf\u0380\x00\x00\x00\x00YϿ\x80\x00\x00\x00\x00Z\xbf\xb0\x80\x00\x00\x00\x00[\xb8\xdc\x00\x00\x00\x00\x00\\\xa8\xcd\x00\x00\x00\x00\x00]\x98\xbe\x00\x00\x00\x00\x00^\x88\xaf" + + "\x00\x00\x00\x00\x00_x\xa0\x00\x00\x00\x00\x00`h\x91\x00\x00\x00\x00\x00aX\x82\x00\x00\x00\x00\x00bHs\x00\x00\x00\x00\x00c8d\x00\x00\x00\x00\x00d(U\x00\x00\x00\x00\x00e\x18F\x00\x00\x00\x00" + + "\x00f\x11q\x80\x00\x00\x00\x00g\x01b\x80\x00\x00\x00\x00g\xf1S\x80\x00\x00\x00\x00h\xe1D\x80\x00\x00\x00\x00i\xd15\x80\x00\x00\x00\x00j\xc1&\x80\x00\x00\x00\x00k\xb1\x17\x80\x00\x00\x00\x00l\xa1\b" + + "\x80\x00\x00\x00\x00m\x90\xf9\x80\x00\x00\x00\x00n\x80\xea\x80\x00\x00\x00\x00opۀ\x00\x00\x00\x00pj\a\x00\x00\x00\x00\x00qY\xf8\x00\x00\x00\x00\x00rI\xe9\x00\x00\x00\x00\x00s9\xda\x00\x00\x00\x00" + + "\x00t)\xcb\x00\x00\x00\x00\x00u\x19\xbc\x00\x00\x00\x00\x00v\t\xad\x00\x00\x00\x00\x00v\xf9\x9e\x00\x00\x00\x00\x00w\xe9\x8f\x00\x00\x00\x00\x00xـ\x00\x00\x00\x00\x00y\xc9q\x00\x00\x00\x00\x00z\xb9b" + + "\x00\x00\x00\x00\x00{\xb2\x8d\x80\x00\x00\x00\x00|\xa2~\x80\x00\x00\x00\x00}\x92o\x80\x00\x00\x00\x00~\x82`\x80\x00\x00\x00\x00\u007frQ\x80\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x8a\x1c\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\x9a\xb0\x01\t\x00\x00\x9a\xb0\x01\t\x00\x00\x8c\xa0\x00\x04LMT\x00AEST\x00AEDT\x00\x00\x00\x00\x01\x01" + + "\nAEST-10AEDT,M10.1.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc1#\xa1o\f\t\x00\x00\f\t\x00\x00\x10\x00\x1c\x00" + + "Australia/HobartUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x96\x00\x00\x00\x05\x00\x00\x00\x0e\x80\x00\x00\x00\x9b\xd5x\x80\x9c\xbc \xf0\xcbT\xb3\x00\xcb\xc7Wp̷V\x80ͧ9pΠs\x00" + + "χ\x1bp\xfb\u008d\x00\xfc\xb2~\x00\xfd\xc7Y\x00\xfev\xb0\x80\xff\xa7;\x00\x00V\x92\x80\x01\x87\x1d\x00\x02?\xaf\x00\x03p9\x80\x04\r\x1c\x00\x05P\x1b\x80\x05\xf68\x80\a/\xfd\x80\a\xd6\x1a\x80" + + "\t\x0f߀\t\xb5\xfc\x80\n\xef\xc1\x80\v\x9f\x19\x00\f\xd8\xde\x00\r~\xfb\x00\x0e\xb8\xc0\x00\x0f^\xdd\x00\x10\x98\xa2\x00\x11>\xbf\x00\x12x\x84\x00\x13\x1e\xa1\x00\x14Xf\x00\x14\xfe\x83\x00\x168H\x00" + + "\x17\x03O\x00\x18!d\x80\x18\xe31\x00\x1a\x01F\x80\x1a\xa7c\x80\x1b\xe1(\x80\x1c\x87E\x80\x1d\xc1\n\x80\x1eg'\x80\x1f\x97\xb2\x00 Y~\x80!\x80\u0380\"B\x9b\x00#i\xeb\x00$\"}\x00" + + "%I\xcd\x00&\x02_\x00')\xaf\x00'\xf4\xb6\x00(\xed\xe1\x80)Ԙ\x00*\xcdÀ+\xb4z\x00,\xad\xa5\x80-\x94\\\x00.\x8d\x87\x80/t>\x000mi\x801]Z\x802V\x86\x00" + + "3=<\x8046h\x005\x1d\x1e\x806\x16J\x006\xfd\x00\x807\xf6,\x008\xdc\xe2\x809\xa7\xe9\x80:\xbcĀ;\xbf*\x80<\xa5\xe1\x00=\x9f\f\x80>\x85\xc3\x00?~\xee\x80@e\xa5\x00" + + "A^ЀBE\x87\x00C>\xb2\x80D.\xa3\x80E\x1e\x94\x80F\x05K\x00G\a\xb1\x00G\xf7\xa2\x00H\xe7\x93\x00Iׄ\x00J\xc7u\x00K\xb7f\x00L\xa7W\x00M\x97H\x00N\x879\x00" + + "Ow*\x00PpU\x80Q`F\x80RP7\x80S@(\x80T0\x19\x80U \n\x80V\x0f\xfb\x80V\xff\xec\x80W\xef݀X\xdf\u0380YϿ\x80Z\xbf\xb0\x80[\xb8\xdc\x00\\\xa8\xcd\x00" + + "]\x98\xbe\x00^\x88\xaf\x00_x\xa0\x00`h\x91\x00aX\x82\x00bHs\x00c8d\x00d(U\x00e\x18F\x00f\x11q\x80g\x01b\x80g\xf1S\x80h\xe1D\x80i\xd15\x80j\xc1&\x80" + + "k\xb1\x17\x80l\xa1\b\x80m\x90\xf9\x80n\x80\xea\x80opۀpj\a\x00qY\xf8\x00rI\xe9\x00s9\xda\x00t)\xcb\x00u\x19\xbc\x00v\t\xad\x00v\xf9\x9e\x00w\xe9\x8f\x00xـ\x00" + + "y\xc9q\x00z\xb9b\x00{\xb2\x8d\x80|\xa2~\x80}\x92o\x80~\x82`\x80\u007frQ\x80\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00" + + "\x8a\x1c\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\x9a\xb0\x01\t\x00\x00\x9a\xb0\x01\t\x00\x00\x8c\xa0\x00\x04LMT\x00AEST\x00AEDT\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x96\x00\x00\x00\x05\x00\x00\x00\x0e\xff\xff\xff\xfft.\x00\xe4\xff\xff\xff\xff\x9b\xd5x\x80\xff\xff\xff\xff\x9c\xbc \xf0\xff\xff\xff\xff\xcb" + + "T\xb3\x00\xff\xff\xff\xff\xcb\xc7Wp\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧ9p\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ\x1bp\xff\xff\xff\xff\xfb\u008d\x00\xff\xff\xff\xff\xfc\xb2~\x00\xff" + + "\xff\xff\xff\xfd\xc7Y\x00\xff\xff\xff\xff\xfev\xb0\x80\xff\xff\xff\xff\xff\xa7;\x00\x00\x00\x00\x00\x00V\x92\x80\x00\x00\x00\x00\x01\x87\x1d\x00\x00\x00\x00\x00\x02?\xaf\x00\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04" + + "\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00" + + "\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12" + + "x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x03O\x00\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18\xe31\x00\x00" + + "\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1eg'\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 " + + "Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00" + + "\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xed\xe1\x80\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*\xcdÀ\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xad\xa5\x80\x00\x00\x00\x00-\x94\\\x00\x00\x00\x00\x00." + + "\x8d\x87\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000mi\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002V\x86\x00\x00\x00\x00\x003=<\x80\x00\x00\x00\x0046h\x00\x00\x00\x00\x005\x1d\x1e\x80\x00" + + "\x00\x00\x006\x16J\x00\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x007\xf6,\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xbf*\x80\x00\x00\x00\x00<" + + "\xa5\xe1\x00\x00\x00\x00\x00=\x9f\f\x80\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?~\xee\x80\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A^Ѐ\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00C>\xb2\x80\x00" + + "\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00E\x1e\x94\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G\a\xb1\x00\x00\x00\x00\x00G\xf7\xa2\x00\x00\x00\x00\x00H\xe7\x93\x00\x00\x00\x00\x00Iׄ\x00\x00\x00\x00\x00J" + + "\xc7u\x00\x00\x00\x00\x00K\xb7f\x00\x00\x00\x00\x00L\xa7W\x00\x00\x00\x00\x00M\x97H\x00\x00\x00\x00\x00N\x879\x00\x00\x00\x00\x00Ow*\x00\x00\x00\x00\x00PpU\x80\x00\x00\x00\x00Q`F\x80\x00" + + "\x00\x00\x00RP7\x80\x00\x00\x00\x00S@(\x80\x00\x00\x00\x00T0\x19\x80\x00\x00\x00\x00U \n\x80\x00\x00\x00\x00V\x0f\xfb\x80\x00\x00\x00\x00V\xff\xec\x80\x00\x00\x00\x00W\xef݀\x00\x00\x00\x00X" + + "\xdf\u0380\x00\x00\x00\x00YϿ\x80\x00\x00\x00\x00Z\xbf\xb0\x80\x00\x00\x00\x00[\xb8\xdc\x00\x00\x00\x00\x00\\\xa8\xcd\x00\x00\x00\x00\x00]\x98\xbe\x00\x00\x00\x00\x00^\x88\xaf\x00\x00\x00\x00\x00_x\xa0\x00\x00" + + "\x00\x00\x00`h\x91\x00\x00\x00\x00\x00aX\x82\x00\x00\x00\x00\x00bHs\x00\x00\x00\x00\x00c8d\x00\x00\x00\x00\x00d(U\x00\x00\x00\x00\x00e\x18F\x00\x00\x00\x00\x00f\x11q\x80\x00\x00\x00\x00g" + + "\x01b\x80\x00\x00\x00\x00g\xf1S\x80\x00\x00\x00\x00h\xe1D\x80\x00\x00\x00\x00i\xd15\x80\x00\x00\x00\x00j\xc1&\x80\x00\x00\x00\x00k\xb1\x17\x80\x00\x00\x00\x00l\xa1\b\x80\x00\x00\x00\x00m\x90\xf9\x80\x00" + + "\x00\x00\x00n\x80\xea\x80\x00\x00\x00\x00opۀ\x00\x00\x00\x00pj\a\x00\x00\x00\x00\x00qY\xf8\x00\x00\x00\x00\x00rI\xe9\x00\x00\x00\x00\x00s9\xda\x00\x00\x00\x00\x00t)\xcb\x00\x00\x00\x00\x00u" + + "\x19\xbc\x00\x00\x00\x00\x00v\t\xad\x00\x00\x00\x00\x00v\xf9\x9e\x00\x00\x00\x00\x00w\xe9\x8f\x00\x00\x00\x00\x00xـ\x00\x00\x00\x00\x00y\xc9q\x00\x00\x00\x00\x00z\xb9b\x00\x00\x00\x00\x00{\xb2\x8d\x80\x00" + + "\x00\x00\x00|\xa2~\x80\x00\x00\x00\x00}\x92o\x80\x00\x00\x00\x00~\x82`\x80\x00\x00\x00\x00\u007frQ\x80\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x00\x00\x8a\x1c\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\x9a\xb0\x01\t\x00\x00\x9a\xb0\x01\t\x00\x00\x8c\xa0\x00\x04LMT\x00AEST\x00AEDT\x00\x00\x00\x00\x01\x01\nAEST-10AE" + + "DT,M10.1.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x16I\x166\xcc\x01\x00\x00\xcc\x01\x00\x00\x0f\x00\x1c\x00Australia/" + + "PerthUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x05\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x05\x00\x00\x00\x0e\x80\x00\x00\x00\x9cN¼\x9c\xbc=\x10\xcbT\xcf \xcb\xc7s\x90̷r\xa0ͧU\x90\t\x0f\xfb\xa0\t\xb6\x18\xa0\x1a\x01b\xa0\x1a\xa7\u007f" + + "\xa0)%\\\xa0)\xaf\xca Eq\xbf F\x05g G#|\xa0G\ue0e0I\x03^\xa0I\xcee\xa0\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00l\x9c\x00\x00\x00\x00" + + "~\x90\x01\x04\x00\x00p\x80\x00\t\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\tLMT\x00AWDT\x00AWST\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x05\x00\x00\x00\x0e\xff\xff\xff\xfft\xa6\x16\xe4\xff\xff\xff\xff\x9cN¼\xff\xff\xff\xff\x9c\xbc=\x10\xff\xff\xff\xff\xcbT\xcf \xff\xff\xff" + + "\xff\xcb\xc7s\x90\xff\xff\xff\xff̷r\xa0\xff\xff\xff\xffͧU\x90\x00\x00\x00\x00\t\x0f\xfb\xa0\x00\x00\x00\x00\t\xb6\x18\xa0\x00\x00\x00\x00\x1a\x01b\xa0\x00\x00\x00\x00\x1a\xa7\u007f\xa0\x00\x00\x00\x00)%\\" + + "\xa0\x00\x00\x00\x00)\xaf\xca \x00\x00\x00\x00Eq\xbf \x00\x00\x00\x00F\x05g \x00\x00\x00\x00G#|\xa0\x00\x00\x00\x00G\ue0e0\x00\x00\x00\x00I\x03^\xa0\x00\x00\x00\x00I\xcee\xa0\x02\x01\x02" + + "\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00l\x9c\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\t\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\tLMT\x00AWDT\x00AWST\x00" + + "\x00\x00\x00\x01\x01\nAWST-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPJ\x04\x18\x99\xae\b\x00\x00\xae\b\x00\x00\x0f\x00\x1c\x00Australia/SouthUT" + + "\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00" + + "\x00\x8e\x00\x00\x00\x05\x00\x00\x00\x0e\x80\x00\x00\x00\x9cN\xad\xa4\x9c\xbc'\xf8\xcbT\xba\b\xcb\xc7^x̷]\x88ͧ@xΠz\bχ\"x\x03p@\x88\x04\r#\b\x05P\"\x88\x05\xf6" + + "?\x88\a0\x04\x88\a\xd6!\x88\t\x0f\xe6\x88\t\xb6\x03\x88\n\xefȈ\v\x9f \b\f\xd8\xe5\b\r\u007f\x02\b\x0e\xb8\xc7\b\x0f^\xe4\b\x10\x98\xa9\b\x11>\xc6\b\x12x\x8b\b\x13\x1e\xa8\b\x14X" + + "m\b\x14\xfe\x8a\b\x168O\b\x16禈\x18!k\x88\x18Lj\x88\x1a\x01M\x88\x1a\xa7j\x88\x1b\xe1/\x88\x1c\x87L\x88\x1d\xc1\x11\x88\x1ey\xa3\x88\x1f\x97\xb9\b Y\x85\x88!\x80Ո\"B" + + "\xa2\b#i\xf2\b$\"\x84\b%I\xd4\b&\x02f\b')\xb6\b'\xcf\xd3\b)\t\x98\b)\xcbd\x88*\xe9z\b+\x98ш,Җ\x88-\x8b(\x88.\xb2x\x88/tE\b0\x92" + + "Z\x881]a\x882r<\x883=C\x884R\x1e\x885\x1d%\x8862\x00\x886\xfd\a\x888\x1b\x1d\b8\xdc\xe9\x889\xfa\xff\b:\xbcˈ;\xda\xe1\b<\xa5\xe8\b=\xba\xc3\b>\x85" + + "\xca\b?\x9a\xa5\b@e\xac\bA\x83\xc1\x88BE\x8e\bCc\xa3\x88D.\xaa\x88EC\x85\x88F\x05R\bG#g\x88G\xf7\xa9\bH\xe7\x9a\bI\u05cb\bJ\xc7|\bK\xb7m\bL\xa7" + + "^\bM\x97O\bN\x87@\bOw1\bPp\\\x88Q`M\x88RP>\x88S@/\x88T0 \x88U \x11\x88V\x10\x02\x88V\xff\xf3\x88W\xef\xe4\x88X\xdfՈY\xcfƈZ\xbf" + + "\xb7\x88[\xb8\xe3\b\\\xa8\xd4\b]\x98\xc5\b^\x88\xb6\b_x\xa7\b`h\x98\baX\x89\bbHz\bc8k\bd(\\\be\x18M\bf\x11x\x88g\x01i\x88g\xf1Z\x88h\xe1" + + "K\x88i\xd1<\x88j\xc1-\x88k\xb1\x1e\x88l\xa1\x0f\x88m\x91\x00\x88n\x80\xf1\x88op\xe2\x88pj\x0e\bqY\xff\brI\xf0\bs9\xe1\bt)\xd2\bu\x19\xc3\bv\t\xb4\bv\xf9" + + "\xa5\bw\xe9\x96\bxه\by\xc9x\bz\xb9i\b{\xb2\x94\x88|\xa2\x85\x88}\x92v\x88~\x82g\x88\u007frX\x88\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x00\x00\x81\xec\x00\x00\x00\x00\x93\xa8\x01\x04\x00\x00\x85\x98\x00\t\x00\x00\x93\xa8\x01\x04\x00\x00\x85\x98\x00\tLMT\x00ACDT\x00ACST\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x8f\x00\x00\x00\x06\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x8b\x14\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cN\xad\xa4\xff\xff\xff" + + "\xff\x9c\xbc'\xf8\xff\xff\xff\xff\xcbT\xba\b\xff\xff\xff\xff\xcb\xc7^x\xff\xff\xff\xff̷]\x88\xff\xff\xff\xffͧ@x\xff\xff\xff\xffΠz\b\xff\xff\xff\xffχ\"x\x00\x00\x00\x00\x03p@" + + "\x88\x00\x00\x00\x00\x04\r#\b\x00\x00\x00\x00\x05P\"\x88\x00\x00\x00\x00\x05\xf6?\x88\x00\x00\x00\x00\a0\x04\x88\x00\x00\x00\x00\a\xd6!\x88\x00\x00\x00\x00\t\x0f\xe6\x88\x00\x00\x00\x00\t\xb6\x03\x88\x00\x00\x00" + + "\x00\n\xefȈ\x00\x00\x00\x00\v\x9f \b\x00\x00\x00\x00\f\xd8\xe5\b\x00\x00\x00\x00\r\u007f\x02\b\x00\x00\x00\x00\x0e\xb8\xc7\b\x00\x00\x00\x00\x0f^\xe4\b\x00\x00\x00\x00\x10\x98\xa9\b\x00\x00\x00\x00\x11>\xc6" + + "\b\x00\x00\x00\x00\x12x\x8b\b\x00\x00\x00\x00\x13\x1e\xa8\b\x00\x00\x00\x00\x14Xm\b\x00\x00\x00\x00\x14\xfe\x8a\b\x00\x00\x00\x00\x168O\b\x00\x00\x00\x00\x16禈\x00\x00\x00\x00\x18!k\x88\x00\x00\x00" + + "\x00\x18Lj\x88\x00\x00\x00\x00\x1a\x01M\x88\x00\x00\x00\x00\x1a\xa7j\x88\x00\x00\x00\x00\x1b\xe1/\x88\x00\x00\x00\x00\x1c\x87L\x88\x00\x00\x00\x00\x1d\xc1\x11\x88\x00\x00\x00\x00\x1ey\xa3\x88\x00\x00\x00\x00\x1f\x97\xb9" + + "\b\x00\x00\x00\x00 Y\x85\x88\x00\x00\x00\x00!\x80Ո\x00\x00\x00\x00\"B\xa2\b\x00\x00\x00\x00#i\xf2\b\x00\x00\x00\x00$\"\x84\b\x00\x00\x00\x00%I\xd4\b\x00\x00\x00\x00&\x02f\b\x00\x00\x00" + + "\x00')\xb6\b\x00\x00\x00\x00'\xcf\xd3\b\x00\x00\x00\x00)\t\x98\b\x00\x00\x00\x00)\xcbd\x88\x00\x00\x00\x00*\xe9z\b\x00\x00\x00\x00+\x98ш\x00\x00\x00\x00,Җ\x88\x00\x00\x00\x00-\x8b(" + + "\x88\x00\x00\x00\x00.\xb2x\x88\x00\x00\x00\x00/tE\b\x00\x00\x00\x000\x92Z\x88\x00\x00\x00\x001]a\x88\x00\x00\x00\x002r<\x88\x00\x00\x00\x003=C\x88\x00\x00\x00\x004R\x1e\x88\x00\x00\x00" + + "\x005\x1d%\x88\x00\x00\x00\x0062\x00\x88\x00\x00\x00\x006\xfd\a\x88\x00\x00\x00\x008\x1b\x1d\b\x00\x00\x00\x008\xdc\xe9\x88\x00\x00\x00\x009\xfa\xff\b\x00\x00\x00\x00:\xbcˈ\x00\x00\x00\x00;\xda\xe1" + + "\b\x00\x00\x00\x00<\xa5\xe8\b\x00\x00\x00\x00=\xba\xc3\b\x00\x00\x00\x00>\x85\xca\b\x00\x00\x00\x00?\x9a\xa5\b\x00\x00\x00\x00@e\xac\b\x00\x00\x00\x00A\x83\xc1\x88\x00\x00\x00\x00BE\x8e\b\x00\x00\x00" + + "\x00Cc\xa3\x88\x00\x00\x00\x00D.\xaa\x88\x00\x00\x00\x00EC\x85\x88\x00\x00\x00\x00F\x05R\b\x00\x00\x00\x00G#g\x88\x00\x00\x00\x00G\xf7\xa9\b\x00\x00\x00\x00H\xe7\x9a\b\x00\x00\x00\x00I\u05cb" + + "\b\x00\x00\x00\x00J\xc7|\b\x00\x00\x00\x00K\xb7m\b\x00\x00\x00\x00L\xa7^\b\x00\x00\x00\x00M\x97O\b\x00\x00\x00\x00N\x87@\b\x00\x00\x00\x00Ow1\b\x00\x00\x00\x00Pp\\\x88\x00\x00\x00" + + "\x00Q`M\x88\x00\x00\x00\x00RP>\x88\x00\x00\x00\x00S@/\x88\x00\x00\x00\x00T0 \x88\x00\x00\x00\x00U \x11\x88\x00\x00\x00\x00V\x10\x02\x88\x00\x00\x00\x00V\xff\xf3\x88\x00\x00\x00\x00W\xef\xe4" + + "\x88\x00\x00\x00\x00X\xdfՈ\x00\x00\x00\x00Y\xcfƈ\x00\x00\x00\x00Z\xbf\xb7\x88\x00\x00\x00\x00[\xb8\xe3\b\x00\x00\x00\x00\\\xa8\xd4\b\x00\x00\x00\x00]\x98\xc5\b\x00\x00\x00\x00^\x88\xb6\b\x00\x00\x00" + + "\x00_x\xa7\b\x00\x00\x00\x00`h\x98\b\x00\x00\x00\x00aX\x89\b\x00\x00\x00\x00bHz\b\x00\x00\x00\x00c8k\b\x00\x00\x00\x00d(\\\b\x00\x00\x00\x00e\x18M\b\x00\x00\x00\x00f\x11x" + + "\x88\x00\x00\x00\x00g\x01i\x88\x00\x00\x00\x00g\xf1Z\x88\x00\x00\x00\x00h\xe1K\x88\x00\x00\x00\x00i\xd1<\x88\x00\x00\x00\x00j\xc1-\x88\x00\x00\x00\x00k\xb1\x1e\x88\x00\x00\x00\x00l\xa1\x0f\x88\x00\x00\x00" + + "\x00m\x91\x00\x88\x00\x00\x00\x00n\x80\xf1\x88\x00\x00\x00\x00op\xe2\x88\x00\x00\x00\x00pj\x0e\b\x00\x00\x00\x00qY\xff\b\x00\x00\x00\x00rI\xf0\b\x00\x00\x00\x00s9\xe1\b\x00\x00\x00\x00t)\xd2" + + "\b\x00\x00\x00\x00u\x19\xc3\b\x00\x00\x00\x00v\t\xb4\b\x00\x00\x00\x00v\xf9\xa5\b\x00\x00\x00\x00w\xe9\x96\b\x00\x00\x00\x00xه\b\x00\x00\x00\x00y\xc9x\b\x00\x00\x00\x00z\xb9i\b\x00\x00\x00" + + "\x00{\xb2\x94\x88\x00\x00\x00\x00|\xa2\x85\x88\x00\x00\x00\x00}\x92v\x88\x00\x00\x00\x00~\x82g\x88\x00\x00\x00\x00\u007frX\x88\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x00\x00\x81\xec\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x93\xa8\x01\t\x00\x00\x85\x98\x00\x04\x00\x00\x93\xa8\x01\t\x00\x00\x85\x98\x00\x04LMT\x00ACST\x00ACDT\x00\x00\x00\x00\x00\x01\x01\nACS" + + "T-9:30ACDT,M10.1.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xac\x8a\\\xb6\xe9\x01\x00\x00\xe9\x01\x00\x00\x12\x00\x1c\x00Au" + + "stralia/LindemanUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x05\x00\x00\x00\x0e\x80\x00\x00\x00\x9cN\xa6\x9c\x9c\xbc \xf0\xcbT\xb3\x00\xcb\xc7Wp̷V\x80ͧ9pΠs\x00" + + "χ\x1bp\x03p9\x80\x04\r\x1c\x00%I\xcd\x00%\xef\xea\x00')\xaf\x00'\xcf\xcc\x00)\t\x91\x00)\xaf\xae\x00*\xe9s\x00+\x98ʀ,ҏ\x80-x\xac\x80\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x8b\xac\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\t\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\x00\x00\x00" + + "\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x05\x00\x00\x00\x0e\xff\xff\xff\xffr\xed\xa2\xd4\xff\xff\xff\xff\x9cN" + + "\xa6\x9c\xff\xff\xff\xff\x9c\xbc \xf0\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7Wp\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧ9p\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ\x1bp\x00\x00" + + "\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf" + + "\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00\x00\x00,ҏ\x80\x00\x00\x00\x00-x\xac\x80\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x8b\xac\x00" + + "\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\t\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\x00\x00\x00\x01\x01\nAEST-10\nPK\x03\x04\n\x00\x00" + + "\x00\x00\x00\xf5F\x9cP(\xd2\xc7k0\x01\x00\x000\x01\x00\x00\x10\x00\x1c\x00Australia/DarwinUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01" + + "\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x03\x00\x00\x00\x0e\x80\x00\x00\x00\x9cN\xad\xa4\x9c" + + "\xbc'\xf8\xcbT\xba\b\xcb\xc7^x̷]\x88ͧ@xΠz\bχ\"x\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00z\xa8\x00\x00\x00\x00\x93\xa8\x01\x04\x00\x00\x85\x98\x00\tLMT\x00AC" + + "DT\x00ACST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x04\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x92X" + + "\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cN\xad\xa4\xff\xff\xff\xff\x9c\xbc'\xf8\xff\xff\xff\xff\xcbT\xba\b\xff\xff\xff\xff\xcb\xc7^x\xff\xff\xff\xff̷]\x88\xff\xff\xff\xffͧ@x\xff\xff\xff\xff" + + "Πz\b\xff\xff\xff\xffχ\"x\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00z\xa8\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x93\xa8\x01\t\x00\x00\x85\x98\x00\x04LMT\x00ACST\x00ACDT\x00" + + "\nACST-9:30\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x16I\x166\xcc\x01\x00\x00\xcc\x01\x00\x00\x0e\x00\x1c\x00Australia/WestUT\t\x00\x03" + + "nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x13\x00" + + "\x00\x00\x05\x00\x00\x00\x0e\x80\x00\x00\x00\x9cN¼\x9c\xbc=\x10\xcbT\xcf \xcb\xc7s\x90̷r\xa0ͧU\x90\t\x0f\xfb\xa0\t\xb6\x18\xa0\x1a\x01b\xa0\x1a\xa7\u007f\xa0)%\\\xa0)\xaf\xca E" + + "q\xbf F\x05g G#|\xa0G\ue0e0I\x03^\xa0I\xcee\xa0\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00l\x9c\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\t" + + "\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\tLMT\x00AWDT\x00AWST\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00" + + "\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x05\x00\x00\x00\x0e\xff\xff\xff\xfft\xa6\x16\xe4\xff\xff\xff\xff\x9cN¼\xff\xff\xff\xff\x9c\xbc=\x10\xff\xff\xff\xff\xcbT\xcf \xff\xff\xff\xff\xcb\xc7s\x90\xff\xff\xff\xff\xcc" + + "\xb7r\xa0\xff\xff\xff\xffͧU\x90\x00\x00\x00\x00\t\x0f\xfb\xa0\x00\x00\x00\x00\t\xb6\x18\xa0\x00\x00\x00\x00\x1a\x01b\xa0\x00\x00\x00\x00\x1a\xa7\u007f\xa0\x00\x00\x00\x00)%\\\xa0\x00\x00\x00\x00)\xaf\xca \x00" + + "\x00\x00\x00Eq\xbf \x00\x00\x00\x00F\x05g \x00\x00\x00\x00G#|\xa0\x00\x00\x00\x00G\ue0e0\x00\x00\x00\x00I\x03^\xa0\x00\x00\x00\x00I\xcee\xa0\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x00\x00l\x9c\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\t\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\tLMT\x00AWDT\x00AWST\x00\x00\x00\x00\x01\x01\nAWST" + + "-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP!v\xa5*D\a\x00\x00D\a\x00\x00\r\x00\x1c\x00Australia/LHIUT\t\x00\x03nӧ^nӧ^u" + + "x\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\x00\x00\x00\x05\x00\x00\x00\x19\x80\x00" + + "\x00\x00\x14\xfef\xe0\x168@\xf8\x16\xe7\x8ah\x18!]x\x18\xc7lh\x1a\x01?x\x1a\xa7Nh\x1b\xe1!x\x1c\x870h\x1d\xc1\x03x\x1ey\x8ep\x1f\x97\xaa\xf8 Ypp!\x80\xc7x\"B" + + "\x8c\xf0#i\xe3\xf8$\"n\xf0%I\xc5\xf8%\xef\xdb\xf0')\xa7\xf8'Ͻ\xf0)\t\x89\xf8)\xaf\x9f\xf0*\xe9k\xf8+\x98\xbcp,҈x-x\x9ep.\xb2jx/X\x80p0\x92" + + "Lx1]Lp2r.x3=.p4R\x10x5\x1d\x10p61\xf2x6\xfc\xf2p8\x1b\x0e\xf88\xdc\xd4p9\xa7\xe2x:\xbc\xb6p;\xda\xd2\xf8<\xa5\xd2\xf0=\xba\xb4\xf8>\x85" + + "\xb4\xf0?\x9a\x96\xf8@e\x96\xf0A\x83\xb3xBEx\xf0Cc\x95xD.\x95pECwxF\x05<\xf0G#YxG\xf7\x93\xf0H\xe7\x8b\xf8I\xd7u\xf0J\xc7m\xf8K\xb7W\xf0L\xa7" + + "O\xf8M\x979\xf0N\x871\xf8Ow\x1b\xf0PpNxQ`8pRP0xS@\x1apT0\x12xU\x1f\xfcpV\x0f\xf4xV\xff\xdepW\xef\xd6xX\xdf\xc0pYϸxZ\xbf" + + "\xa2p[\xb8\xd4\xf8\\\xa8\xbe\xf0]\x98\xb6\xf8^\x88\xa0\xf0_x\x98\xf8`h\x82\xf0aXz\xf8bHd\xf0c8\\\xf8d(F\xf0e\x18>\xf8f\x11cpg\x01[xg\xf1Eph\xe1" + + "=xi\xd1'pj\xc1\x1fxk\xb1\tpl\xa1\x01xm\x90\xebpn\x80\xe3xop\xcdppi\xff\xf8qY\xe9\xf0rI\xe1\xf8s9\xcb\xf0t)\xc3\xf8u\x19\xad\xf0v\t\xa5\xf8v\xf9" + + "\x8f\xf0w\xe9\x87\xf8x\xd9q\xf0y\xc9i\xf8z\xb9S\xf0{\xb2\x86x|\xa2pp}\x92hx~\x82Rp\u007frJx\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x04\x00\x00\x95$\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\xa1\xb8\x01\t\x00\x00\x93\xa8" + + "\x00\x0f\x00\x00\x9a\xb0\x01\x15LMT\x00AEST\x00+1130\x00+1030\x00+11\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00t\x00\x00\x00\x05\x00\x00\x00\x19\xff\xff\xff\xffs\x16w\xdc\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168@\xf8\x00\x00\x00\x00\x16\xe7\x8ah\x00\x00\x00\x00\x18!]x\x00\x00\x00" + + "\x00\x18\xc7lh\x00\x00\x00\x00\x1a\x01?x\x00\x00\x00\x00\x1a\xa7Nh\x00\x00\x00\x00\x1b\xe1!x\x00\x00\x00\x00\x1c\x870h\x00\x00\x00\x00\x1d\xc1\x03x\x00\x00\x00\x00\x1ey\x8ep\x00\x00\x00\x00\x1f\x97\xaa" + + "\xf8\x00\x00\x00\x00 Ypp\x00\x00\x00\x00!\x80\xc7x\x00\x00\x00\x00\"B\x8c\xf0\x00\x00\x00\x00#i\xe3\xf8\x00\x00\x00\x00$\"n\xf0\x00\x00\x00\x00%I\xc5\xf8\x00\x00\x00\x00%\xef\xdb\xf0\x00\x00\x00" + + "\x00')\xa7\xf8\x00\x00\x00\x00'Ͻ\xf0\x00\x00\x00\x00)\t\x89\xf8\x00\x00\x00\x00)\xaf\x9f\xf0\x00\x00\x00\x00*\xe9k\xf8\x00\x00\x00\x00+\x98\xbcp\x00\x00\x00\x00,҈x\x00\x00\x00\x00-x\x9e" + + "p\x00\x00\x00\x00.\xb2jx\x00\x00\x00\x00/X\x80p\x00\x00\x00\x000\x92Lx\x00\x00\x00\x001]Lp\x00\x00\x00\x002r.x\x00\x00\x00\x003=.p\x00\x00\x00\x004R\x10x\x00\x00\x00" + + "\x005\x1d\x10p\x00\x00\x00\x0061\xf2x\x00\x00\x00\x006\xfc\xf2p\x00\x00\x00\x008\x1b\x0e\xf8\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xa7\xe2x\x00\x00\x00\x00:\xbc\xb6p\x00\x00\x00\x00;\xda\xd2" + + "\xf8\x00\x00\x00\x00<\xa5\xd2\xf0\x00\x00\x00\x00=\xba\xb4\xf8\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x96\xf8\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xb3x\x00\x00\x00\x00BEx\xf0\x00\x00\x00" + + "\x00Cc\x95x\x00\x00\x00\x00D.\x95p\x00\x00\x00\x00ECwx\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Yx\x00\x00\x00\x00G\xf7\x93\xf0\x00\x00\x00\x00H\xe7\x8b\xf8\x00\x00\x00\x00I\xd7u" + + "\xf0\x00\x00\x00\x00J\xc7m\xf8\x00\x00\x00\x00K\xb7W\xf0\x00\x00\x00\x00L\xa7O\xf8\x00\x00\x00\x00M\x979\xf0\x00\x00\x00\x00N\x871\xf8\x00\x00\x00\x00Ow\x1b\xf0\x00\x00\x00\x00PpNx\x00\x00\x00" + + "\x00Q`8p\x00\x00\x00\x00RP0x\x00\x00\x00\x00S@\x1ap\x00\x00\x00\x00T0\x12x\x00\x00\x00\x00U\x1f\xfcp\x00\x00\x00\x00V\x0f\xf4x\x00\x00\x00\x00V\xff\xdep\x00\x00\x00\x00W\xef\xd6" + + "x\x00\x00\x00\x00X\xdf\xc0p\x00\x00\x00\x00Yϸx\x00\x00\x00\x00Z\xbf\xa2p\x00\x00\x00\x00[\xb8\xd4\xf8\x00\x00\x00\x00\\\xa8\xbe\xf0\x00\x00\x00\x00]\x98\xb6\xf8\x00\x00\x00\x00^\x88\xa0\xf0\x00\x00\x00" + + "\x00_x\x98\xf8\x00\x00\x00\x00`h\x82\xf0\x00\x00\x00\x00aXz\xf8\x00\x00\x00\x00bHd\xf0\x00\x00\x00\x00c8\\\xf8\x00\x00\x00\x00d(F\xf0\x00\x00\x00\x00e\x18>\xf8\x00\x00\x00\x00f\x11c" + + "p\x00\x00\x00\x00g\x01[x\x00\x00\x00\x00g\xf1Ep\x00\x00\x00\x00h\xe1=x\x00\x00\x00\x00i\xd1'p\x00\x00\x00\x00j\xc1\x1fx\x00\x00\x00\x00k\xb1\tp\x00\x00\x00\x00l\xa1\x01x\x00\x00\x00" + + "\x00m\x90\xebp\x00\x00\x00\x00n\x80\xe3x\x00\x00\x00\x00op\xcdp\x00\x00\x00\x00pi\xff\xf8\x00\x00\x00\x00qY\xe9\xf0\x00\x00\x00\x00rI\xe1\xf8\x00\x00\x00\x00s9\xcb\xf0\x00\x00\x00\x00t)\xc3" + + "\xf8\x00\x00\x00\x00u\x19\xad\xf0\x00\x00\x00\x00v\t\xa5\xf8\x00\x00\x00\x00v\xf9\x8f\xf0\x00\x00\x00\x00w\xe9\x87\xf8\x00\x00\x00\x00x\xd9q\xf0\x00\x00\x00\x00y\xc9i\xf8\x00\x00\x00\x00z\xb9S\xf0\x00\x00\x00" + + "\x00{\xb2\x86x\x00\x00\x00\x00|\xa2pp\x00\x00\x00\x00}\x92hx\x00\x00\x00\x00~\x82Rp\x00\x00\x00\x00\u007frJx\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x04\x00\x00\x95$\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\xa1\xb8\x01\t\x00" + + "\x00\x93\xa8\x00\x0f\x00\x00\x9a\xb0\x01\x15LMT\x00AEST\x00+1130\x00+1030\x00+11\x00\n<+1030>-10:30<+11>-11,M" + + "10.1.0,M4.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPF\xc7\x15h\x9c\b\x00\x00\x9c\b\x00\x00\r\x00\x1c\x00Australia/NSWUT\t" + + "\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00" + + "\x8e\x00\x00\x00\x05\x00\x00\x00\x0e\x80\x00\x00\x00\x9cN\xa6\x9c\x9c\xbc \xf0\xcbT\xb3\x00\xcb\xc7Wp̷V\x80ͧ9pΠs\x00χ\x1bp\x03p9\x80\x04\r\x1c\x00\x05P\x1b\x80\x05\xf68" + + "\x80\a/\xfd\x80\a\xd6\x1a\x80\t\x0f߀\t\xb5\xfc\x80\n\xef\xc1\x80\v\x9f\x19\x00\f\xd8\xde\x00\r~\xfb\x00\x0e\xb8\xc0\x00\x0f^\xdd\x00\x10\x98\xa2\x00\x11>\xbf\x00\x12x\x84\x00\x13\x1e\xa1\x00\x14Xf" + + "\x00\x14\xfe\x83\x00\x168H\x00\x17\f\x89\x80\x18!d\x80\x18ǁ\x80\x1a\x01F\x80\x1a\xa7c\x80\x1b\xe1(\x80\x1c\x87E\x80\x1d\xc1\n\x80\x1ey\x9c\x80\x1f\x97\xb2\x00 Y~\x80!\x80\u0380\"B\x9b" + + "\x00#i\xeb\x00$\"}\x00%I\xcd\x00%\xef\xea\x00')\xaf\x00'\xcf\xcc\x00)\t\x91\x00)\xaf\xae\x00*\xe9s\x00+\x98ʀ,ҏ\x80-x\xac\x80.\xb2q\x80/X\x8e\x800\x92S" + + "\x801]Z\x802r5\x803=<\x804R\x17\x805\x1d\x1e\x8061\xf9\x806\xfd\x00\x808\x1b\x16\x008\xdc\xe2\x809\xa7\xe9\x80:\xbcĀ;\xda\xda\x00<\xa5\xe1\x00=\xba\xbc\x00>\x85\xc3" + + "\x00?\x9a\x9e\x00@e\xa5\x00A\x83\xba\x80BE\x87\x00Cc\x9c\x80D.\xa3\x80EC~\x80F\x05K\x00G#`\x80G\xf7\xa2\x00H\xe7\x93\x00Iׄ\x00J\xc7u\x00K\xb7f\x00L\xa7W" + + "\x00M\x97H\x00N\x879\x00Ow*\x00PpU\x80Q`F\x80RP7\x80S@(\x80T0\x19\x80U \n\x80V\x0f\xfb\x80V\xff\xec\x80W\xef݀X\xdf\u0380YϿ\x80Z\xbf\xb0" + + "\x80[\xb8\xdc\x00\\\xa8\xcd\x00]\x98\xbe\x00^\x88\xaf\x00_x\xa0\x00`h\x91\x00aX\x82\x00bHs\x00c8d\x00d(U\x00e\x18F\x00f\x11q\x80g\x01b\x80g\xf1S\x80h\xe1D" + + "\x80i\xd15\x80j\xc1&\x80k\xb1\x17\x80l\xa1\b\x80m\x90\xf9\x80n\x80\xea\x80opۀpj\a\x00qY\xf8\x00rI\xe9\x00s9\xda\x00t)\xcb\x00u\x19\xbc\x00v\t\xad\x00v\xf9\x9e" + + "\x00w\xe9\x8f\x00xـ\x00y\xc9q\x00z\xb9b\x00{\xb2\x8d\x80|\xa2~\x80}\x92o\x80~\x82`\x80\u007frQ\x80\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00" + + "\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\t\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x8e\x00\x00\x00\x05\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\u007f<\xff\xff\xff\xff\x9cN\xa6\x9c\xff\xff\xff\xff\x9c\xbc \xf0\xff\xff\xff\xff" + + "\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7Wp\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧ9p\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ\x1bp\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00" + + "\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00" + + "\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00" + + "\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\f\x89\x80\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18ǁ\x80\x00\x00\x00\x00" + + "\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80" + + "\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00" + + "'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00\x00\x00,ҏ\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80" + + "\x00\x00\x00\x00/X\x8e\x80\x00\x00\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x00" + + "61\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00" + + "\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00" + + "D.\xa3\x80\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\x00\x00\x00\x00H\xe7\x93\x00\x00\x00\x00\x00Iׄ\x00\x00\x00\x00\x00J\xc7u\x00" + + "\x00\x00\x00\x00K\xb7f\x00\x00\x00\x00\x00L\xa7W\x00\x00\x00\x00\x00M\x97H\x00\x00\x00\x00\x00N\x879\x00\x00\x00\x00\x00Ow*\x00\x00\x00\x00\x00PpU\x80\x00\x00\x00\x00Q`F\x80\x00\x00\x00\x00" + + "RP7\x80\x00\x00\x00\x00S@(\x80\x00\x00\x00\x00T0\x19\x80\x00\x00\x00\x00U \n\x80\x00\x00\x00\x00V\x0f\xfb\x80\x00\x00\x00\x00V\xff\xec\x80\x00\x00\x00\x00W\xef݀\x00\x00\x00\x00X\xdf\u0380" + + "\x00\x00\x00\x00YϿ\x80\x00\x00\x00\x00Z\xbf\xb0\x80\x00\x00\x00\x00[\xb8\xdc\x00\x00\x00\x00\x00\\\xa8\xcd\x00\x00\x00\x00\x00]\x98\xbe\x00\x00\x00\x00\x00^\x88\xaf\x00\x00\x00\x00\x00_x\xa0\x00\x00\x00\x00\x00" + + "`h\x91\x00\x00\x00\x00\x00aX\x82\x00\x00\x00\x00\x00bHs\x00\x00\x00\x00\x00c8d\x00\x00\x00\x00\x00d(U\x00\x00\x00\x00\x00e\x18F\x00\x00\x00\x00\x00f\x11q\x80\x00\x00\x00\x00g\x01b\x80" + + "\x00\x00\x00\x00g\xf1S\x80\x00\x00\x00\x00h\xe1D\x80\x00\x00\x00\x00i\xd15\x80\x00\x00\x00\x00j\xc1&\x80\x00\x00\x00\x00k\xb1\x17\x80\x00\x00\x00\x00l\xa1\b\x80\x00\x00\x00\x00m\x90\xf9\x80\x00\x00\x00\x00" + + "n\x80\xea\x80\x00\x00\x00\x00opۀ\x00\x00\x00\x00pj\a\x00\x00\x00\x00\x00qY\xf8\x00\x00\x00\x00\x00rI\xe9\x00\x00\x00\x00\x00s9\xda\x00\x00\x00\x00\x00t)\xcb\x00\x00\x00\x00\x00u\x19\xbc\x00" + + "\x00\x00\x00\x00v\t\xad\x00\x00\x00\x00\x00v\xf9\x9e\x00\x00\x00\x00\x00w\xe9\x8f\x00\x00\x00\x00\x00xـ\x00\x00\x00\x00\x00y\xc9q\x00\x00\x00\x00\x00z\xb9b\x00\x00\x00\x00\x00{\xb2\x8d\x80\x00\x00\x00\x00" + + "|\xa2~\x80\x00\x00\x00\x00}\x92o\x80\x00\x00\x00\x00~\x82`\x80\x00\x00\x00\x00\u007frQ\x80\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0" + + "\x01\x04\x00\x00\x8c\xa0\x00\t\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\x00\x00\x00\x01\x01\nAEST-10AEDT,M10.1.0," + + "M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x8f\xdbK\xf0\xc3\b\x00\x00\xc3\b\x00\x00\x15\x00\x1c\x00Australia/Broken_Hill" + + "UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00" + + "\x00\x00\x00\x8e\x00\x00\x00\x05\x00\x00\x00\x0e\x80\x00\x00\x00\x9cN\xad\xa4\x9c\xbc'\xf8\xcbT\xba\b\xcb\xc7^x̷]\x88ͧ@xΠz\bχ\"x\x03p@\x88\x04\r#\b\x05P\"\x88" + + "\x05\xf6?\x88\a0\x04\x88\a\xd6!\x88\t\x0f\xe6\x88\t\xb6\x03\x88\n\xefȈ\v\x9f \b\f\xd8\xe5\b\r\u007f\x02\b\x0e\xb8\xc7\b\x0f^\xe4\b\x10\x98\xa9\b\x11>\xc6\b\x12x\x8b\b\x13\x1e\xa8\b" + + "\x14Xm\b\x14\xfe\x8a\b\x168O\b\x17\f\x90\x88\x18!k\x88\x18Lj\x88\x1a\x01M\x88\x1a\xa7j\x88\x1b\xe1/\x88\x1c\x87L\x88\x1d\xc1\x11\x88\x1ey\xa3\x88\x1f\x97\xb9\b Y\x85\x88!\x80Ո" + + "\"B\xa2\b#i\xf2\b$\"\x84\b%I\xd4\b%\xef\xf1\b')\xb6\b'\xcf\xd3\b)\t\x98\b)\xaf\xb5\b*\xe9z\b+\x98ш,Җ\x88-x\xb3\x88.\xb2x\x88/X\x95\x88" + + "0\x92Z\x881]a\x882r<\x883=C\x884R\x1e\x885\x1d%\x8862\x00\x886\xfd\a\x888\x1b\x1d\b8\xdc\xe9\x889\xfa\xff\b:\xbcˈ;\xda\xe1\b<\xa5\xe8\b=\xba\xc3\b" + + ">\x85\xca\b?\x9a\xa5\b@e\xac\bA\x83\xc1\x88BE\x8e\bCc\xa3\x88D.\xaa\x88EC\x85\x88F\x05R\bG#g\x88G\xf7\xa9\bH\xe7\x9a\bI\u05cb\bJ\xc7|\bK\xb7m\b" + + "L\xa7^\bM\x97O\bN\x87@\bOw1\bPp\\\x88Q`M\x88RP>\x88S@/\x88T0 \x88U \x11\x88V\x10\x02\x88V\xff\xf3\x88W\xef\xe4\x88X\xdfՈY\xcfƈ" + + "Z\xbf\xb7\x88[\xb8\xe3\b\\\xa8\xd4\b]\x98\xc5\b^\x88\xb6\b_x\xa7\b`h\x98\baX\x89\bbHz\bc8k\bd(\\\be\x18M\bf\x11x\x88g\x01i\x88g\xf1Z\x88" + + "h\xe1K\x88i\xd1<\x88j\xc1-\x88k\xb1\x1e\x88l\xa1\x0f\x88m\x91\x00\x88n\x80\xf1\x88op\xe2\x88pj\x0e\bqY\xff\brI\xf0\bs9\xe1\bt)\xd2\bu\x19\xc3\bv\t\xb4\b" + + "v\xf9\xa5\bw\xe9\x96\bxه\by\xc9x\bz\xb9i\b{\xb2\x94\x88|\xa2\x85\x88}\x92v\x88~\x82g\x88\u007frX\x88\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x00\x00\x84\x9c\x00\x00\x00\x00\x93\xa8\x01\x04\x00\x00\x85\x98\x00\t\x00\x00\x93\xa8\x01\x04\x00\x00\x85\x98\x00\tLMT\x00ACDT\x00ACST\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00\x00\a\x00\x00\x00\x13\xff\xff\xff\xffs\x16\x88d\xff\xff\xff\xffv\x04\xa5\xe0\xff\xff\xff\xff{\x12\x03p\xff" + + "\xff\xff\xff\x9cN\xad\xa4\xff\xff\xff\xff\x9c\xbc'\xf8\xff\xff\xff\xff\xcbT\xba\b\xff\xff\xff\xff\xcb\xc7^x\xff\xff\xff\xff̷]\x88\xff\xff\xff\xffͧ@x\xff\xff\xff\xffΠz\b\xff\xff\xff\xff\xcf" + + "\x87\"x\x00\x00\x00\x00\x03p@\x88\x00\x00\x00\x00\x04\r#\b\x00\x00\x00\x00\x05P\"\x88\x00\x00\x00\x00\x05\xf6?\x88\x00\x00\x00\x00\a0\x04\x88\x00\x00\x00\x00\a\xd6!\x88\x00\x00\x00\x00\t\x0f\xe6\x88\x00" + + "\x00\x00\x00\t\xb6\x03\x88\x00\x00\x00\x00\n\xefȈ\x00\x00\x00\x00\v\x9f \b\x00\x00\x00\x00\f\xd8\xe5\b\x00\x00\x00\x00\r\u007f\x02\b\x00\x00\x00\x00\x0e\xb8\xc7\b\x00\x00\x00\x00\x0f^\xe4\b\x00\x00\x00\x00\x10" + + "\x98\xa9\b\x00\x00\x00\x00\x11>\xc6\b\x00\x00\x00\x00\x12x\x8b\b\x00\x00\x00\x00\x13\x1e\xa8\b\x00\x00\x00\x00\x14Xm\b\x00\x00\x00\x00\x14\xfe\x8a\b\x00\x00\x00\x00\x168O\b\x00\x00\x00\x00\x17\f\x90\x88\x00" + + "\x00\x00\x00\x18!k\x88\x00\x00\x00\x00\x18Lj\x88\x00\x00\x00\x00\x1a\x01M\x88\x00\x00\x00\x00\x1a\xa7j\x88\x00\x00\x00\x00\x1b\xe1/\x88\x00\x00\x00\x00\x1c\x87L\x88\x00\x00\x00\x00\x1d\xc1\x11\x88\x00\x00\x00\x00\x1e" + + "y\xa3\x88\x00\x00\x00\x00\x1f\x97\xb9\b\x00\x00\x00\x00 Y\x85\x88\x00\x00\x00\x00!\x80Ո\x00\x00\x00\x00\"B\xa2\b\x00\x00\x00\x00#i\xf2\b\x00\x00\x00\x00$\"\x84\b\x00\x00\x00\x00%I\xd4\b\x00" + + "\x00\x00\x00%\xef\xf1\b\x00\x00\x00\x00')\xb6\b\x00\x00\x00\x00'\xcf\xd3\b\x00\x00\x00\x00)\t\x98\b\x00\x00\x00\x00)\xaf\xb5\b\x00\x00\x00\x00*\xe9z\b\x00\x00\x00\x00+\x98ш\x00\x00\x00\x00," + + "Җ\x88\x00\x00\x00\x00-x\xb3\x88\x00\x00\x00\x00.\xb2x\x88\x00\x00\x00\x00/X\x95\x88\x00\x00\x00\x000\x92Z\x88\x00\x00\x00\x001]a\x88\x00\x00\x00\x002r<\x88\x00\x00\x00\x003=C\x88\x00" + + "\x00\x00\x004R\x1e\x88\x00\x00\x00\x005\x1d%\x88\x00\x00\x00\x0062\x00\x88\x00\x00\x00\x006\xfd\a\x88\x00\x00\x00\x008\x1b\x1d\b\x00\x00\x00\x008\xdc\xe9\x88\x00\x00\x00\x009\xfa\xff\b\x00\x00\x00\x00:" + + "\xbcˈ\x00\x00\x00\x00;\xda\xe1\b\x00\x00\x00\x00<\xa5\xe8\b\x00\x00\x00\x00=\xba\xc3\b\x00\x00\x00\x00>\x85\xca\b\x00\x00\x00\x00?\x9a\xa5\b\x00\x00\x00\x00@e\xac\b\x00\x00\x00\x00A\x83\xc1\x88\x00" + + "\x00\x00\x00BE\x8e\b\x00\x00\x00\x00Cc\xa3\x88\x00\x00\x00\x00D.\xaa\x88\x00\x00\x00\x00EC\x85\x88\x00\x00\x00\x00F\x05R\b\x00\x00\x00\x00G#g\x88\x00\x00\x00\x00G\xf7\xa9\b\x00\x00\x00\x00H" + + "\xe7\x9a\b\x00\x00\x00\x00I\u05cb\b\x00\x00\x00\x00J\xc7|\b\x00\x00\x00\x00K\xb7m\b\x00\x00\x00\x00L\xa7^\b\x00\x00\x00\x00M\x97O\b\x00\x00\x00\x00N\x87@\b\x00\x00\x00\x00Ow1\b\x00" + + "\x00\x00\x00Pp\\\x88\x00\x00\x00\x00Q`M\x88\x00\x00\x00\x00RP>\x88\x00\x00\x00\x00S@/\x88\x00\x00\x00\x00T0 \x88\x00\x00\x00\x00U \x11\x88\x00\x00\x00\x00V\x10\x02\x88\x00\x00\x00\x00V" + + "\xff\xf3\x88\x00\x00\x00\x00W\xef\xe4\x88\x00\x00\x00\x00X\xdfՈ\x00\x00\x00\x00Y\xcfƈ\x00\x00\x00\x00Z\xbf\xb7\x88\x00\x00\x00\x00[\xb8\xe3\b\x00\x00\x00\x00\\\xa8\xd4\b\x00\x00\x00\x00]\x98\xc5\b\x00" + + "\x00\x00\x00^\x88\xb6\b\x00\x00\x00\x00_x\xa7\b\x00\x00\x00\x00`h\x98\b\x00\x00\x00\x00aX\x89\b\x00\x00\x00\x00bHz\b\x00\x00\x00\x00c8k\b\x00\x00\x00\x00d(\\\b\x00\x00\x00\x00e" + + "\x18M\b\x00\x00\x00\x00f\x11x\x88\x00\x00\x00\x00g\x01i\x88\x00\x00\x00\x00g\xf1Z\x88\x00\x00\x00\x00h\xe1K\x88\x00\x00\x00\x00i\xd1<\x88\x00\x00\x00\x00j\xc1-\x88\x00\x00\x00\x00k\xb1\x1e\x88\x00" + + "\x00\x00\x00l\xa1\x0f\x88\x00\x00\x00\x00m\x91\x00\x88\x00\x00\x00\x00n\x80\xf1\x88\x00\x00\x00\x00op\xe2\x88\x00\x00\x00\x00pj\x0e\b\x00\x00\x00\x00qY\xff\b\x00\x00\x00\x00rI\xf0\b\x00\x00\x00\x00s" + + "9\xe1\b\x00\x00\x00\x00t)\xd2\b\x00\x00\x00\x00u\x19\xc3\b\x00\x00\x00\x00v\t\xb4\b\x00\x00\x00\x00v\xf9\xa5\b\x00\x00\x00\x00w\xe9\x96\b\x00\x00\x00\x00xه\b\x00\x00\x00\x00y\xc9x\b\x00" + + "\x00\x00\x00z\xb9i\b\x00\x00\x00\x00{\xb2\x94\x88\x00\x00\x00\x00|\xa2\x85\x88\x00\x00\x00\x00}\x92v\x88\x00\x00\x00\x00~\x82g\x88\x00\x00\x00\x00\u007frX\x88\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x00\x00\x84\x9c\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\t\x00\x00\x93\xa8\x01\x0e\x00\x00\x85\x98\x00\t\x00\x00\x93\xa8\x01\x0e\x00\x00\x85\x98\x00\tLMT\x00AES" + + "T\x00ACST\x00ACDT\x00\x00\x00\x00\x00\x00\x01\x01\nACST-9:30ACDT,M10.1.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00" + + "\x00\xf5F\x9cPh\xa7{˜\b\x00\x00\x9c\b\x00\x00\x10\x00\x1c\x00Australia/CurrieUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00" + + "\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x8e\x00\x00\x00\x05\x00\x00\x00\x0e\x80\x00\x00\x00\x9b\xd5x\x80\x9c\xbc " + + "\xf0\xcbT\xb3\x00\xcb\xc7Wp̷V\x80ͧ9pΠs\x00χ\x1bp\x03p9\x80\x04\r\x1c\x00\x05P\x1b\x80\x05\xf68\x80\a/\xfd\x80\a\xd6\x1a\x80\t\x0f߀\t\xb5\xfc\x80\n\xef\xc1" + + "\x80\v\x9f\x19\x00\f\xd8\xde\x00\r~\xfb\x00\x0e\xb8\xc0\x00\x0f^\xdd\x00\x10\x98\xa2\x00\x11>\xbf\x00\x12x\x84\x00\x13\x1e\xa1\x00\x14Xf\x00\x14\xfe\x83\x00\x168H\x00\x17\x03O\x00\x18!d\x80\x18\xe31" + + "\x00\x1a\x01F\x80\x1a\xa7c\x80\x1b\xe1(\x80\x1c\x87E\x80\x1d\xc1\n\x80\x1eg'\x80\x1f\x97\xb2\x00 Y~\x80!\x80\u0380\"B\x9b\x00#i\xeb\x00$\"}\x00%I\xcd\x00&\x02_\x00')\xaf" + + "\x00'\xf4\xb6\x00(\xed\xe1\x80)Ԙ\x00*\xcdÀ+\xb4z\x00,\xad\xa5\x80-\x94\\\x00.\x8d\x87\x80/t>\x000mi\x801]Z\x802V\x86\x003=<\x8046h\x005\x1d\x1e" + + "\x806\x16J\x006\xfd\x00\x807\xf6,\x008\xdc\xe2\x809\xa7\xe9\x80:\xbcĀ;\xbf*\x80<\xa5\xe1\x00=\x9f\f\x80>\x85\xc3\x00?~\xee\x80@e\xa5\x00A^ЀBE\x87\x00C>\xb2" + + "\x80D.\xa3\x80E\x1e\x94\x80F\x05K\x00G\a\xb1\x00G\xf7\xa2\x00H\xe7\x93\x00Iׄ\x00J\xc7u\x00K\xb7f\x00L\xa7W\x00M\x97H\x00N\x879\x00Ow*\x00PpU\x80Q`F" + + "\x80RP7\x80S@(\x80T0\x19\x80U \n\x80V\x0f\xfb\x80V\xff\xec\x80W\xef݀X\xdf\u0380YϿ\x80Z\xbf\xb0\x80[\xb8\xdc\x00\\\xa8\xcd\x00]\x98\xbe\x00^\x88\xaf\x00_x\xa0" + + "\x00`h\x91\x00aX\x82\x00bHs\x00c8d\x00d(U\x00e\x18F\x00f\x11q\x80g\x01b\x80g\xf1S\x80h\xe1D\x80i\xd15\x80j\xc1&\x80k\xb1\x17\x80l\xa1\b\x80m\x90\xf9" + + "\x80n\x80\xea\x80opۀpj\a\x00qY\xf8\x00rI\xe9\x00s9\xda\x00t)\xcb\x00u\x19\xbc\x00v\t\xad\x00v\xf9\x9e\x00w\xe9\x8f\x00xـ\x00y\xc9q\x00z\xb9b\x00{\xb2\x8d" + + "\x80|\xa2~\x80}\x92o\x80~\x82`\x80\u007frQ\x80\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x86\xe0\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\x9a\xb0\x01\t\x00\x00\x9a" + + "\xb0\x01\t\x00\x00\x8c\xa0\x00\x04LMT\x00AEST\x00AEDT\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00" + + "\x00\x00\x00\x8e\x00\x00\x00\x05\x00\x00\x00\x0e\xff\xff\xff\xfft.\x04 \xff\xff\xff\xff\x9b\xd5x\x80\xff\xff\xff\xff\x9c\xbc \xf0\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7Wp\xff\xff\xff\xff̷V\x80" + + "\xff\xff\xff\xffͧ9p\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ\x1bp\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00" + + "\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00" + + "\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00" + + "\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x03O\x00\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18\xe31\x00\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80" + + "\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1eg'\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00" + + "#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xed\xe1\x80\x00\x00\x00\x00)Ԙ\x00" + + "\x00\x00\x00\x00*\xcdÀ\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xad\xa5\x80\x00\x00\x00\x00-\x94\\\x00\x00\x00\x00\x00.\x8d\x87\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000mi\x80\x00\x00\x00\x00" + + "1]Z\x80\x00\x00\x00\x002V\x86\x00\x00\x00\x00\x003=<\x80\x00\x00\x00\x0046h\x00\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\x16J\x00\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x007\xf6,\x00" + + "\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xbf*\x80\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\x9f\f\x80\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00" + + "?~\xee\x80\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A^Ѐ\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00C>\xb2\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00E\x1e\x94\x80\x00\x00\x00\x00F\x05K\x00" + + "\x00\x00\x00\x00G\a\xb1\x00\x00\x00\x00\x00G\xf7\xa2\x00\x00\x00\x00\x00H\xe7\x93\x00\x00\x00\x00\x00Iׄ\x00\x00\x00\x00\x00J\xc7u\x00\x00\x00\x00\x00K\xb7f\x00\x00\x00\x00\x00L\xa7W\x00\x00\x00\x00\x00" + + "M\x97H\x00\x00\x00\x00\x00N\x879\x00\x00\x00\x00\x00Ow*\x00\x00\x00\x00\x00PpU\x80\x00\x00\x00\x00Q`F\x80\x00\x00\x00\x00RP7\x80\x00\x00\x00\x00S@(\x80\x00\x00\x00\x00T0\x19\x80" + + "\x00\x00\x00\x00U \n\x80\x00\x00\x00\x00V\x0f\xfb\x80\x00\x00\x00\x00V\xff\xec\x80\x00\x00\x00\x00W\xef݀\x00\x00\x00\x00X\xdf\u0380\x00\x00\x00\x00YϿ\x80\x00\x00\x00\x00Z\xbf\xb0\x80\x00\x00\x00\x00" + + "[\xb8\xdc\x00\x00\x00\x00\x00\\\xa8\xcd\x00\x00\x00\x00\x00]\x98\xbe\x00\x00\x00\x00\x00^\x88\xaf\x00\x00\x00\x00\x00_x\xa0\x00\x00\x00\x00\x00`h\x91\x00\x00\x00\x00\x00aX\x82\x00\x00\x00\x00\x00bHs\x00" + + "\x00\x00\x00\x00c8d\x00\x00\x00\x00\x00d(U\x00\x00\x00\x00\x00e\x18F\x00\x00\x00\x00\x00f\x11q\x80\x00\x00\x00\x00g\x01b\x80\x00\x00\x00\x00g\xf1S\x80\x00\x00\x00\x00h\xe1D\x80\x00\x00\x00\x00" + + "i\xd15\x80\x00\x00\x00\x00j\xc1&\x80\x00\x00\x00\x00k\xb1\x17\x80\x00\x00\x00\x00l\xa1\b\x80\x00\x00\x00\x00m\x90\xf9\x80\x00\x00\x00\x00n\x80\xea\x80\x00\x00\x00\x00opۀ\x00\x00\x00\x00pj\a\x00" + + "\x00\x00\x00\x00qY\xf8\x00\x00\x00\x00\x00rI\xe9\x00\x00\x00\x00\x00s9\xda\x00\x00\x00\x00\x00t)\xcb\x00\x00\x00\x00\x00u\x19\xbc\x00\x00\x00\x00\x00v\t\xad\x00\x00\x00\x00\x00v\xf9\x9e\x00\x00\x00\x00\x00" + + "w\xe9\x8f\x00\x00\x00\x00\x00xـ\x00\x00\x00\x00\x00y\xc9q\x00\x00\x00\x00\x00z\xb9b\x00\x00\x00\x00\x00{\xb2\x8d\x80\x00\x00\x00\x00|\xa2~\x80\x00\x00\x00\x00}\x92o\x80\x00\x00\x00\x00~\x82`\x80" + + "\x00\x00\x00\x00\u007frQ\x80\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x86\xe0\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\x9a\xb0\x01\t\x00\x00\x9a\xb0\x01\t\x00\x00\x8c\xa0\x00\x04" + + "LMT\x00AEST\x00AEDT\x00\x00\x00\x00\x01\x01\nAEST-10AEDT,M10.1.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5" + + "F\x9cP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x1c\x00Brazil/UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x03\x04\n\x00" + + "\x00\x00\x00\x00\xf5F\x9cP\x92)G\x11\xcc\x02\x00\x00\xcc\x02\x00\x00\x10\x00\x1c\x00Brazil/DeNoronhaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5" + + "\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00(\x00\x00\x00\x03\x00\x00\x00\f\x96\xaaed\xb8\x0f;\xd0" + + "\xb8\xfd2\x90\xb9\xf1& \xba\xdef\x10\xda8\xa0 \xda\xeb\xec \xdc\x19ӠܹK\x10\xdd\xfb\a ޛ\xd0\x10\xdf\u074c \xe0T%\x10\xf4\x97\xf1\xa0\xf5\x05P\x10\xf6\xc0V \xf7\x0e\x10\x90" + + "\xf8Q\x1e \xf8Ƿ\x10\xfa\nĠ\xfa\xa8\xea\x90\xfb\xeb\xf8 \xfc\x8bo\x90\x1dɀ \x1exɐ\x1f\xa0'\xa0 3\xc1\x90!\x81[ \"\v\xba\x90#X\x02\xa0#\xe2b\x10%7\xe4\xa0" + + "%Թ\x107\xf6\xb8\xa08\xb8w\x109\xdf\xd5 9\xe9\x01\x90;\xc8\xf1\xa02\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe6\xee\xf1\xbft\x02\x00\x00t\x02\x00\x00\v\x00\x1c\x00Brazil/AcreUT\t\x00\x03nӧ^nӧ^ux" + + "\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x05\x00\x00\x00\f\x96\xaa\x86" + + "\x90\xb8\x0ff\x00\xb8\xfd\\\xc0\xb9\xf1PP\xbaސ@\xda8\xcaP\xda\xec\x16P\xdc\x19\xfd\xd0ܹu@\xdd\xfb1Pޛ\xfa@\xdfݶP\xe0TO@\xf4\x98\x1b\xd0\xf5\x05z@\xf6\xc0\x80" + + "P\xf7\x0e:\xc0\xf8QHP\xf8\xc7\xe1@\xfa\n\xee\xd0\xfa\xa9\x14\xc0\xfb\xec\"P\xfc\x8b\x99\xc0\x1dɪP\x1ex\xf3\xc0\x1f\xa0Q\xd0 3\xeb\xc0!\x81\x85P\"\v\xe4\xc0H`\u007fPR\u007f\x04" + + "\xc0\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x02\xff\xff\xc0p\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00" + + "\x04\xff\xff\xb9\xb0\x00\bLMT\x00-04\x00-05\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x05\x00" + + "\x00\x00\f\xff\xff\xff\xff\x96\xaa\x86\x90\xff\xff\xff\xff\xb8\x0ff\x00\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xf1PP\xff\xff\xff\xff\xbaސ@\xff\xff\xff\xff\xda8\xcaP\xff\xff\xff\xff\xda\xec\x16P\xff" + + "\xff\xff\xff\xdc\x19\xfd\xd0\xff\xff\xff\xffܹu@\xff\xff\xff\xff\xdd\xfb1P\xff\xff\xff\xffޛ\xfa@\xff\xff\xff\xff\xdfݶP\xff\xff\xff\xff\xe0TO@\xff\xff\xff\xff\xf4\x98\x1b\xd0\xff\xff\xff\xff\xf5" + + "\x05z@\xff\xff\xff\xff\xf6\xc0\x80P\xff\xff\xff\xff\xf7\x0e:\xc0\xff\xff\xff\xff\xf8QHP\xff\xff\xff\xff\xf8\xc7\xe1@\xff\xff\xff\xff\xfa\n\xee\xd0\xff\xff\xff\xff\xfa\xa9\x14\xc0\xff\xff\xff\xff\xfb\xec\"P\xff" + + "\xff\xff\xff\xfc\x8b\x99\xc0\x00\x00\x00\x00\x1dɪP\x00\x00\x00\x00\x1ex\xf3\xc0\x00\x00\x00\x00\x1f\xa0Q\xd0\x00\x00\x00\x00 3\xeb\xc0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"\v\xe4\xc0\x00\x00\x00\x00H" + + "`\u007fP\x00\x00\x00\x00R\u007f\x04\xc0\x00\x00\x00\x00\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x02\xff\xff\xc0p\x00\x00\xff\xff\xc7" + + "\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\x04\xff\xff\xb9\xb0\x00\bLMT\x00-04\x00-05\x00\n<-05>5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPM\x16\b*\xa4" + + "\x05\x00\x00\xa4\x05\x00\x00\v\x00\x1c\x00Brazil/EastUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\\\x00\x00\x00\x03\x00\x00\x00\f\x96\xaar\xb4\xb8\x0fI\xe0\xb8\xfd@\xa0\xb9\xf140\xba\xdet \xda8\xae0\xda\xeb" + + "\xfa0\xdc\x19\xe1\xb0ܹY \xdd\xfb\x150ޛ\xde \xdfݚ0\xe0T3 \xf4Z\t0\xf5\x05^ \xf6\xc0d0\xf7\x0e\x1e\xa0\xf8Q,0\xf8\xc7\xc5 \xfa\nҰ\xfa\xa8\xf8\xa0\xfb\xec" + + "\x060\xfc\x8b}\xa0\x1dɎ0\x1exנ\x1f\xa05\xb0 3Ϡ!\x81i0\"\vȠ#X\x10\xb0#\xe2p %7\xf2\xb0%\xd4\xc7 '!\x0f0'\xbd\xe3\xa0)\x00\xf10)\x94" + + "\x8b *\xea\r\xb0+k2\xa0,\xc0\xb50-f\xc4 .\xa0\x970/F\xa6 0\x80y01\x1dM\xa02W \xb03\x06j 48T04\xf8\xc1 6 \x1f06\xcfh\xa07\xf6" + + "ư8\xb8\x85 9\xdf\xe30:\x8f,\xa0;\xc8\xff\xb0N\xf0\xa0?\x91\xfe0@.ҠA\x86\xf80B\x17\xef CQ\xc20C\xf7\xd1 EMS\xb0E\xe0" + + "\xed\xa0G\x11\x860G\xb7\x95 H\xfa\xa2\xb0I\x97w Jڄ\xb0K\x80\x93\xa0L\xbaf\xb0M`u\xa0N\x9aH\xb0OI\x92 P\x83e0Q 9\xa0RcG0S\x00\x1b\xa0TC" + + ")0T\xe98 V#\v0V\xc9\x1a X\x02\xed0X\xa8\xfc Y\xe2\xcf0Z\x88\xde [\xde`\xb0\\h\xc0 \u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\xff\xff\xd4L\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\\\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaar\xb4\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140" + + "\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff" + + "\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4Z\t0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 " + + "\xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00" + + " 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x00'!\x0f0" + + "\x00\x00\x00\x00'\xbd\xe3\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\x94\x8b \x00\x00\x00\x00*\xea\r\xb0\x00\x00\x00\x00+k2\xa0\x00\x00\x00\x00,\xc0\xb50\x00\x00\x00\x00-f\xc4 \x00\x00\x00\x00" + + ".\xa0\x970\x00\x00\x00\x00/F\xa6 \x00\x00\x00\x000\x80y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00\x002W \xb0\x00\x00\x00\x003\x06j \x00\x00\x00\x0048T0\x00\x00\x00\x004\xf8\xc1 " + + "\x00\x00\x00\x006 \x1f0\x00\x00\x00\x006\xcfh\xa0\x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x00:\x8f,\xa0\x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00" + + "N\xf0\xa0\x00\x00\x00\x00?\x91\xfe0\x00\x00\x00\x00@.Ҡ\x00\x00\x00\x00A\x86\xf80\x00\x00\x00\x00B\x17\xef \x00\x00\x00\x00CQ\xc20" + + "\x00\x00\x00\x00C\xf7\xd1 \x00\x00\x00\x00EMS\xb0\x00\x00\x00\x00E\xe0\xed\xa0\x00\x00\x00\x00G\x11\x860\x00\x00\x00\x00G\xb7\x95 \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\x97w \x00\x00\x00\x00" + + "Jڄ\xb0\x00\x00\x00\x00K\x80\x93\xa0\x00\x00\x00\x00L\xbaf\xb0\x00\x00\x00\x00M`u\xa0\x00\x00\x00\x00N\x9aH\xb0\x00\x00\x00\x00OI\x92 \x00\x00\x00\x00P\x83e0\x00\x00\x00\x00Q 9\xa0" + + "\x00\x00\x00\x00RcG0\x00\x00\x00\x00S\x00\x1b\xa0\x00\x00\x00\x00TC)0\x00\x00\x00\x00T\xe98 \x00\x00\x00\x00V#\v0\x00\x00\x00\x00V\xc9\x1a \x00\x00\x00\x00X\x02\xed0\x00\x00\x00\x00" + + "X\xa8\xfc \x00\x00\x00\x00Y\xe2\xcf0\x00\x00\x00\x00Z\x88\xde \x00\x00\x00\x00[\xde`\xb0\x00\x00\x00\x00\\h\xc0 \x00\x00\x00\x00\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\xff\xff\xd4L\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00\n<-03>3\nPK\x03\x04\n\x00" + + "\x00\x00\x00\x00\xf5F\x9cP*\x95<\xda\\\x02\x00\x00\\\x02\x00\x00\v\x00\x1c\x00Brazil/WestUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14" + + "\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x03\x00\x00\x00\f\x96\xaa\u007fD\xb8\x0fW\xf0\xb8\xfdN\xb0\xb9" + + "\xf1B@\xbaނ0\xda8\xbc@\xda\xec\b@\xdc\x19\xef\xc0ܹg0\xdd\xfb#@ޛ\xec0\xdfݨ@\xe0TA0\xf4\x98\r\xc0\xf5\x05l0\xf6\xc0r@\xf7\x0e,\xb0\xf8Q:@\xf8" + + "\xc7\xd30\xfa\n\xe0\xc0\xfa\xa9\x06\xb0\xfb\xec\x14@\xfc\x8b\x8b\xb0\x1dɜ@\x1ex\xe5\xb0\x1f\xa0C\xc0 3ݰ!\x81w@\"\vְ,\xc0\xc3@-f\xd20\u007f\xff\xff\xff\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\xff\xffǼ\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03\x00-04\x00TZi" + + "f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\u007fD\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff" + + "\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xbaނ0\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#" + + "@\xff\xff\xff\xffޛ\xec0\xff\xff\xff\xff\xdfݨ@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff" + + "\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5" + + "\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3ݰ\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"\vְ\x00\x00\x00\x00,\xc0\xc3@\x00\x00\x00\x00-f\xd20\x00\x00\x00\x00\u007f\xff\xff\xff\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\xff\xffǼ\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03\x00-04\x00\n" + + "<-04>4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP3\x9e\xfd\x8a.\b\x00\x00.\b\x00\x00\x03\x00\x1c\x00CETUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5" + + "\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x88\x00\x00\x00\x04\x00\x00\x00\t\x9b\f\x17`\x9b\xd5\xda\xf0" + + "\x9cٮ\x90\x9d\xa4\xb5\x90\x9e\xb9\x90\x90\x9f\x84\x97\x90\xc8\tq\x90\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10Ђ%\x10\xd1r\x16\x10\xd2N@\x90\r\xa4c\x90\x0e\x8b\x1a\x10\x0f\x84E\x90" + + "\x10t6\x90\x11d'\x90\x12T\x18\x90\x13MD\x10\x143\xfa\x90\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10" + + "\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10" + + "I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90" + + "V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10" + + "e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10" + + "s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x00\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\x0e\x10\x00\x05\x00\x00\x1c \x01\x00\x00\x00\x1c \x01\x00\x00\x00\x0e\x10\x00\x05CEST\x00CET\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x88\x00\x00\x00\x04\x00\x00\x00\t\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff" + + "\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4" + + "\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00" + + "\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe" + + "\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00" + + "\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05" + + "\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00" + + "\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83" + + "\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00" + + "\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3" + + "\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00" + + "\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q" + + "\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00" + + "\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6" + + "\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x00\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\x0e" + + "\x10\x00\x05\x00\x00\x1c \x01\x00\x00\x00\x1c \x01\x00\x00\x00\x0e\x10\x00\x05CEST\x00CET\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M10.5.0/" + + "3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPdO0\x9c\x06\t\x00\x00\x06\t\x00\x00\a\x00\x1c\x00CST6CDTUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01" + + "\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x95\x00\x00\x00\x05\x00\x00\x00\x10\x9e\xa6,\x80\x9f\xba\xf9p\xa0" + + "\x86\x0e\x80\xa1\x9a\xdbpˈ\xfe\x80\xd2#\xf4p\xd2a\t\xf0\xfa\xf8g\x00\xfb\xe8I\xf0\xfc\xd8I\x00\xfd\xc8+\xf0\xfe\xb8+\x00\xff\xa8\r\xf0\x00\x98\r\x00\x01\x87\xef\xf0\x02w\xef\x00\x03q\fp\x04" + + "a\v\x80\x05P\xeep\x06@\xed\x80\a0\xd0p\a\x8d'\x80\t\x10\xb2p\t\xad\xa3\x00\n\xf0\x94p\v\xe0\x93\x80\fٰ\xf0\r\xc0u\x80\x0e\xb9\x92\xf0\x0f\xa9\x92\x00\x10\x99t\xf0\x11\x89t\x00\x12" + + "yV\xf0\x13iV\x00\x14Y8\xf0\x15I8\x00\x169\x1a\xf0\x17)\x1a\x00\x18\"7p\x19\b\xfc\x00\x1a\x02\x19p\x1a\xf2\x18\x80\x1b\xe1\xfbp\x1c\xd1\xfa\x80\x1d\xc1\xddp\x1e\xb1܀\x1f\xa1\xbfp " + + "v\x0f\x00!\x81\xa1p\"U\xf1\x00#j\xbd\xf0$5\xd3\x00%J\x9f\xf0&\x15\xb5\x00'*\x81\xf0'\xfeр)\nc\xf0)\u07b3\x80*\xeaE\xf0+\xbe\x95\x80,\xd3bp-\x9ew\x80." + + "\xb3Dp/~Y\x800\x93&p1gv\x002s\bp3GX\x004R\xeap5':\x0062\xccp7\a\x1c\x008\x1b\xe8\xf08\xe6\xfe\x009\xfb\xca\xf0:\xc6\xe0\x00;۬\xf0<" + + "\xaf\xfc\x80=\xbb\x8e\xf0>\x8fހ?\x9bp\xf0@o\xc0\x80A\x84\x8dpBO\xa2\x80CdopD/\x84\x80EDQpE\xf3\xb7\x00G-m\xf0Gә\x00I\rO\xf0I\xb3{\x00J" + + "\xed1\xf0K\x9c\x97\x80L\xd6NpM|y\x80N\xb60pO\\[\x80P\x96\x12pQ<=\x80Ru\xf4pS\x1c\x1f\x80TU\xd6pT\xfc\x01\x80V5\xb8pV\xe5\x1e\x00X\x1e\xd4\xf0X" + + "\xc5\x00\x00Y\xfe\xb6\xf0Z\xa4\xe2\x00[ޘ\xf0\\\x84\xc4\x00]\xbez\xf0^d\xa6\x00_\x9e\\\xf0`M\u0080a\x87ypb-\xa4\x80cg[pd\r\x86\x80eG=pe\xedh\x80g" + + "'\x1fpg\xcdJ\x80i\a\x01pi\xad,\x80j\xe6\xe3pk\x96I\x00l\xcf\xff\xf0mv+\x00n\xaf\xe1\xf0oV\r\x00p\x8f\xc3\xf0q5\xef\x00ro\xa5\xf0s\x15\xd1\x00tO\x87\xf0t" + + "\xfe\xed\x80v8\xa4pv\xdeπx\x18\x86px\xbe\xb1\x80y\xf8hpz\x9e\x93\x80{\xd8Jp|~u\x80}\xb8,p~^W\x80\u007f\x98\x0ep\x01\x00\x01\x00\x02\x03\x00\x01\x00\x01\x00\x01\x00" + + "\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00" + + "\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00" + + "\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x01\x00\xff\xff\xb9\xb0\x01\b\xff\xff\xb9\xb0\x01\f\xff\xff\xab\xa0\x00\x04CDT\x00CST\x00CWT\x00CP" + + "T\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x95\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff" + + "\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xfa\xf8g\x00" + + "\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00" + + "\x02w\xef\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t\x10\xb2p" + + "\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00" + + "\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00" + + "\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00" + + "\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0" + + "\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00" + + ",\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00" + + "\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00" + + ":\xc6\xe0\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp" + + "\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G-m\xf0\x00\x00\x00\x00Gә\x00\x00\x00\x00\x00" + + "I\rO\xf0\x00\x00\x00\x00I\xb3{\x00\x00\x00\x00\x00J\xed1\xf0\x00\x00\x00\x00K\x9c\x97\x80\x00\x00\x00\x00L\xd6Np\x00\x00\x00\x00M|y\x80\x00\x00\x00\x00N\xb60p\x00\x00\x00\x00O\\[\x80" + + "\x00\x00\x00\x00P\x96\x12p\x00\x00\x00\x00Q<=\x80\x00\x00\x00\x00Ru\xf4p\x00\x00\x00\x00S\x1c\x1f\x80\x00\x00\x00\x00TU\xd6p\x00\x00\x00\x00T\xfc\x01\x80\x00\x00\x00\x00V5\xb8p\x00\x00\x00\x00" + + "V\xe5\x1e\x00\x00\x00\x00\x00X\x1e\xd4\xf0\x00\x00\x00\x00X\xc5\x00\x00\x00\x00\x00\x00Y\xfe\xb6\xf0\x00\x00\x00\x00Z\xa4\xe2\x00\x00\x00\x00\x00[ޘ\xf0\x00\x00\x00\x00\\\x84\xc4\x00\x00\x00\x00\x00]\xbez\xf0" + + "\x00\x00\x00\x00^d\xa6\x00\x00\x00\x00\x00_\x9e\\\xf0\x00\x00\x00\x00`M\u0080\x00\x00\x00\x00a\x87yp\x00\x00\x00\x00b-\xa4\x80\x00\x00\x00\x00cg[p\x00\x00\x00\x00d\r\x86\x80\x00\x00\x00\x00" + + "eG=p\x00\x00\x00\x00e\xedh\x80\x00\x00\x00\x00g'\x1fp\x00\x00\x00\x00g\xcdJ\x80\x00\x00\x00\x00i\a\x01p\x00\x00\x00\x00i\xad,\x80\x00\x00\x00\x00j\xe6\xe3p\x00\x00\x00\x00k\x96I\x00" + + "\x00\x00\x00\x00l\xcf\xff\xf0\x00\x00\x00\x00mv+\x00\x00\x00\x00\x00n\xaf\xe1\xf0\x00\x00\x00\x00oV\r\x00\x00\x00\x00\x00p\x8f\xc3\xf0\x00\x00\x00\x00q5\xef\x00\x00\x00\x00\x00ro\xa5\xf0\x00\x00\x00\x00" + + "s\x15\xd1\x00\x00\x00\x00\x00tO\x87\xf0\x00\x00\x00\x00t\xfe\xed\x80\x00\x00\x00\x00v8\xa4p\x00\x00\x00\x00v\xdeπ\x00\x00\x00\x00x\x18\x86p\x00\x00\x00\x00x\xbe\xb1\x80\x00\x00\x00\x00y\xf8hp" + + "\x00\x00\x00\x00z\x9e\x93\x80\x00\x00\x00\x00{\xd8Jp\x00\x00\x00\x00|~u\x80\x00\x00\x00\x00}\xb8,p\x00\x00\x00\x00~^W\x80\x00\x00\x00\x00\u007f\x98\x0ep\x01\x00\x01\x00\x02\x03\x00\x01\x00\x01\x00\x01" + + "\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01" + + "\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01" + + "\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x01\x00\xff\xff\xb9\xb0\x01\b\xff\xff\xb9\xb0\x01\f\xff\xff\xab\xa0\x00\x04CDT\x00CST\x00CWT\x00C" + + "PT\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\a\x00\x1c\x00Canada/UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe8OD\xf3" + + "`\r\x00\x00`\r\x00\x00\x0f\x00\x1c\x00Canada/AtlanticUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\xe4\x00\x00\x00\x05\x00\x00\x00\x14\x80\U0006b81a\xe4\xde\xc0\x9b\xd6\x130\x9e\xb8\x85`\x9f\xba\xddP\xa2" + + "\x9d\x17@\xa30\xb10\xa4zV@\xa5\x1b\x1f0\xa6S\xa0\xc0\xa6\xfcR\xb0\xa8<\xbd@\xa8\xdc4\xb0\xaa\x1c\x9f@\xaa\xcd:0\xab\xfc\x81@\xac\xbf\x910\xad\xee\xd8@\xae\x8c\xfe0\xaf\xbcE@\xb0" + + "\u007fU0\xb1\xae\x9c@\xb2Kp\xb0\xb3\x8e~@\xb4$\xbb0\xb5n`@\xb6\x15\xc0\xb0\xb7NB@\xb8\b\x17\xb0\xb9$\xe9\xc0\xb9\xe7\xf9\xb0\xbb\x04\xcb\xc0\xbb\xd1\x160\xbd\x00]@\xbd\x9d1\xb0\xbe" + + "\xf2\xb4@\xbf\x90\xda0\xc0\xd3\xe7\xc0\xc1^G0\u008d\x8e@\xc3P\x9e0\xc4mp@\xc50\x800\xc6r<@\xc7\x10b0\xc86n\xc0\xc8\xf9~\xb0\xca\x16P\xc0\xca\xd9`\xb0ˈ\xe2`\xd2" + + "#\xf4p\xd2`\xed\xd0\xd3u\xd6\xe0\xd4@\xcf\xd0\xd5U\xb8\xe0\xd6 \xb1\xd0\xd75\x9a\xe0\xd8\x00\x93\xd0\xd9\x15|\xe0\xd9\xe0u\xd0\xdc\xde{`ݩtP\u07be]`߉VP\xe0\x9e?`\xe1" + + "i8P\xe2~!`\xe3I\x1aP\xe6G\x1f\xe0\xe7\x12\x18\xd0\xe8'\x01\xe0\xe8\xf1\xfa\xd0\xea\x06\xe3\xe0\xea\xd1\xdc\xd0\xeb\xe6\xc5\xe0챾\xd0\xf1\x8f\xa6`\xf2\u007f\x89P\xf3o\x88`\xf4_kP\xf5" + + "Oj`\xf6?MP\xf7/L`\xf8(i\xd0\xf9\x0f.`\xfa\bK\xd0\xfa\xf8J\xe0\xfb\xe8-\xd0\xfc\xd8,\xe0\xfd\xc8\x0f\xd0\xfe\xb8\x0e\xe0\xff\xa7\xf1\xd0\x00\x97\xf0\xe0\x01\x87\xd3\xd0\x02w\xd2\xe0\x03" + + "p\xf0P\x04`\xef`\x05P\xd2P\x06@\xd1`\a0\xb4P\b \xb3`\t\x10\x96P\n\x00\x95`\n\xf0xP\v\xe0w`\fٔ\xd0\r\xc0Y`\x0e\xb9v\xd0\x0f\xa9u\xe0\x10\x99X\xd0\x11" + + "\x89W\xe0\x12y:\xd0\x13i9\xe0\x14Y\x1c\xd0\x15I\x1b\xe0\x168\xfe\xd0\x17(\xfd\xe0\x18\"\x1bP\x19\b\xdf\xe0\x1a\x01\xfdP\x1a\xf1\xfc`\x1b\xe1\xdfP\x1c\xd1\xde`\x1d\xc1\xc1P\x1e\xb1\xc0`\x1f" + + "\xa1\xa3P u\xf2\xe0!\x81\x85P\"U\xd4\xe0#j\xa1\xd0$5\xb6\xe0%J\x83\xd0&\x15\x98\xe0'*e\xd0'\xfe\xb5`)\nG\xd0)ޗ`*\xea)\xd0+\xbey`,\xd3FP-" + + "\x9e[`.\xb3(P/~=`0\x93\nP1gY\xe02r\xecP3G;\xe04R\xceP5'\x1d\xe062\xb0P7\x06\xff\xe08\x1b\xcc\xd08\xe6\xe1\xe09\xfb\xae\xd0:\xc6\xc3\xe0;" + + "ې\xd0<\xaf\xe0`=\xbbr\xd0>\x8f\xc2`?\x9bT\xd0@o\xa4`A\x84qPBO\x86`CdSPD/h`ED5PE\xf3\x9a\xe0G-Q\xd0G\xd3|\xe0I\r3\xd0I" + + "\xb3^\xe0J\xed\x15\xd0K\x9c{`L\xd62PM|]`N\xb6\x14PO\\?`P\x95\xf6PQ\x8f\xc2`\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@o\xa4`\x00\x00\x00\x00A\x84qP\x00" + + "\x00\x00\x00BO\x86`\x00\x00\x00\x00CdSP\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x9a\xe0\x00\x00\x00\x00G-Q\xd0\x00\x00\x00\x00G\xd3|\xe0\x00\x00\x00\x00I" + + "\r3\xd0\x00\x00\x00\x00I\xb3^\xe0\x00\x00\x00\x00J\xed\x15\xd0\x00\x00\x00\x00K\x9c{`\x00\x00\x00\x00L\xd62P\x00\x00\x00\x00M|]`\x00\x00\x00\x00N\xb6\x14P\x00\x00\x00\x00O\\?`\x00" + + "\x00\x00\x00P\x95\xf6P\x00\x00\x00\x00Q\x8f\xfa\xa0?" + + "\x9b\x8d\x10@oܠA\x84\xa9\x90BO\xbe\xa0Cd\x8b\x90D/\xa0\xa0EDm\x90E\xf3\xd3 G-\x8a\x10Gӵ I\rl\x10I\xb3\x97 J\xedN\x10K\x9c\xb3\xa0L\xd6j\x90M" + + "|\x95\xa0N\xb6L\x90O\\w\xa0P\x96.\x90Q\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9" + + "\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x00\x00\x00\x00G-\x8a\x10\x00\x00\x00\x00Gӵ \x00\x00\x00" + + "\x00I\rl\x10\x00\x00\x00\x00I\xb3\x97 \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00M|\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\\w" + + "\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q\x8f\xd0p?\x9bb\xe0@o\xb2pA\x84\u007f`BO\x94pCda`D/vpEDC`E\xf3\xa8\xf0G-_\xe0Gӊ\xf0I\rA\xe0I" + + "\xb3l\xf0J\xed#\xe0K\x9c\x89pL\xd6@`M|kpN\xb6\"`O\\MpP\x96\x04`Q\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\u007f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`" + + "\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x00\x00\x00\x00G-_\xe0\x00\x00\x00\x00Gӊ\xf0\x00\x00\x00\x00I\rA\xe0\x00\x00\x00\x00I\xb3l\xf0\x00\x00\x00\x00" + + "J\xed#\xe0\x00\x00\x00\x00K\x9c\x89p\x00\x00\x00\x00L\xd6@`\x00\x00\x00\x00M|kp\x00\x00\x00\x00N\xb6\"`\x00\x00\x00\x00O\\Mp\x00\x00\x00\x00P\x96\x04`\x00\x00\x00\x00Q\x8f\xfa\xa0?\x9b\x8d\x10@oܠA\x84\xa9\x90BO\xbe\xa0Cd\x8b\x90D/\xa0\xa0E" + + "Dm\x90E\xf3\xd3 G-\x8a\x10Gӵ I\rl\x10I\xb3\x97 J\xedN\x10K\x9c\xb3\xa0L\xd6j\x90M|\x95\xa0N\xb6L\x90O\\w\xa0P\x96.\x90Q\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00" + + "A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x00\x00\x00\x00G-\x8a\x10\x00\x00\x00\x00Gӵ " + + "\x00\x00\x00\x00I\rl\x10\x00\x00\x00\x00I\xb3\x97 \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00M|\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00" + + "O\\w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q\x8f\x9ft?\x9b1\xe4@o\x81tA\x84NdBOctCd0dD/E" + + "tED\x12dE\xf3w\xf4G-.\xe4G\xd3Y\xf4I\r\x10\xe4I\xb3;\xf4J\xec\xf2\xe4K\x9cXtL\xd6\x0fdM|:tN\xb6\rHO\\8XP\x95\xefHQ<\x1aXRu\xd1" + + "HS\x1b\xfcXTU\xb3HT\xfb\xdeXV5\x95HV\xe4\xfa\xd8X\x1e\xb1\xc8X\xc4\xdc\xd8Y\xfe\x93\xc8Z\xa4\xbe\xd8[\xdeu\xc8\\\x84\xa0\xd8]\xbeW\xc8^d\x82\xd8_\x9e9\xc8`M\x9f" + + "Xa\x87VHb-\x81Xcg8Hd\rcXeG\x1aHe\xedEXg&\xfcHg\xcd'Xi\x06\xdeHi\xad\tXj\xe6\xc0Hk\x96%\xd8l\xcf\xdc\xc8mv\a\xd8n\xaf\xbe" + + "\xc8oU\xe9\xd8p\x8f\xa0\xc8q5\xcb\xd8ro\x82\xc8s\x15\xad\xd8tOd\xc8t\xfe\xcaXv8\x81HvެXx\x18cHx\xbe\x8eXy\xf8EHz\x9epX{\xd8'H|~R" + + "X}\xb8\tH~^4X\u007f\x97\xebH\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x06\x05\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\a\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\xff\xffΔ\x00\x00\xff\xffܤ\x01\x04\xff\xffΔ\x00\b\xff\xff\xdc\xd8\x01\x04\xff\xff\xce\xc8\x00\b\xff\xff\xdc\xd8\x01\f\xff\xff\xdc\xd8\x01\x10\xff\xff\xea\xe8\x01\x14" + + "\xff\xff\xdc\xd8\x01\x04LMT\x00NDT\x00NST\x00NPT\x00NWT\x00NDDT\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\xef\x00\x00\x00\t\x00\x00\x00\x19\xff\xff\xff\xff^=4\xec\xff\xff\xff\xff\x9c\xcfb\f\xff\xff\xff\xff\x9d\xa4\xe6\xfc\xff\xff\xff" + + "\xff\x9e\xb8~\x8c\xff\xff\xff\xff\x9f\xba\xd6|\xff\xff\xff\xff\xa0\xb6\x88\xdc\xff\xff\xff\xff\xa18\xffL\xff\xff\xff\xff\xa2\x95\x19\\\xff\xff\xff\xff\xa3\x84\xfcL\xff\xff\xff\xff\xa4t\xfb\\\xff\xff\xff\xff\xa5d\xde" + + "L\xff\xff\xff\xff\xa6^\x17\xdc\xff\xff\xff\xff\xa7D\xc0L\xff\xff\xff\xff\xa8=\xf9\xdc\xff\xff\xff\xff\xa9$\xa2L\xff\xff\xff\xff\xaa\x1d\xdb\xdc\xff\xff\xff\xff\xab\x04\x84L\xff\xff\xff\xff\xab\xfd\xbd\xdc\xff\xff\xff" + + "\xff\xac\xe4fL\xff\xff\xff\xff\xadݟ\xdc\xff\xff\xff\xff\xae͂\xcc\xff\xff\xff\xff\xaf\xbd\x81\xdc\xff\xff\xff\xff\xb0\xadd\xcc\xff\xff\xff\xff\xb1\xa6\x9e\\\xff\xff\xff\xff\xb2\x8dF\xcc\xff\xff\xff\xff\xb3\x86\x80" + + "\\\xff\xff\xff\xff\xb4m(\xcc\xff\xff\xff\xff\xb5fb\\\xff\xff\xff\xff\xb6M\n\xcc\xff\xff\xff\xff\xb7FD\\\xff\xff\xff\xff\xb8,\xec\xcc\xff\xff\xff\xff\xb9&&\\\xff\xff\xff\xff\xba\x16\tL\xff\xff\xff" + + "\xff\xbb\x0fB\xdc\xff\xff\xff\xff\xbb\xf5\xebL\xff\xff\xff\xff\xbc\xef$\xdc\xff\xff\xff\xff\xbd\xd5\xcdL\xff\xff\xff\xff\xbe\x9eMl\xff\xff\xff\xff\xbe\xcf\x06\xa8\xff\xff\xff\xff\xbf\xb5\xaf\x18\xff\xff\xff\xff\xc0\xb81" + + "8\xff\xff\xff\xff\xc1y\xef\xa8\xff\xff\xff\xff\u0098\x138\xff\xff\xff\xff\xc3YѨ\xff\xff\xff\xff\xc4w\xf58\xff\xff\xff\xff\xc59\xb3\xa8\xff\xff\xff\xff\xc6a\x11\xb8\xff\xff\xff\xff\xc7\x19\x95\xa8\xff\xff\xff" + + "\xff\xc8@\xf3\xb8\xff\xff\xff\xff\xc9\x02\xb2(\xff\xff\xff\xff\xca ո\xff\xff\xff\xff\xca\xe2\x94(\xff\xff\xff\xff\xcc\x00\xb7\xb8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xe6\xc8\xff\xff\xff\xffӈD" + + "\xd8\xff\xff\xff\xff\xd4J\x03H\xff\xff\xff\xff\xd5h&\xd8\xff\xff\xff\xff\xd6)\xe5H\xff\xff\xff\xff\xd7H\b\xd8\xff\xff\xff\xff\xd8\t\xc7H\xff\xff\xff\xff\xd9'\xea\xd8\xff\xff\xff\xff\xd9\xe9\xa9H\xff\xff\xff" + + "\xff\xdb\x11\aX\xff\xff\xff\xff\xdb\xd2\xc5\xc8\xff\xff\xff\xff\xdc\xdetX\xff\xff\xff\xffݩmH\xff\xff\xff\xff\u07beVX\xff\xff\xff\xff߉OH\xff\xff\xff\xff\xe0\x9e8X\xff\xff\xff\xff\xe1i1" + + "H\xff\xff\xff\xff\xe2~\x1aX\xff\xff\xff\xff\xe3I\x13H\xff\xff\xff\xff\xe4]\xfcX\xff\xff\xff\xff\xe5(\xf5H\xff\xff\xff\xff\xe6G\x18\xd8\xff\xff\xff\xff\xe7\x12\x11\xc8\xff\xff\xff\xff\xe8&\xfa\xd8\xff\xff\xff" + + "\xff\xe8\xf1\xf3\xc8\xff\xff\xff\xff\xea\x06\xdc\xd8\xff\xff\xff\xff\xea\xd1\xd5\xc8\xff\xff\xff\xff\xeb\xe6\xbe\xd8\xff\xff\xff\xff챷\xc8\xff\xff\xff\xff\xedƠ\xd8\xff\xff\xff\xff\ueffeH\xff\xff\xff\xffﯽ" + + "X\xff\xff\xff\xff\xf0\x9f\xa0H\xff\xff\xff\xff\xf1\x8f\x9fX\xff\xff\xff\xff\xf2\u007f\x82H\xff\xff\xff\xff\xf3o\x81X\xff\xff\xff\xff\xf4_dH\xff\xff\xff\xff\xf5OcX\xff\xff\xff\xff\xf6?FH\xff\xff\xff" + + "\xff\xf7/EX\xff\xff\xff\xff\xf8(b\xc8\xff\xff\xff\xff\xf9\x0f'X\xff\xff\xff\xff\xfa\bD\xc8\xff\xff\xff\xff\xfa\xf8C\xd8\xff\xff\xff\xff\xfb\xe8&\xc8\xff\xff\xff\xff\xfc\xd8%\xd8\xff\xff\xff\xff\xfd\xc8\b" + + "\xc8\xff\xff\xff\xff\xfe\xb8\a\xd8\xff\xff\xff\xff\xff\xa7\xea\xc8\x00\x00\x00\x00\x00\x97\xe9\xd8\x00\x00\x00\x00\x01\x87\xcc\xc8\x00\x00\x00\x00\x02w\xcb\xd8\x00\x00\x00\x00\x03p\xe9H\x00\x00\x00\x00\x04`\xe8X\x00\x00\x00" + + "\x00\x05P\xcbH\x00\x00\x00\x00\x06@\xcaX\x00\x00\x00\x00\a0\xadH\x00\x00\x00\x00\b \xacX\x00\x00\x00\x00\t\x10\x8fH\x00\x00\x00\x00\n\x00\x8eX\x00\x00\x00\x00\n\xf0qH\x00\x00\x00\x00\v\xe0p" + + "X\x00\x00\x00\x00\fٍ\xc8\x00\x00\x00\x00\r\xc0RX\x00\x00\x00\x00\x0e\xb9o\xc8\x00\x00\x00\x00\x0f\xa9n\xd8\x00\x00\x00\x00\x10\x99Q\xc8\x00\x00\x00\x00\x11\x89P\xd8\x00\x00\x00\x00\x12y3\xc8\x00\x00\x00" + + "\x00\x13i2\xd8\x00\x00\x00\x00\x14Y\x15\xc8\x00\x00\x00\x00\x15I\x14\xd8\x00\x00\x00\x00\x168\xf7\xc8\x00\x00\x00\x00\x17(\xf6\xd8\x00\x00\x00\x00\x18\"\x14H\x00\x00\x00\x00\x19\b\xd8\xd8\x00\x00\x00\x00\x1a\x01\xf6" + + "H\x00\x00\x00\x00\x1a\xf1\xf5X\x00\x00\x00\x00\x1b\xe1\xd8H\x00\x00\x00\x00\x1c\xd1\xd7X\x00\x00\x00\x00\x1d\xc1\xbaH\x00\x00\x00\x00\x1e\xb1\xb9X\x00\x00\x00\x00\x1f\xa1\x9cH\x00\x00\x00\x00 u\xcf\xf4\x00\x00\x00" + + "\x00!\x81bd\x00\x00\x00\x00\"U\xb1\xf4\x00\x00\x00\x00#jp\xd4\x00\x00\x00\x00$5\x93\xf4\x00\x00\x00\x00%J`\xe4\x00\x00\x00\x00&\x15u\xf4\x00\x00\x00\x00'*B\xe4\x00\x00\x00\x00'\xfe\x92" + + "t\x00\x00\x00\x00)\n$\xe4\x00\x00\x00\x00)\xdett\x00\x00\x00\x00*\xea\x06\xe4\x00\x00\x00\x00+\xbeVt\x00\x00\x00\x00,\xd3#d\x00\x00\x00\x00-\x9e8t\x00\x00\x00\x00.\xb3\x05d\x00\x00\x00" + + "\x00/~\x1at\x00\x00\x00\x000\x92\xe7d\x00\x00\x00\x001g6\xf4\x00\x00\x00\x002r\xc9d\x00\x00\x00\x003G\x18\xf4\x00\x00\x00\x004R\xabd\x00\x00\x00\x005&\xfa\xf4\x00\x00\x00\x0062\x8d" + + "d\x00\x00\x00\x007\x06\xdc\xf4\x00\x00\x00\x008\x1b\xa9\xe4\x00\x00\x00\x008\xe6\xbe\xf4\x00\x00\x00\x009\xfb\x8b\xe4\x00\x00\x00\x00:Ơ\xf4\x00\x00\x00\x00;\xdbm\xe4\x00\x00\x00\x00<\xaf\xbdt\x00\x00\x00" + + "\x00=\xbbO\xe4\x00\x00\x00\x00>\x8f\x9ft\x00\x00\x00\x00?\x9b1\xe4\x00\x00\x00\x00@o\x81t\x00\x00\x00\x00A\x84Nd\x00\x00\x00\x00BOct\x00\x00\x00\x00Cd0d\x00\x00\x00\x00D/E" + + "t\x00\x00\x00\x00ED\x12d\x00\x00\x00\x00E\xf3w\xf4\x00\x00\x00\x00G-.\xe4\x00\x00\x00\x00G\xd3Y\xf4\x00\x00\x00\x00I\r\x10\xe4\x00\x00\x00\x00I\xb3;\xf4\x00\x00\x00\x00J\xec\xf2\xe4\x00\x00\x00" + + "\x00K\x9cXt\x00\x00\x00\x00L\xd6\x0fd\x00\x00\x00\x00M|:t\x00\x00\x00\x00N\xb6\rH\x00\x00\x00\x00O\\8X\x00\x00\x00\x00P\x95\xefH\x00\x00\x00\x00Q<\x1aX\x00\x00\x00\x00Ru\xd1" + + "H\x00\x00\x00\x00S\x1b\xfcX\x00\x00\x00\x00TU\xb3H\x00\x00\x00\x00T\xfb\xdeX\x00\x00\x00\x00V5\x95H\x00\x00\x00\x00V\xe4\xfa\xd8\x00\x00\x00\x00X\x1e\xb1\xc8\x00\x00\x00\x00X\xc4\xdc\xd8\x00\x00\x00" + + "\x00Y\xfe\x93\xc8\x00\x00\x00\x00Z\xa4\xbe\xd8\x00\x00\x00\x00[\xdeu\xc8\x00\x00\x00\x00\\\x84\xa0\xd8\x00\x00\x00\x00]\xbeW\xc8\x00\x00\x00\x00^d\x82\xd8\x00\x00\x00\x00_\x9e9\xc8\x00\x00\x00\x00`M\x9f" + + "X\x00\x00\x00\x00a\x87VH\x00\x00\x00\x00b-\x81X\x00\x00\x00\x00cg8H\x00\x00\x00\x00d\rcX\x00\x00\x00\x00eG\x1aH\x00\x00\x00\x00e\xedEX\x00\x00\x00\x00g&\xfcH\x00\x00\x00" + + "\x00g\xcd'X\x00\x00\x00\x00i\x06\xdeH\x00\x00\x00\x00i\xad\tX\x00\x00\x00\x00j\xe6\xc0H\x00\x00\x00\x00k\x96%\xd8\x00\x00\x00\x00l\xcf\xdc\xc8\x00\x00\x00\x00mv\a\xd8\x00\x00\x00\x00n\xaf\xbe" + + "\xc8\x00\x00\x00\x00oU\xe9\xd8\x00\x00\x00\x00p\x8f\xa0\xc8\x00\x00\x00\x00q5\xcb\xd8\x00\x00\x00\x00ro\x82\xc8\x00\x00\x00\x00s\x15\xad\xd8\x00\x00\x00\x00tOd\xc8\x00\x00\x00\x00t\xfe\xcaX\x00\x00\x00" + + "\x00v8\x81H\x00\x00\x00\x00vެX\x00\x00\x00\x00x\x18cH\x00\x00\x00\x00x\xbe\x8eX\x00\x00\x00\x00y\xf8EH\x00\x00\x00\x00z\x9epX\x00\x00\x00\x00{\xd8'H\x00\x00\x00\x00|~R" + + "X\x00\x00\x00\x00}\xb8\tH\x00\x00\x00\x00~^4X\x00\x00\x00\x00\u007f\x97\xebH\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x06\x05\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\a\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\xff\xffΔ\x00\x00\xff\xffܤ\x01\x04\xff\xffΔ\x00\b\xff\xff\xdc\xd8\x01\x04\xff\xff\xce\xc8\x00\b\xff\xff\xdc\xd8\x01\f" + + "\xff\xff\xdc\xd8\x01\x10\xff\xff\xea\xe8\x01\x14\xff\xff\xdc\xd8\x01\x04LMT\x00NDT\x00NST\x00NPT\x00NWT\x00NDDT\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" + + "\x00\nNST3:30NDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPd\x8e\xf3\xab4\v\x00\x004\v\x00\x00\x0e\x00\x1c\x00Ca" + + "nada/CentralUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xba\x00\x00\x00\a\x00\x00\x00\x14\x80\x00\x00\x00\x9b\x01\xfb\xe0\x9búP\x9e\xb8\xa1\x80\x9f\xba\xf9p\u00a0;\x80\xc3O\x84\xf0ˈ\xfe\x80\xd2#\xf4p" + + "\xd2a\t\xf0ӈh\x00\xd4S`\xf0\xd5U\xd5\x00\xd6 \xcd\xf0\xd75\xb7\x00\xd8\x00\xaf\xf0\xd9\x15\x99\x00\xd9\xe0\x91\xf0\xdb\x00\a\x00\xdb\xc8\\\xf0\xdcޗ\x80ݩ\x90p\u07bey\x80߉rp" + + "\xe0\x9e[\x80\xe1iTp\xe2~=\x80\xe3I6p\xe4^\x1f\x80\xe5)\x18p\xe6G<\x00\xe7\x124\xf0\xe8'\x1e\x00\xe8\xf2\x16\xf0\xea\a\x00\x00\xea\xd1\xf8\xf0\xeb\xe6\xe2\x00\xec\xd6\xc4\xf0\xed\xc6\xc4\x00" + + "\ue47c\xf0\xf3o\xa4\x80\xf41b\xf0\xf9\x0fJ\x80\xfa\bv\x00\xfa\xf8g\x00\xfb\xe8X\x00\xfc\xd8I\x00\xfd\xc8:\x00\xfe\xb8+\x00\xff\xa8\x1c\x00\x00\x98\r\x00\x01\x87\xfe\x00\x02w\xef\x00\x03q\x1a\x80" + + "\x04a\v\x80\x05P\xfc\x80\x06@\xed\x80\a0ހ\b π\t\x10\xc0\x80\n\x00\xb1\x80\n\xf0\xa2\x80\v\xe0\x93\x80\fٿ\x00\r\xc0u\x80\x0e\xb9\xa1\x00\x0f\xa9\x92\x00\x10\x99\x83\x00\x11\x89t\x00" + + "\x12ye\x00\x13iV\x00\x14YG\x00\x15I8\x00\x169)\x00\x17)\x1a\x00\x18\"E\x80\x19\b\xfc\x00\x1a\x02'\x80\x1a\xf2\x18\x80\x1b\xe2\t\x80\x1c\xd1\xfa\x80\x1d\xc1\xeb\x80\x1e\xb1܀\x1f\xa1̀" + + " v\x0f\x00!\x81\xaf\x80\"U\xf1\x00#j\xcc\x00$5\xd3\x00%J\xae\x00&\x15\xb5\x00'*\x90\x00'\xfeр)\nr\x00)\u07b3\x80*\xeaT\x00+\xbe\x95\x80,\xd3p\x80-\x9ew\x80" + + ".\xb3R\x80/~Y\x800\x934\x801gv\x002s\x16\x803GX\x004R\xf8\x805':\x0062ڀ7\a\x1c\x008\x1b\xf7\x008\xe6\xfe\x009\xfb\xd9\x00:\xc6\xe0\x00;ۻ\x00" + + "<\xaf\xfc\x80=\xbb\x9d\x00>\x8fހ?\x9b\u007f\x00@o\xc0\x80A\x84\x9b\x80BO\xa2\x80Cd}\x80D/\x84\x80EDQpE\xf3\xb7\x00G-m\xf0Gә\x00I\rO\xf0I\xb3{\x00" + + "J\xed1\xf0K\x9c\x97\x80L\xd6NpM|y\x80N\xb60pO\\[\x80P\x96\x12pQ<=\x80Ru\xf4pS\x1c\x1f\x80TU\xd6pT\xfc\x01\x80V5\xb8pV\xe5\x1e\x00X\x1e\xd4\xf0" + + "X\xc5\x00\x00Y\xfe\xb6\xf0Z\xa4\xe2\x00[ޘ\xf0\\\x84\xc4\x00]\xbez\xf0^d\xa6\x00_\x9e\\\xf0`M\u0080a\x87ypb-\xa4\x80cg[pd\r\x86\x80eG=pe\xedh\x80" + + "g'\x1fpg\xcdJ\x80i\a\x01pi\xad,\x80j\xe6\xe3pk\x96I\x00l\xcf\xff\xf0mv+\x00n\xaf\xe1\xf0oV\r\x00p\x8f\xc3\xf0q5\xef\x00ro\xa5\xf0s\x15\xd1\x00tO\x87\xf0" + + "t\xfe\xed\x80v8\xa4pv\xdeπx\x18\x86px\xbe\xb1\x80y\xf8hpz\x9e\x93\x80{\xd8Jp|~u\x80}\xb8,p~^W\x80\u007f\x98\x0ep\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xa4\xec\x00\x00" + + "\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\bLMT\x00CDT\x00CST\x00CWT\x00CPT\x00\x00\x00\x00\x00" + + "\x01\x01\x01\x00\x00\x00\x00\x01\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xba\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xffd\xe4" + + "\xb0\x94\xff\xff\xff\xff\x9b\x01\xfb\xe0\xff\xff\xff\xff\x9búP\xff\xff\xff\xff\x9e\xb8\xa1\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\u00a0;\x80\xff\xff\xff\xff\xc3O\x84\xf0\xff\xff\xff\xffˈ\xfe\x80\xff\xff" + + "\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xffӈh\x00\xff\xff\xff\xff\xd4S`\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00" + + "\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xdb\x00\a\x00\xff\xff\xff\xff\xdb\xc8\\\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff" + + "\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G" + + "<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff" + + "\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\ue47c\xf0\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf41b\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\bv\x00\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8" + + "X\x00\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xef\x00\x00\x00" + + "\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\b π\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\n\x00" + + "\xb1\x80\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00" + + "\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"" + + "E\x80\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1܀\x00\x00" + + "\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15" + + "\xb5\x00\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3p\x80\x00\x00" + + "\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R" + + "\xf8\x80\x00\x00\x00\x005':\x00\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00" + + "\x00\x00;ۻ\x00\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9b\u007f\x00\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO" + + "\xa2\x80\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G-m\xf0\x00\x00\x00\x00Gә\x00\x00\x00\x00\x00I\rO\xf0\x00\x00" + + "\x00\x00I\xb3{\x00\x00\x00\x00\x00J\xed1\xf0\x00\x00\x00\x00K\x9c\x97\x80\x00\x00\x00\x00L\xd6Np\x00\x00\x00\x00M|y\x80\x00\x00\x00\x00N\xb60p\x00\x00\x00\x00O\\[\x80\x00\x00\x00\x00P\x96" + + "\x12p\x00\x00\x00\x00Q<=\x80\x00\x00\x00\x00Ru\xf4p\x00\x00\x00\x00S\x1c\x1f\x80\x00\x00\x00\x00TU\xd6p\x00\x00\x00\x00T\xfc\x01\x80\x00\x00\x00\x00V5\xb8p\x00\x00\x00\x00V\xe5\x1e\x00\x00\x00" + + "\x00\x00X\x1e\xd4\xf0\x00\x00\x00\x00X\xc5\x00\x00\x00\x00\x00\x00Y\xfe\xb6\xf0\x00\x00\x00\x00Z\xa4\xe2\x00\x00\x00\x00\x00[ޘ\xf0\x00\x00\x00\x00\\\x84\xc4\x00\x00\x00\x00\x00]\xbez\xf0\x00\x00\x00\x00^d" + + "\xa6\x00\x00\x00\x00\x00_\x9e\\\xf0\x00\x00\x00\x00`M\u0080\x00\x00\x00\x00a\x87yp\x00\x00\x00\x00b-\xa4\x80\x00\x00\x00\x00cg[p\x00\x00\x00\x00d\r\x86\x80\x00\x00\x00\x00eG=p\x00\x00" + + "\x00\x00e\xedh\x80\x00\x00\x00\x00g'\x1fp\x00\x00\x00\x00g\xcdJ\x80\x00\x00\x00\x00i\a\x01p\x00\x00\x00\x00i\xad,\x80\x00\x00\x00\x00j\xe6\xe3p\x00\x00\x00\x00k\x96I\x00\x00\x00\x00\x00l\xcf" + + "\xff\xf0\x00\x00\x00\x00mv+\x00\x00\x00\x00\x00n\xaf\xe1\xf0\x00\x00\x00\x00oV\r\x00\x00\x00\x00\x00p\x8f\xc3\xf0\x00\x00\x00\x00q5\xef\x00\x00\x00\x00\x00ro\xa5\xf0\x00\x00\x00\x00s\x15\xd1\x00\x00\x00" + + "\x00\x00tO\x87\xf0\x00\x00\x00\x00t\xfe\xed\x80\x00\x00\x00\x00v8\xa4p\x00\x00\x00\x00v\xdeπ\x00\x00\x00\x00x\x18\x86p\x00\x00\x00\x00x\xbe\xb1\x80\x00\x00\x00\x00y\xf8hp\x00\x00\x00\x00z\x9e" + + "\x93\x80\x00\x00\x00\x00{\xd8Jp\x00\x00\x00\x00|~u\x80\x00\x00\x00\x00}\xb8,p\x00\x00\x00\x00~^W\x80\x00\x00\x00\x00\u007f\x98\x0ep\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xa4\xec\x00\x00\xff\xff\xb9\xb0\x01\x04" + + "\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\bLMT\x00CDT\x00CST\x00CWT\x00CPT\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00" + + "\x00\x01\x00\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPI-l\xd2\x1c\t\x00\x00\x1c\t\x00\x00\x0f\x00\x1c\x00Ca" + + "nada/MountainUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x96\x00\x00\x00\x05\x00\x00\x00\x14\x88\xde\xce\xe0\x9e\xb8\xaf\x90\x9f\xbb\a\x80\xa0\x98\x91\x90\xa0҅\x80\xa2\x8a萣\x84\x06\x00\xa4jʐ\xa55\xc3" + + "\x80\xa6S\xe7\x10\xa7\x15\xa5\x80\xa83\xc9\x10\xa8\xfe\xc2\x00ˉ\f\x90\xd2#\xf4p\xd2a\x18\x00\xd5U\xe3\x10\xd6 \xdc\x00\x04a\x19\x90\x05P\xfc\x80\x06@\xfb\x90\a0ހ\b ݐ\t\x10\xc0" + + "\x80\n\x00\xbf\x90\n\xf0\xa2\x80\vࡐ\fٿ\x00\r\xc0\x83\x90\x0e\xb9\xa1\x00\x0f\xa9\xa0\x10\x10\x99\x83\x00\x11\x89\x82\x10\x12ye\x00\x13id\x10\x14YG\x00\x15IF\x10\x169)\x00\x17)(" + + "\x10\x18\"E\x80\x19\t\n\x10\x1a\x02'\x80\x1a\xf2&\x90\x1b\xe2\t\x80\x1c\xd2\b\x90\x1d\xc1\xeb\x80\x1e\xb1\xea\x90\x1f\xa1̀ v\x1d\x10!\x81\xaf\x80\"U\xff\x10#j\xcc\x00$5\xe1\x10%J\xae" + + "\x00&\x15\xc3\x10'*\x90\x00'\xfeߐ)\nr\x00)\xde\xc1\x90*\xeaT\x00+\xbe\xa3\x90,\xd3p\x80-\x9e\x85\x90.\xb3R\x80/~g\x900\x934\x801g\x84\x102s\x16\x803Gf" + + "\x104R\xf8\x805'H\x1062ڀ7\a*\x108\x1b\xf7\x008\xe7\f\x109\xfb\xd9\x00:\xc6\xee\x10;ۻ\x00<\xb0\n\x90=\xbb\x9d\x00>\x8f\xec\x90?\x9b\u007f\x00@oΐA\x84\x9b" + + "\x80BO\xb0\x90Cd}\x80D/\x92\x90ED_\x80E\xf3\xc5\x10G-|\x00Gӧ\x10I\r^\x00I\xb3\x89\x10J\xed@\x00K\x9c\xa5\x90L\xd6\\\x80M|\x87\x90N\xb6>\x80O\\i" + + "\x90P\x96 \x80Q\x8f\xec\x90\x00\x00\x00\x00?\x9b\u007f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00" + + "\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x00\x00\x00\x00G-|\x00\x00\x00\x00\x00Gӧ\x10\x00\x00\x00\x00I\r^\x00\x00\x00\x00\x00I" + + "\xb3\x89\x10\x00\x00\x00\x00J\xed@\x00\x00\x00\x00\x00K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\\\x80\x00\x00\x00\x00M|\x87\x90\x00\x00\x00\x00N\xb6>\x80\x00\x00\x00\x00O\\i\x90\x00\x00\x00\x00P\x96 \x80\x00" + + "\x00\x00\x00QO@\x06\x00\r\xb0\a\v\xbc@\a\xdf\xef\xb0\b\xfe\x13@\t\xbfѰ\n\xdd\xf5@\v\xa8\xee0\f\xbd\xd7@\r\x88\xd00\x0e\x9d\xb9" + + "@\x0fh\xb20\x10\x86\xd5\xc0\x11H\x940\x12f\xb7\xc0\x13(v0\x14F\x99\xc0\x15\x11\x92\xb0\x16&{\xc0\x16\xf1t\xb0\x18\x06]\xc0\x18\xd1V\xb0\x19\xe6?\xc0\x1a\xb18\xb0\x1b\xcf\\@\x1c\x91\x1a" + + "\xb0\x1d\xaf>@\x1ep\xfc\xb0\x1f\x8f @ \u007f\x030!o\x02@\"9\xfb0#N\xe4@$\x19\xdd0%8\x00\xc0%\xf9\xbf0&\xf2\xf8\xc0'١0(\xf7\xc4\xc0)½\xb0*צ" + + "\xc0+\xa2\x9f\xb0,\xb7\x88\xc0-\x82\x81\xb0.\x97j\xc0/bc\xb00\x80\x87@1BE\xb02`i@3=\xd704@K@5\vD06\r\xb8@7\x06հ8\x00\x0f@8\xcb\b" + + "09\xe9+\xc0:\xaa\xea0;\xc9\r\xc0<\x8a\xcc0=\xa8\xef\xc0>j\xae0?\x88\xd1\xc0@SʰAh\xb3\xc0B3\xac\xb0CH\x95\xc0D\x13\x8e\xb0E1\xb2@E\xf3p\xb0G\x11\x94" + + "@G\xef\x020H\xf1v@I\xbco0J\xd1X@K\xb8\x00\xb0L\xb1:@M\xc6\a0NP\x82\xc0O\x9c\xae\xb0PB\xd9\xc0Q|\x90\xb0R+\xf6@S\\r\xb0T\v\xd8@W7\xe6" + + "0W\xaf\xec\xc0Y\x17\xc80Y\x8f\xce\xc0Z\xf7\xaa0[o\xb0\xc0\\\xa9g\xb0]t|\xc0^\x89I\xb0_T^\xc0`i+\xb0a4@\xc0bI\r\xb0c\x14\"\xc0d(\xef\xb0d\xf4\x04" + + "\xc0f\x12\f0f\xdd!@g\xf1\xee0h\xbd\x03@i\xd1\xd00j\x9c\xe5@k\xb1\xb20l|\xc7@m\x91\x940n\\\xa9@oz\xb0\xb0p<\x8b@qZ\x92\xb0r%\xa7\xc0s:t" + + "\xb0t\x05\x89\xc0u\x1aV\xb0u\xe5k\xc0v\xfa8\xb0w\xc5M\xc0x\xda\x1a\xb0y\xa5/\xc0z\xc370{\x85\x11\xc0|\xa3\x190}n.@~\x82\xfb0\u007fN\x10@\u007f\xff\xff\xff\x01\x04\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x06\xff\xff\x99x\x00\x00\xff\xff\x99x\x00\x04\xff\xff\xab\xa0\x01\b\xff\xff\x9d\x90\x00\f\xff\xff\x9d\x90\x00\f\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\x10L" + + "MT\x00EMT\x00-06\x00-07\x00-05\x00\x00\x00\x01\x01\x00\x01\x01\x00\x00\x01\x01\x00\x01\x01TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00" + + "\a\x00\x00\x00\x00\x00\x00\x00\x8c\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xffi\x87B\b\xff\xff\xff\xff\xb9\xc7@\x88\xff\xff\xff\xff\xfd\xd1<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00\x00" + + "\x00\x00rܰ\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00\x02@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +\xb0\x00\x00\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\r\xb0\x00\x00\x00\x00\a\v\xbc" + + "@\x00\x00\x00\x00\a\xdf\xef\xb0\x00\x00\x00\x00\b\xfe\x13@\x00\x00\x00\x00\t\xbfѰ\x00\x00\x00\x00\n\xdd\xf5@\x00\x00\x00\x00\v\xa8\xee0\x00\x00\x00\x00\f\xbd\xd7@\x00\x00\x00\x00\r\x88\xd00\x00\x00\x00" + + "\x00\x0e\x9d\xb9@\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00\x10\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11\x92" + + "\xb0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00" + + "\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \u007f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"9\xfb0\x00\x00\x00\x00#N\xe4" + + "@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'١0\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)½\xb0\x00\x00\x00" + + "\x00*צ\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE" + + "\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\vD0\x00\x00\x00\x006\r\xb8@\x00\x00\x00\x007\x06հ\x00\x00\x00\x008\x00\x0f@\x00\x00\x00" + + "\x008\xcb\b0\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1" + + "\xc0\x00\x00\x00\x00@Sʰ\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00" + + "\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\a" + + "0\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T\v\xd8@\x00\x00\x00" + + "\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00Y\x17\xc80\x00\x00\x00\x00Y\x8f\xce\xc0\x00\x00\x00\x00Z\xf7\xaa0\x00\x00\x00\x00[o\xb0\xc0\x00\x00\x00\x00\\\xa9g\xb0\x00\x00\x00\x00]t|" + + "\xc0\x00\x00\x00\x00^\x89I\xb0\x00\x00\x00\x00_T^\xc0\x00\x00\x00\x00`i+\xb0\x00\x00\x00\x00a4@\xc0\x00\x00\x00\x00bI\r\xb0\x00\x00\x00\x00c\x14\"\xc0\x00\x00\x00\x00d(\xef\xb0\x00\x00\x00" + + "\x00d\xf4\x04\xc0\x00\x00\x00\x00f\x12\f0\x00\x00\x00\x00f\xdd!@\x00\x00\x00\x00g\xf1\xee0\x00\x00\x00\x00h\xbd\x03@\x00\x00\x00\x00i\xd1\xd00\x00\x00\x00\x00j\x9c\xe5@\x00\x00\x00\x00k\xb1\xb2" + + "0\x00\x00\x00\x00l|\xc7@\x00\x00\x00\x00m\x91\x940\x00\x00\x00\x00n\\\xa9@\x00\x00\x00\x00oz\xb0\xb0\x00\x00\x00\x00p<\x8b@\x00\x00\x00\x00qZ\x92\xb0\x00\x00\x00\x00r%\xa7\xc0\x00\x00\x00" + + "\x00s:t\xb0\x00\x00\x00\x00t\x05\x89\xc0\x00\x00\x00\x00u\x1aV\xb0\x00\x00\x00\x00u\xe5k\xc0\x00\x00\x00\x00v\xfa8\xb0\x00\x00\x00\x00w\xc5M\xc0\x00\x00\x00\x00x\xda\x1a\xb0\x00\x00\x00\x00y\xa5/" + + "\xc0\x00\x00\x00\x00z\xc370\x00\x00\x00\x00{\x85\x11\xc0\x00\x00\x00\x00|\xa3\x190\x00\x00\x00\x00}n.@\x00\x00\x00\x00~\x82\xfb0\x00\x00\x00\x00\u007fN\x10@\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x04\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x06\xff\xff\x99x\x00\x00\xff\xff\x99x\x00\x04\xff\xff\xab\xa0\x01\b\xff\xff\x9d\x90\x00\f\xff\xff\x9d\x90\x00\f\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\x10L" + + "MT\x00EMT\x00-06\x00-07\x00-05\x00\x00\x00\x01\x01\x00\x01\x01\x00\x00\x01\x01\x00\x01\x01\n<-06>6<-05>,M9.1.6/22,M4.1" + + ".6/22\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP|p&\x14\xe1\t\x00\x00\xe1\t\x00\x00\x11\x00\x1c\x00Chile/ContinentalUT\t\x00\x03n\xd3" + + "\xa7^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\xa0\x00\x00\x00" + + "\b\x00\x00\x00\x14\x80\x00\x00\x00\x8f0GF\x9b\\\xe5P\x9f|\xe2ơ\x00q\xc0\xb0^wƱw=@\xb2A\x00гXp\xc0\xb4\"4P\xb59\xa4@\xb6\x03gз\x1a\xd7\xc0\xb7\xe4\x9b" + + "P\xb8\xfd\\\xc0\xb9\xc7 P\xcc\x1cn@\xccl\xe7\xd0\xd3\u070f\xc0\xd4\x1bɰ\xd53U\xc0\xd5v\x92@\xfd\xd1<@\xfe\x92\xfa\xb0\xff\xcc\xcd\xc0\x00rܰ\x01uP\xc0\x02@I\xb0\x03U2" + + "\xc0\x04 +\xb0\x05>O@\x06\x00\r\xb0\a\v\xbc@\a\xdf\xef\xb0\b\xfe\x13@\t\xbfѰ\n\xdd\xf5@\v\xa8\xee0\f\xbd\xd7@\r\x88\xd00\x0e\x9d\xb9@\x0fh\xb20\x10\x86\xd5\xc0\x11H\x94" + + "0\x12f\xb7\xc0\x13(v0\x14F\x99\xc0\x15\x11\x92\xb0\x16&{\xc0\x16\xf1t\xb0\x18\x06]\xc0\x18\xd1V\xb0\x19\xe6?\xc0\x1a\xb18\xb0\x1b\xcf\\@\x1c\x91\x1a\xb0\x1d\xaf>@\x1ep\xfc\xb0\x1f\x8f " + + "@ \u007f\x030!o\x02@\"9\xfb0#N\xe4@$\x19\xdd0%8\x00\xc0%\xf9\xbf0&\xf2\xf8\xc0'١0(\xf7\xc4\xc0)½\xb0*צ\xc0+\xa2\x9f\xb0,\xb7\x88\xc0-\x82\x81" + + "\xb0.\x97j\xc0/bc\xb00\x80\x87@1BE\xb02`i@3=\xd704@K@5\vD06\r\xb8@7\x06հ8\x00\x0f@8\xcb\b09\xe9+\xc0:\xaa\xea0;\xc9\r" + + "\xc0<\x8a\xcc0=\xa8\xef\xc0>j\xae0?\x88\xd1\xc0@SʰAh\xb3\xc0B3\xac\xb0CH\x95\xc0D\x13\x8e\xb0E1\xb2@E\xf3p\xb0G\x11\x94@G\xef\x020H\xf1v@I\xbco" + + "0J\xd1X@K\xb8\x00\xb0L\xb1:@M\xc6\a0NP\x82\xc0O\x9c\xae\xb0PB\xd9\xc0Q|\x90\xb0R+\xf6@S\\r\xb0T\v\xd8@W7\xe60W\xaf\xec\xc0Y\x17\xc80Y\x8f\xce" + + "\xc0Z\xf7\xaa0[o\xb0\xc0\\\xa9g\xb0]t|\xc0^\x89I\xb0_T^\xc0`i+\xb0a4@\xc0bI\r\xb0c\x14\"\xc0d(\xef\xb0d\xf4\x04\xc0f\x12\f0f\xdd!@g\xf1\xee" + + "0h\xbd\x03@i\xd1\xd00j\x9c\xe5@k\xb1\xb20l|\xc7@m\x91\x940n\\\xa9@oz\xb0\xb0p<\x8b@qZ\x92\xb0r%\xa7\xc0s:t\xb0t\x05\x89\xc0u\x1aV\xb0u\xe5k" + + "\xc0v\xfa8\xb0w\xc5M\xc0x\xda\x1a\xb0y\xa5/\xc0z\xc370{\x85\x11\xc0|\xa3\x190}n.@~\x82\xfb0\u007fN\x10@\u007f\xff\xff\xff\x01\x02\x01\x03\x01\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02" + + "\x03\x02\x03\x05\x03\x02\x03\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" + + "\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" + + "\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\x06\xff\xff\xbd\xba\x00\x00\xff\xff\xbd\xba\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\f\xff\xff\xc7\xc0\x01\f\xff\xff\xd5\xd0\x01" + + "\x10\xff\xff\xd5\xd0\x01\x10\xff\xff\xc7\xc0\x00\fLMT\x00SMT\x00-05\x00-04\x00-03\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x01\x01TZif3\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\xa0\x00\x00\x00\b\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x1d\xc6\xff\xff\xff\xff\x8f0GF\xff\xff\xff\xff\x9b\\\xe5P\xff\xff\xff" + + "\xff\x9f|\xe2\xc6\xff\xff\xff\xff\xa1\x00q\xc0\xff\xff\xff\xff\xb0^w\xc6\xff\xff\xff\xff\xb1w=@\xff\xff\xff\xff\xb2A\x00\xd0\xff\xff\xff\xff\xb3Xp\xc0\xff\xff\xff\xff\xb4\"4P\xff\xff\xff\xff\xb59\xa4" + + "@\xff\xff\xff\xff\xb6\x03g\xd0\xff\xff\xff\xff\xb7\x1a\xd7\xc0\xff\xff\xff\xff\xb7\xe4\x9bP\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xc7 P\xff\xff\xff\xff\xcc\x1cn@\xff\xff\xff\xff\xccl\xe7\xd0\xff\xff\xff" + + "\xff\xd3\u070f\xc0\xff\xff\xff\xff\xd4\x1bɰ\xff\xff\xff\xff\xd53U\xc0\xff\xff\xff\xff\xd5v\x92@\xff\xff\xff\xff\xfd\xd1<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00\x00\x00\x00r\xdc" + + "\xb0\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00\x02@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +\xb0\x00\x00\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\r\xb0\x00\x00\x00\x00\a\v\xbc@\x00\x00\x00" + + "\x00\a\xdf\xef\xb0\x00\x00\x00\x00\b\xfe\x13@\x00\x00\x00\x00\t\xbfѰ\x00\x00\x00\x00\n\xdd\xf5@\x00\x00\x00\x00\v\xa8\xee0\x00\x00\x00\x00\f\xbd\xd7@\x00\x00\x00\x00\r\x88\xd00\x00\x00\x00\x00\x0e\x9d\xb9" + + "@\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00\x10\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11\x92\xb0\x00\x00\x00" + + "\x00\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\x91\x1a" + + "\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \u007f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"9\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00" + + "\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'١0\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)½\xb0\x00\x00\x00\x00*צ" + + "\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00" + + "\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\vD0\x00\x00\x00\x006\r\xb8@\x00\x00\x00\x007\x06հ\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\b" + + "0\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00" + + "\x00@Sʰ\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94" + + "@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\a0\x00\x00\x00" + + "\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T\v\xd8@\x00\x00\x00\x00W7\xe6" + + "0\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00Y\x17\xc80\x00\x00\x00\x00Y\x8f\xce\xc0\x00\x00\x00\x00Z\xf7\xaa0\x00\x00\x00\x00[o\xb0\xc0\x00\x00\x00\x00\\\xa9g\xb0\x00\x00\x00\x00]t|\xc0\x00\x00\x00" + + "\x00^\x89I\xb0\x00\x00\x00\x00_T^\xc0\x00\x00\x00\x00`i+\xb0\x00\x00\x00\x00a4@\xc0\x00\x00\x00\x00bI\r\xb0\x00\x00\x00\x00c\x14\"\xc0\x00\x00\x00\x00d(\xef\xb0\x00\x00\x00\x00d\xf4\x04" + + "\xc0\x00\x00\x00\x00f\x12\f0\x00\x00\x00\x00f\xdd!@\x00\x00\x00\x00g\xf1\xee0\x00\x00\x00\x00h\xbd\x03@\x00\x00\x00\x00i\xd1\xd00\x00\x00\x00\x00j\x9c\xe5@\x00\x00\x00\x00k\xb1\xb20\x00\x00\x00" + + "\x00l|\xc7@\x00\x00\x00\x00m\x91\x940\x00\x00\x00\x00n\\\xa9@\x00\x00\x00\x00oz\xb0\xb0\x00\x00\x00\x00p<\x8b@\x00\x00\x00\x00qZ\x92\xb0\x00\x00\x00\x00r%\xa7\xc0\x00\x00\x00\x00s:t" + + "\xb0\x00\x00\x00\x00t\x05\x89\xc0\x00\x00\x00\x00u\x1aV\xb0\x00\x00\x00\x00u\xe5k\xc0\x00\x00\x00\x00v\xfa8\xb0\x00\x00\x00\x00w\xc5M\xc0\x00\x00\x00\x00x\xda\x1a\xb0\x00\x00\x00\x00y\xa5/\xc0\x00\x00\x00" + + "\x00z\xc370\x00\x00\x00\x00{\x85\x11\xc0\x00\x00\x00\x00|\xa3\x190\x00\x00\x00\x00}n.@\x00\x00\x00\x00~\x82\xfb0\x00\x00\x00\x00\u007fN\x10@\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x01\x03\x01\x04\x02" + + "\x04\x02\x04\x02\x04\x02\x04\x02\x03\x02\x03\x05\x03\x02\x03\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" + + "\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" + + "\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\x06\xff\xff\xbd\xba\x00\x00\xff\xff\xbd\xba\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\f\xff\xff\xc7" + + "\xc0\x01\f\xff\xff\xd5\xd0\x01\x10\xff\xff\xd5\xd0\x01\x10\xff\xff\xc7\xc0\x00\fLMT\x00SMT\x00-05\x00-04\x00-03\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x01\x01\n<-" + + "04>4<-03>,M9.1.6/24,M4.1.6/24\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPAkx\xeap\t\x00\x00p\t\x00\x00\x04\x00\x1c\x00" + + "CubaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06" + + "\x00\x00\x00\x00\x00\x00\x00\x9c\x00\x00\x00\x06\x00\x00\x00\x10\x80\x00\x00\x00\xacb\u0080\xb1ӔP\xb2t]@\xc8[f\xd0\xc8\xd3Q@\xca;H\xd0ʼm\xc0\xcc$eP̜O\xc0\xd1\xc4\vP" + + "\xd2;\xf5\xc0ӣ\xedP\xd4\x1b\xd7\xc0\xf7`\x05\xd0\xf7\xff}@\xf9=D\xd0\xf9\xe3S\xc0\xfa\xdb;\xd0\xfb\xa7\x86@\xfcũ\xd0\xfd\x87h@\xfe\xb8\x00\xd0\xff\xa7\xe3\xc0\x00\x97\xe2\xd0\x01\x87\xc5\xc0" + + "\x02w\xc4\xd0\x03p\xe2@\x04`\xe1P\x055\x14\xc0\x06@\xc3P\a\x16H@\b \xa5P\b\xf7{\xc0\n\x00\x87P\n\xf0j@\v\xe0iP\fن\xc0\r\xc0KP\x0e\xb9h\xc0\x0f\xb2\xa2P" + + "\x10}\x9b@\x11Q\xea\xd0\x12f\xb7\xc0\x131\xcc\xd0\x14F\x99\xc0\x15[\x82\xd0\x16&{\xc0\x17;d\xd0\x18\x06]\xc0\x19\x1bF\xd0\x19\xe6?\xc0\x1a\xfb(\xd0\x1b\xcf\\@\x1c\xdb\n\xd0\x1d\xaf>@" + + "\x1ezSP\x1f\x8f @ Z5P!o\x02@\"CQ\xd0#N\xe4@$#3\xd0%.\xc6@&\x15\x8a\xd0'\x17\xe2\xc0'\xfe\xa7P(\xf7\xd2\xd0)މP*״\xd0+\xbekP" + + ",\xb7\x96\xd0-\x9eMP.\x97x\xd0/~/P0wZ\xd01gK\xd02W<\xd03G-\xd04@YP5\x1d\xd5P62\xb0P6\xfd\xb7P8\x1b\xcc\xd08\xe6\xd3\xd09\xfb\xae\xd0" + + ":Ƶ\xd0;ې\xd0<\xaf\xd2P=\xbbr\xd0>\x8f\xb4P?\x9bT\xd0@f[\xd0ED5PE\xf3\x8c\xd0G$\x17PGܩPI\x03\xf9PI\xb3P\xd0J\xe3\xdbPK\x9cmP" + + "L\xcc\xf7\xd0M\x85\x89\xd0N\xbfN\xd0Ow\xe0\xd0P\x95\xf6PQ<\x13PRu\xd8PS\x1b\xf5PTU\xbaPT\xfb\xd7PV5\x9cPV\xe4\xf3\xd0X\x1e\xb8\xd0X\xc4\xd5\xd0Y\xfe\x9a\xd0" + + "Z\xa4\xb7\xd0[\xde|\xd0\\\x84\x99\xd0]\xbe^\xd0^d{\xd0_\x9e@\xd0`M\x98Pa\x87]Pb-zPcg?Pd\r\\PeG!Pe\xed>Pg'\x03Pg\xcd P" + + "i\x06\xe5Pi\xad\x02Pj\xe6\xc7Pk\x96\x1e\xd0l\xcf\xe3\xd0mv\x00\xd0n\xaf\xc5\xd0oU\xe2\xd0p\x8f\xa7\xd0q5\xc4\xd0ro\x89\xd0s\x15\xa6\xd0tOk\xd0t\xfe\xc3Pv8\x88P" + + "vޥPx\x18jPx\xbe\x87Py\xf8LPz\x9eiP{\xd8.P|~KP}\xb8\x10P~^-P\u007f\x97\xf2P\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\xff\xff\xb2\xc8\x00\x00\xff\xff\xb2\xc0\x00\x04\xff\xff\xc7\xc0\x01\b\xff\xff\xb9\xb0\x00\f\xff\xff\xb9\xb0\x00\f\xff\xff\xc7\xc0\x01\bLMT\x00HMT\x00" + + "CDT\x00CST\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x9c\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff" + + "\xff\xffi\x87(\xb8\xff\xff\xff\xff\xacb\u0080\xff\xff\xff\xff\xb1ӔP\xff\xff\xff\xff\xb2t]@\xff\xff\xff\xff\xc8[f\xd0\xff\xff\xff\xff\xc8\xd3Q@\xff\xff\xff\xff\xca;H\xd0\xff\xff\xff\xffʼ" + + "m\xc0\xff\xff\xff\xff\xcc$eP\xff\xff\xff\xff̜O\xc0\xff\xff\xff\xff\xd1\xc4\vP\xff\xff\xff\xff\xd2;\xf5\xc0\xff\xff\xff\xffӣ\xedP\xff\xff\xff\xff\xd4\x1b\xd7\xc0\xff\xff\xff\xff\xf7`\x05\xd0\xff\xff" + + "\xff\xff\xf7\xff}@\xff\xff\xff\xff\xf9=D\xd0\xff\xff\xff\xff\xf9\xe3S\xc0\xff\xff\xff\xff\xfa\xdb;\xd0\xff\xff\xff\xff\xfb\xa7\x86@\xff\xff\xff\xff\xfcũ\xd0\xff\xff\xff\xff\xfd\x87h@\xff\xff\xff\xff\xfe\xb8" + + "\x00\xd0\xff\xff\xff\xff\xff\xa7\xe3\xc0\x00\x00\x00\x00\x00\x97\xe2\xd0\x00\x00\x00\x00\x01\x87\xc5\xc0\x00\x00\x00\x00\x02w\xc4\xd0\x00\x00\x00\x00\x03p\xe2@\x00\x00\x00\x00\x04`\xe1P\x00\x00\x00\x00\x055\x14\xc0\x00\x00" + + "\x00\x00\x06@\xc3P\x00\x00\x00\x00\a\x16H@\x00\x00\x00\x00\b \xa5P\x00\x00\x00\x00\b\xf7{\xc0\x00\x00\x00\x00\n\x00\x87P\x00\x00\x00\x00\n\xf0j@\x00\x00\x00\x00\v\xe0iP\x00\x00\x00\x00\f\xd9" + + "\x86\xc0\x00\x00\x00\x00\r\xc0KP\x00\x00\x00\x00\x0e\xb9h\xc0\x00\x00\x00\x00\x0f\xb2\xa2P\x00\x00\x00\x00\x10}\x9b@\x00\x00\x00\x00\x11Q\xea\xd0\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x131\xcc\xd0\x00\x00" + + "\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15[\x82\xd0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x17;d\xd0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x19\x1bF\xd0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xfb" + + "(\xd0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\xdb\n\xd0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ezSP\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 Z5P\x00\x00\x00\x00!o\x02@\x00\x00" + + "\x00\x00\"CQ\xd0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$#3\xd0\x00\x00\x00\x00%.\xc6@\x00\x00\x00\x00&\x15\x8a\xd0\x00\x00\x00\x00'\x17\xe2\xc0\x00\x00\x00\x00'\xfe\xa7P\x00\x00\x00\x00(\xf7" + + "\xd2\xd0\x00\x00\x00\x00)މP\x00\x00\x00\x00*״\xd0\x00\x00\x00\x00+\xbekP\x00\x00\x00\x00,\xb7\x96\xd0\x00\x00\x00\x00-\x9eMP\x00\x00\x00\x00.\x97x\xd0\x00\x00\x00\x00/~/P\x00\x00" + + "\x00\x000wZ\xd0\x00\x00\x00\x001gK\xd0\x00\x00\x00\x002W<\xd0\x00\x00\x00\x003G-\xd0\x00\x00\x00\x004@YP\x00\x00\x00\x005\x1d\xd5P\x00\x00\x00\x0062\xb0P\x00\x00\x00\x006\xfd" + + "\xb7P\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xd3\xd0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:Ƶ\xd0\x00\x00\x00\x00;ې\xd0\x00\x00\x00\x00<\xaf\xd2P\x00\x00\x00\x00=\xbbr\xd0\x00\x00" + + "\x00\x00>\x8f\xb4P\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@f[\xd0\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x8c\xd0\x00\x00\x00\x00G$\x17P\x00\x00\x00\x00GܩP\x00\x00\x00\x00I\x03" + + "\xf9P\x00\x00\x00\x00I\xb3P\xd0\x00\x00\x00\x00J\xe3\xdbP\x00\x00\x00\x00K\x9cmP\x00\x00\x00\x00L\xcc\xf7\xd0\x00\x00\x00\x00M\x85\x89\xd0\x00\x00\x00\x00N\xbfN\xd0\x00\x00\x00\x00Ow\xe0\xd0\x00\x00" + + "\x00\x00P\x95\xf6P\x00\x00\x00\x00Q<\x13P\x00\x00\x00\x00Ru\xd8P\x00\x00\x00\x00S\x1b\xf5P\x00\x00\x00\x00TU\xbaP\x00\x00\x00\x00T\xfb\xd7P\x00\x00\x00\x00V5\x9cP\x00\x00\x00\x00V\xe4" + + "\xf3\xd0\x00\x00\x00\x00X\x1e\xb8\xd0\x00\x00\x00\x00X\xc4\xd5\xd0\x00\x00\x00\x00Y\xfe\x9a\xd0\x00\x00\x00\x00Z\xa4\xb7\xd0\x00\x00\x00\x00[\xde|\xd0\x00\x00\x00\x00\\\x84\x99\xd0\x00\x00\x00\x00]\xbe^\xd0\x00\x00" + + "\x00\x00^d{\xd0\x00\x00\x00\x00_\x9e@\xd0\x00\x00\x00\x00`M\x98P\x00\x00\x00\x00a\x87]P\x00\x00\x00\x00b-zP\x00\x00\x00\x00cg?P\x00\x00\x00\x00d\r\\P\x00\x00\x00\x00eG" + + "!P\x00\x00\x00\x00e\xed>P\x00\x00\x00\x00g'\x03P\x00\x00\x00\x00g\xcd P\x00\x00\x00\x00i\x06\xe5P\x00\x00\x00\x00i\xad\x02P\x00\x00\x00\x00j\xe6\xc7P\x00\x00\x00\x00k\x96\x1e\xd0\x00\x00" + + "\x00\x00l\xcf\xe3\xd0\x00\x00\x00\x00mv\x00\xd0\x00\x00\x00\x00n\xaf\xc5\xd0\x00\x00\x00\x00oU\xe2\xd0\x00\x00\x00\x00p\x8f\xa7\xd0\x00\x00\x00\x00q5\xc4\xd0\x00\x00\x00\x00ro\x89\xd0\x00\x00\x00\x00s\x15" + + "\xa6\xd0\x00\x00\x00\x00tOk\xd0\x00\x00\x00\x00t\xfe\xc3P\x00\x00\x00\x00v8\x88P\x00\x00\x00\x00vޥP\x00\x00\x00\x00x\x18jP\x00\x00\x00\x00x\xbe\x87P\x00\x00\x00\x00y\xf8LP\x00\x00" + + "\x00\x00z\x9eiP\x00\x00\x00\x00{\xd8.P\x00\x00\x00\x00|~KP\x00\x00\x00\x00}\xb8\x10P\x00\x00\x00\x00~^-P\x00\x00\x00\x00\u007f\x97\xf2P\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04" + + "\x02\x04\x02\x04\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\xff\xff\xb2\xc8\x00\x00\xff\xff\xb2\xc0\x00\x04\xff\xff\xc7\xc0\x01\b\xff\xff\xb9\xb0\x00\f\xff\xff\xb9\xb0\x00\f\xff\xff\xc7\xc0\x01\bLM" + + "T\x00HMT\x00CDT\x00CST\x00\x00\x00\x00\x00\x01\x01\nCST5CDT,M3.2.0/0,M11.1.0/1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F" + + "\x9cP[\r\x01\x02t\a\x00\x00t\a\x00\x00\x03\x00\x1c\x00EETUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00z\x00\x00\x00\x04\x00\x00\x00\t\r\xa4c\x90\x0e\x8b\x1a\x10\x0f\x84E\x90\x10t6\x90\x11d'\x90\x12T\x18\x90\x13MD" + + "\x10\x143\xfa\x90\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c" + + "\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa" + + "\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(" + + "\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g\xe8\x97" + + "\x90h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15" + + "\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01" + + "\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01" + + "\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x00\x1c \x00\x05\x00\x00*0\x01\x00\x00\x00*0\x01" + + "\x00\x00\x00\x1c \x00\x05EEST\x00EET\x00\x01\x01\x01\x01\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00z" + + "\x00\x00\x00\x04\x00\x00\x00\t\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00" + + "\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90" + + "\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00" + + "!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90" + + "\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00" + + "K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90" + + "\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00" + + "Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10" + + "\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00" + + "g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10" + + "\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00" + + "v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090" + + "\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00" + + "\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00" + + "\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x00\x1c \x00\x05\x00\x00*0\x01\x00\x00\x00*0\x01\x00\x00\x00\x1c \x00\x05EEST\x00EET\x00\x01" + + "\x01\x01\x01\x01\x01\x01\x01\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPH\x02\x8b\xd7r\x00\x00\x00r" + + "\x00\x00\x00\x03\x00\x1c\x00ESTUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xb9\xb0\x00\x00EST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xb9\xb0\x00\x00EST\x00\nEST5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP$'\x1c\x82\x06\t\x00\x00\x06\t\x00\x00\a\x00" + + "\x1c\x00EST5EDTUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x95\x00\x00\x00\x05\x00\x00\x00\x10\x9e\xa6\x1ep\x9f\xba\xeb`\xa0\x86\x00p\xa1\x9a\xcd`ˈ\xf0p\xd2#\xf4p\xd2`\xfb\xe0\xfa\xf8X\xf0\xfb\xe8;\xe0\xfc\xd8:" + + "\xf0\xfd\xc8\x1d\xe0\xfe\xb8\x1c\xf0\xff\xa7\xff\xe0\x00\x97\xfe\xf0\x01\x87\xe1\xe0\x02w\xe0\xf0\x03p\xfe`\x04`\xfdp\x05P\xe0`\x06@\xdfp\a0\xc2`\a\x8d\x19p\t\x10\xa4`\t\xad\x94\xf0\n\xf0\x86" + + "`\v\xe0\x85p\f٢\xe0\r\xc0gp\x0e\xb9\x84\xe0\x0f\xa9\x83\xf0\x10\x99f\xe0\x11\x89e\xf0\x12yH\xe0\x13iG\xf0\x14Y*\xe0\x15I)\xf0\x169\f\xe0\x17)\v\xf0\x18\")`\x19\b\xed" + + "\xf0\x1a\x02\v`\x1a\xf2\np\x1b\xe1\xed`\x1c\xd1\xecp\x1d\xc1\xcf`\x1e\xb1\xcep\x1f\xa1\xb1` v\x00\xf0!\x81\x93`\"U\xe2\xf0#j\xaf\xe0$5\xc4\xf0%J\x91\xe0&\x15\xa6\xf0'*s" + + "\xe0'\xfe\xc3p)\nU\xe0)ޥp*\xea7\xe0+\xbe\x87p,\xd3T`-\x9eip.\xb36`/~Kp0\x93\x18`1gg\xf02r\xfa`3GI\xf04R\xdc`5'+" + + "\xf062\xbe`7\a\r\xf08\x1b\xda\xe08\xe6\xef\xf09\xfb\xbc\xe0:\xc6\xd1\xf0;۞\xe0<\xaf\xeep=\xbb\x80\xe0>\x8f\xd0p?\x9bb\xe0@o\xb2pA\x84\u007f`BO\x94pCda" + + "`D/vpEDC`E\xf3\xa8\xf0G-_\xe0Gӊ\xf0I\rA\xe0I\xb3l\xf0J\xed#\xe0K\x9c\x89pL\xd6@`M|kpN\xb6\"`O\\MpP\x96\x04`Q\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\u007f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00ED" + + "C`\x00\x00\x00\x00E\xf3\xa8\xf0\x00\x00\x00\x00G-_\xe0\x00\x00\x00\x00Gӊ\xf0\x00\x00\x00\x00I\rA\xe0\x00\x00\x00\x00I\xb3l\xf0\x00\x00\x00\x00J\xed#\xe0\x00\x00\x00\x00K\x9c\x89p\x00\x00" + + "\x00\x00L\xd6@`\x00\x00\x00\x00M|kp\x00\x00\x00\x00N\xb6\"`\x00\x00\x00\x00O\\Mp\x00\x00\x00\x00P\x96\x04`\x00\x00\x00\x00Q\xa8^`?s" + + "WP@\x91z\xe0A\\s\xd0Bq\\\xe0C\xe0E\x12\xfdPF1 \xe0F\xe0jPH\x11\x02\xe0H\xb7\x11\xd0I\xf0\xe4\xe0J\x8d\xb9PK\xda\x01`La\xbd\xd0L\x89" + + "X\xe0L\xa4\xfaPSu8\xe0S\xac\x89\xd0Sڼ`T$\x82P\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x01\x02\x01\x02\x01\x02\x00\x00\x1dU\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x01\x04LMT\x00EES" + + "T\x00EET\x00\x00\x00\x00\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\u007f\x00\x00\x00\x04\x00\x00\x00\r\xff\xff\xff\xff}\xbd" + + "M\xab\xff\xff\xff\xffȓ\xb4\xe0\xff\xff\xff\xff\xc8\xfa{\xd0\xff\xff\xff\xff\xc9\xfc\xef\xe0\xff\xff\xff\xff\xca\xc7\xe8\xd0\xff\xff\xff\xff\xcbˮ`\xff\xff\xff\xff\xcc\xdf)\xd0\xff\xff\xff\xffͬ\xe1\xe0\xff\xff" + + "\xff\xff\xce\xc6\xf4\xd0\xff\xff\xff\xffϏf\xe0\xff\xff\xff\xffЩy\xd0\xff\xff\xff\xffф`\xe0\xff\xff\xff\xffҊ\xadP\xff\xff\xff\xff\xe86c`\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea\v" + + "\xb9`\xff\xff\xff\xff\xea\xd5`\xd0\xff\xff\xff\xff\xeb\xec\xfa\xf0\xff\xff\xff\xff\xec\xb5m\x00\xff\xff\xff\xff\xed\xcf\u007f\xf0\xff\xff\xff\xff\xee\x97\xf2\x00\xff\xff\xff\xffﰳp\xff\xff\xff\xff\xf0y%\x80\xff\xff" + + "\xff\xff\xf1\x91\xe6\xf0\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3s\x1ap\xff\xff\xff\xff\xf4;\x8c\x80\xff\xff\xff\xff\xf5U\x9fp\xff\xff\xff\xff\xf6\x1e\x11\x80\xff\xff\xff\xff\xf76\xd2\xf0\xff\xff\xff\xff\xf7\xff" + + "E\x00\xff\xff\xff\xff\xf9\x18\x06p\xff\xff\xff\xff\xf9\xe1\xca\x00\xff\xff\xff\xff\xfa\xf99\xf0\xff\xff\xff\xff\xfb\xc2\xfd\x80\xff\xff\xff\xff\xfc۾\xf0\xff\xff\xff\xff\xfd\xa5\x82\x80\xff\xff\xff\xff\xfe\xbc\xf2p\xff\xff" + + "\xff\xff\xff\x86\xb6\x00\x00\x00\x00\x00\x00\x9e%\xf0\x00\x00\x00\x00\x01g\xe9\x80\x00\x00\x00\x00\x02\u007fYp\x00\x00\x00\x00\x03I\x1d\x00\x00\x00\x00\x00\x04a\xdep\x00\x00\x00\x00\x05+\xa2\x00\x00\x00\x00\x00\x06C" + + "\x11\xf0\x00\x00\x00\x00\a\fՀ\x00\x00\x00\x00\b$Ep\x00\x00\x00\x00\b\xee\t\x00\x00\x00\x00\x00\n\x05x\xf0\x00\x00\x00\x00\n\xcf<\x80\x00\x00\x00\x00\v\xe7\xfd\xf0\x00\x00\x00\x00\f\xb1\xc1\x80\x00\x00" + + "\x00\x00\r\xc91p\x00\x00\x00\x00\x0e\x92\xf5\x00\x00\x00\x00\x00\x0f\xaad\xf0\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11\x8b\x98p\x00\x00\x00\x00\x12U\\\x00\x00\x00\x00\x00\x13n\x1dp\x00\x00\x00\x00\x147" + + "\xe1\x00\x00\x00\x00\x00\x15OP\xf0\x00\x00\x00\x00\x16\x19\x14\x80\x00\x00\x00\x00\x17\xa0\x93\xf0\x00\x00\x00\x00\x17\xfaH\x00\x00\x00\x00\x00\x19p\xa3\xf0\x00\x00\x00\x00\x19\xdb{\x80\x00\x00\x00\x00\x1a\xf4<\xf0\x00\x00" + + "\x00\x00\x1b\xbe\x00\x80\x00\x00\x00\x00\x1c\xd5pp\x00\x00\x00\x00\x1d\x9f4\x00\x00\x00\x00\x00\x1e\xb6\xa3\xf0\x00\x00\x00\x00\x1f\x80g\x80\x00\x00\x00\x00 \x97\xd7p\x00\x00\x00\x00!a\x9b\x00\x00\x00\x00\x00\"z" + + "\\p\x00\x00\x00\x00#D \x00\x00\x00\x00\x00$b'p\x00\x00\x00\x00%%S\x80\x00\x00\x00\x00&<\xc3p\x00\x00\x00\x00'\x06\x87\x00\x00\x00\x00\x00(\x1d\xf6\xf0\x00\x00\x00\x00(纀\x00\x00" + + "\x00\x00*\x00{\xf0\x00\x00\x00\x00*\xca?\x80\x00\x00\x00\x00+\xe1\xafp\x00\x00\x00\x00,\xabs\x00\x00\x00\x00\x00-\xc2\xe2\xf0\x00\x00\x00\x00.\x8c\xa6\x80\x00\x00\x00\x00/\xa0\x13\xe0\x00\x00\x00\x000k" + + "\f\xd0\x00\x00\x00\x001\u007f\xf5\xe0\x00\x00\x00\x002J\xee\xd0\x00\x00\x00\x003_\xd7\xe0\x00\x00\x00\x004*\xd0\xd0\x00\x00\x00\x005?\xb9\xe0\x00\x00\x00\x006\n\xb2\xd0\x00\x00\x00\x007(\xd6`\x00\x00" + + "\x00\x007\xf3\xcfP\x00\x00\x00\x009\b\xb8`\x00\x00\x00\x009ӱP\x00\x00\x00\x00:\xe8\x9a`\x00\x00\x00\x00;\xb3\x93P\x00\x00\x00\x00<\xc8|`\x00\x00\x00\x00=\x93uP\x00\x00\x00\x00>\xa8" + + "^`\x00\x00\x00\x00?sWP\x00\x00\x00\x00@\x91z\xe0\x00\x00\x00\x00A\\s\xd0\x00\x00\x00\x00Bq\\\xe0\x00\x00\x00\x00C\xe0\x00\x00\x00\x00E\x12\xfdP\x00\x00" + + "\x00\x00F1 \xe0\x00\x00\x00\x00F\xe0jP\x00\x00\x00\x00H\x11\x02\xe0\x00\x00\x00\x00H\xb7\x11\xd0\x00\x00\x00\x00I\xf0\xe4\xe0\x00\x00\x00\x00J\x8d\xb9P\x00\x00\x00\x00K\xda\x01`\x00\x00\x00\x00La" + + "\xbd\xd0\x00\x00\x00\x00L\x89X\xe0\x00\x00\x00\x00L\xa4\xfaP\x00\x00\x00\x00Su8\xe0\x00\x00\x00\x00S\xac\x89\xd0\x00\x00\x00\x00Sڼ`\x00\x00\x00\x00T$\x82P\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x01\x02\x01\x02\x01\x02\x00\x00\x1d" + + "U\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x01\x04LMT\x00EEST\x00EET\x00\x00\x00\x00\x01\nEET-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf2" + + "(l\xe9\xa4\r\x00\x00\xa4\r\x00\x00\x04\x00\x1c\x00EireUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\xe4\x00\x00\x00\t\x00\x00\x00\x14\x80\x00\x00\x00\x9b&\xb3\x91\x9b\xd6\v\x11\x9c\xcf0\xa0\x9d\xa4à\x9e\x9c\x9d\xa0\x9f\x97\x1a\xa0\xa0" + + "\x85\xba \xa1v\xfc\xa0\xa2e\x9c \xa3{Ƞ\xa4N\xb8\xa0\xa5?\xfb \xa6%` \xa7'\xc6 \xa8*, \xa8\xeb\xf8\xa0\xaa\x00Ӡ\xaa\xd5\x15 \xab\xe9\xf0 \xac\xc7l \xad\xc9\xd2 \xae" + + "\xa7N \xaf\xa0y\xa0\xb0\x870 \xb1\x92Р\xb2pL\xa0\xb3r\xb2\xa0\xb4P.\xa0\xb5IZ \xb60\x10\xa0\xb72v\xa0\xb8\x0f\xf2\xa0\xb9\x12X\xa0\xb9\xefԠ\xba\xe9\x00 \xbb\xd8\xf1 \xbc" + + "\xdbW \xbd\xb8\xd3 \xbe\xb1\xfe\xa0\xbf\x98\xb5 \xc0\x9b\x1b \xc1x\x97 \xc2z\xfd \xc3Xy \xc4Q\xa4\xa0\xc58[ \xc6:\xc1 \xc7X֠\xc7\xda\t\xa0\xd4I\xe0 \xd5\x1e!\xa0\xd6" + + "N\xac \xd7,( \xd8.\x8e \xd8\xf9\x95 \xda\x0ep \xda\xeb\xec \xdb\xe5\x17\xa0\xdc\xcb\xce \xdd\xc4\xf9\xa0\u07b4\xea\xa0߮\x16 \xe0\x94̠\xe1rH\xa0\xe2kt \xe3R*\xa0\xe4" + + "T\x90\xa0\xe52\f\xa0\xe6=\xad \xe7\x1b) \xe8\x14T\xa0\xe8\xfb\v \xe9\xfdq \xea\xda\xed \xeb\xddS \xec\xba\xcf \xed\xb3\xfa\xa0\ue6b1 \xef\x81g\xa0\xf0\x9f} \xf1aI\xa0\xf2" + + "\u007f_ \xf3Jf \xf4_A \xf5!\r\xa0\xf6?# \xf7\x00\xef\xa0\xf8\x1f\x05 \xf8\xe0Ѡ\xf9\xfe\xe7 \xfa\xc0\xb3\xa0\xfb\xe8\x03\xa0\xfc{\xab\xa0\xfdǻp\x03p\xc6 \x04)X \x05" + + "P\xa8 \x06\t: \a0\x8a \a\xe9\x1c \t\x10l \t\xc8\xfe \n\xf0N \v\xb2\x1a\xa0\f\xd00 \r\x91\xfc\xa0\x0e\xb0\x12 \x0fqޠ\x10\x99.\xa0\x11Q\xc0\xa0\x12y\x10\xa0\x13" + + "1\xa2\xa0\x14X\xf2\xa0\x15#\xeb\x90\x168Ɛ\x17\x03͐\x18\x18\xa8\x90\x18㯐\x19\xf8\x8a\x90\x1aÑ\x90\x1b\xe1\xa7\x10\x1c\xac\xae\x10\x1d\xc1\x89\x10\x1e\x8c\x90\x10\x1f\xa1k\x10 lr\x10!" + + "\x81M\x10\"LT\x10#a/\x10$,6\x10%JK\x90&\f\x18\x10'*-\x90'\xf54\x90)\n\x0f\x90)\xd5\x16\x90*\xe9\xf1\x90+\xb4\xf8\x90,\xc9Ӑ-\x94ڐ.\xa9\xb5\x90/" + + "t\xbc\x900\x89\x97\x901]\xd9\x102r\xb4\x103=\xbb\x104R\x96\x105\x1d\x9d\x1062x\x106\xfd\u007f\x108\x1b\x94\x908\xdda\x109\xfbv\x90:\xbdC\x10;\xdbX\x90<\xa6_\x90=" + + "\xbb:\x90>\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K" + + "\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y" + + "\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g" + + "藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v" + + "/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\b\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\xff\xff\xfa$\x00\x00\xff\xff\xfa\x0f\x00\x04\x00\x00\b\x1f\x01\b\x00\x00\x0e\x10\x01\f\x00\x00\x00\x00\x00" + + "\x10\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x01\x10\x00\x00\x0e\x10\x00\b\x00\x00\x0e\x10\x00\bLMT\x00DMT\x00IST\x00BST\x00GMT\x00\x00\x00\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00" + + "\x01\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\xe4\x00\x00\x00\t\x00\x00\x00\x14\xff\xff\xff\xffW\xd1\n\xdc\xff\xff\xff\xff\x9b" + + "&\xb3\x91\xff\xff\xff\xff\x9b\xd6\v\x11\xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff" + + "\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8" + + "\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff" + + "\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb7" + + "2v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff" + + "\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc5" + + "8[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd7,( \xff" + + "\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\xde" + + "\xb4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff" + + "\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec" + + "\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\u007f_ \xff\xff\xff\xff\xf3Jf \xff" + + "\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa" + + "\xc0\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfdǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00" + + "\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r" + + "\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\x00\x00\x00\x00\x10\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00" + + "\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x168Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b" + + "\xe1\xa7\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00" + + "\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)" + + "\xd5\x16\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xc9Ӑ\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00" + + "\x00\x00\x001]\xd9\x10\x00\x00\x00\x002r\xb4\x10\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\u007f\x10\x00\x00\x00\x008" + + "\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00" + + "\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F" + + "\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00" + + "\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00T" + + "LG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00" + + "\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b" + + "?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00" + + "\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p" + + "\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00" + + "\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~" + + "y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\b\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\xff" + + "\xff\xfa$\x00\x00\xff\xff\xfa\x0f\x00\x04\x00\x00\b\x1f\x01\b\x00\x00\x0e\x10\x01\f\x00\x00\x00\x00\x00\x10\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x01\x10\x00\x00\x0e\x10\x00\b\x00\x00\x0e\x10\x00\bLMT\x00DMT" + + "\x00IST\x00BST\x00GMT\x00\x00\x00\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\nIST-1GMT0,M10.5.0,M3.5.0/1\nP" + + "K\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x1c\x00Etc/UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00" + + "\x00PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPu\xfezBv\x00\x00\x00v\x00\x00\x00\n\x00\x1c\x00Etc/GMT-10UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04" + + "\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x8c\xa0\x00\x00+" + + "10\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x8c\xa0\x00\x00+10\x00\n<+" + + "10>-10\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\"\xf5\x03\xd8u\x00\x00\x00u\x00\x00\x00\n\x00\x1c\x00Etc/GMT+12UT\t\x00\x03nӧ^nӧ^" + + "ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff" + + "\xffW@\x00\x00-12\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xffW@\x00\x00-" + + "12\x00\n<-12>12\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP?\xaf\xca\tv\x00\x00\x00v\x00\x00\x00\n\x00\x1c\x00Etc/GMT-11UT\t\x00\x03nӧ" + + "^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" + + "\x00\x00\x00\x04\x00\x00\x9a\xb0\x00\x00+11\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00" + + "\x9a\xb0\x00\x00+11\x00\n<+11>-11\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfaj.6r\x00\x00\x00r\x00\x00\x00\r\x00\x1c\x00Etc/Universa" + + "lUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa64^\xabr\x00\x00\x00r\x00\x00\x00\r\x00\x1c\x00Etc/Gre" + + "enwichUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf0\xa0JZu\x00\x00\x00u\x00\x00\x00\t\x00\x1c\x00Et" + + "c/GMT-6UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00T`\x00\x00+06\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00T`\x00\x00+06\x00\n<+06>-6\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xae\xf6\xe6\x02u\x00\x00\x00u\x00\x00\x00\t\x00" + + "\x1c\x00Etc/GMT-1UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x0e\x10\x00\x00+01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x0e\x10\x00\x00+01\x00\n<+01>-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc6\x113Iu\x00\x00\x00u\x00" + + "\x00\x00\t\x00\x1c\x00Etc/GMT-8UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00p\x80\x00\x00+08\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00p\x80\x00\x00+08\x00\n<+08>-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP'j\x99\xaet\x00" + + "\x00\x00t\x00\x00\x00\t\x00\x1c\x00Etc/GMT+4UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xc7\xc0\x00\x00-04\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xc7\xc0\x00\x00-04\x00\n<-04>4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x10\x8b\x9a" + + "\xb9t\x00\x00\x00t\x00\x00\x00\t\x00\x1c\x00Etc/GMT+3UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xd5\xd0\x00\x00-03\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xd5\xd0\x00\x00-03\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP" + + "\xd8\xf3g\xcbu\x00\x00\x00u\x00\x00\x00\t\x00\x1c\x00Etc/GMT-9UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00~\x90\x00\x00+09\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00~\x90\x00\x00+09\x00\n<+09>-9\nPK\x03\x04\n\x00\x00\x00\x00\x00" + + "\xf5F\x9cP\xa64^\xabr\x00\x00\x00r\x00\x00\x00\t\x00\x1c\x00Etc/GMT-0UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZi" + + "f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00TZif2\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00" + + "\x00\xf5F\x9cP\xad8\xee\xe8u\x00\x00\x00u\x00\x00\x00\t\x00\x1c\x00Etc/GMT-7UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZ" + + "if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00bp\x00\x00+07\x00TZif2\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00bp\x00\x00+07\x00\n<+07>-7\nPK\x03\x04\n" + + "\x00\x00\x00\x00\x00\xf5F\x9cPt3\xab2\nPK" + + "\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP'\xb3*\xdbt\x00\x00\x00t\x00\x00\x00\t\x00\x1c\x00Etc/GMT+5UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00" + + "\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xb9\xb0\x00\x00-05\x00T" + + "Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xb9\xb0\x00\x00-05\x00\n<-05>5" + + "\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa64^\xabr\x00\x00\x00r\x00\x00\x00\a\x00\x1c\x00Etc/GMTUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00" + + "\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00" + + "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\n" + + "PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfaj.6r\x00\x00\x00r\x00\x00\x00\b\x00\x1c\x00Etc/ZuluUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00" + + "\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00" + + "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\n" + + "PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP<\x16\x95\ru\x00\x00\x00u\x00\x00\x00\n\x00\x1c\x00Etc/GMT+11UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5" + + "\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xffeP\x00\x00-1" + + "1\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xffeP\x00\x00-11\x00\n<-1" + + "1>11\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf5$\xd1Nv\x00\x00\x00v\x00\x00\x00\n\x00\x1c\x00Etc/GMT-13UT\t\x00\x03nӧ^nӧ^ux" + + "\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\xb6" + + "\xd0\x00\x00+13\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\xb6\xd0\x00\x00+13" + + "\x00\n<+13>-13\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xca\xffryv\x00\x00\x00v\x00\x00\x00\n\x00\x1c\x00Etc/GMT-14UT\t\x00\x03nӧ^" + + "nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" + + "\x00\x00\x04\x00\x00\xc4\xe0\x00\x00+14\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\xc4" + + "\xe0\x00\x00+14\x00\n<+14>-14\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x1cM+7u\x00\x00\x00u\x00\x00\x00\n\x00\x1c\x00Etc/GMT+10UT\t" + + "\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xffs`\x00\x00-10\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" + + "\x00\x00\x04\xff\xffs`\x00\x00-10\x00\n<-10>10\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xd4T=bv\x00\x00\x00v\x00\x00\x00\n\x00\x1c\x00Etc/GMT-" + + "12UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\xa8\xc0\x00\x00+12\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\xa8\xc0\x00\x00+12\x00\n<+12>-12\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa64^\xabr\x00\x00\x00r\x00\x00\x00\b\x00\x1c\x00Et" + + "c/GMT0UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfaj.6r\x00\x00\x00r\x00\x00\x00\a\x00\x1c\x00Et" + + "c/UCTUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa64^\xabr\x00\x00\x00r\x00\x00\x00\t\x00\x1c\x00Etc" + + "/GMT+0UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPʤ\xba\xfat\x00\x00\x00t\x00\x00\x00\t\x00\x1c\x00Et" + + "c/GMT+7UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\x9d\x90\x00\x00-07\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\x9d\x90\x00\x00-07\x00\n<-07>7\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb4n-\xd3t\x00\x00\x00t\x00\x00\x00\t\x00\x1c" + + "\x00Etc/GMT+9UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\x81p\x00\x00-09\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\x81p\x00\x00-09\x00\n<-09>9\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xcd\xd6j_u\x00\x00\x00u\x00\x00\x00" + + "\t\x00\x1c\x00Etc/GMT-2UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x1c \x00\x00+02\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x1c \x00\x00+02\x00\n<+02>-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x93\x80\xc6\au\x00\x00\x00" + + "u\x00\x00\x00\t\x00\x1c\x00Etc/GMT-5UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00FP\x00\x00+05\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00FP\x00\x00+05\x00\n<+05>-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc0ތQ" + + "t\x00\x00\x00t\x00\x00\x00\t\x00\x1c\x00Etc/GMT+8UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\x8f\x80\x00\x00-08\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\x8f\x80\x00\x00-08\x00\n<-08>8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xae" + + "\x1c\x8b\u007ft\x00\x00\x00t\x00\x00\x00\t\x00\x1c\x00Etc/GMT+6UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xab\xa0\x00\x00-06\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xab\xa0\x00\x00-06\x00\n<-06>6\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F" + + "\x9cP\xfd\x9c\n\x98t\x00\x00\x00t\x00\x00\x00\t\x00\x1c\x00Etc/GMT+1UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xf1\xf0\x00\x00-01\x00TZif2\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xf1\xf0\x00\x00-01\x00\n<-01>1\nPK\x03\x04\n\x00\x00\x00\x00" + + "\x00\xf5F\x9cP\xfaj.6r\x00\x00\x00r\x00\x00\x00\a\x00\x1c\x00Etc/UTCUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif" + + "2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00TZif2\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK\x03\x04\n\x00\x00\x00\x00\x00" + + "\xf5F\x9cP\v\x96r\xe4u\x00\x00\x00u\x00\x00\x00\t\x00\x1c\x00Etc/GMT-4UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZi" + + "f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x008@\x00\x00+04\x00TZif2\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x008@\x00\x00+04\x00\n<+04>-4\nPK\x03\x04\n\x00" + + "\x00\x00\x00\x00\xf5F\x9cP\x90N\xce\xedu\x00\x00\x00u\x00\x00\x00\t\x00\x1c\x00Etc/GMT-3UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00" + + "\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00*0\x00\x00+03\x00TZif2" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00*0\x00\x00+03\x00\n<+03>-3\nPK" + + "\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x1c\x00Europe/UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14" + + "\x00\x00\x00PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPy\xcc\x01\x9du\a\x00\x00u\a\x00\x00\r\x00\x1c\x00Europe/ZurichUT\t\x00\x03nӧ^nӧ^u" + + "x\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00w\x00\x00\x00\x05\x00\x00\x00\r\x80\x00" + + "\x00\x00\xca\x17j\x00\xca\xe2q\x00\xcb\xf7L\x00\xcc\xc2S\x00\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c" + + "\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03" + + "\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf7" + + "0\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=" + + "\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1" + + "\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\b\x00\x00\x00\x00" + + "\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\x00\x00\x00\x01\x01\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00x\x00\x00\x00\x06\x00\x00\x00\x11\xff\xff\xff\xff$\xf0\xea\x80\xff\xff\xff\xffq\xd4\x06\x86\xff\xff\xff\xff\xca\x17j\x00\xff\xff\xff\xff\xca\xe2" + + "q\x00\xff\xff\xff\xff\xcb\xf7L\x00\xff\xff\xff\xff\xcc\xc2S\x00\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00" + + "\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 l" + + "r\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00" + + "\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3" + + "\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00" + + "\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7" + + "\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00" + + "\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d" + + "\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00" + + "\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11" + + "\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00" + + "\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x03\x02\x03\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x00\x00\b\x00\x00\x00\x00\x00\x06\xfa\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x01\b" + + "\x00\x00\x0e\x10\x00\rLMT\x00BMT\x00CEST\x00CET\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M10.5.0" + + "/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPL\xde\\7\x92\v\x00\x00\x92\v\x00\x00\f\x00\x1c\x00Europe/ParisUT\t\x00\x03nӧ^nӧ^ux" + + "\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\xb8\x00\x00\x00\r\x00\x00\x00\x1f\x80\x00\x00" + + "\x00\x91`P\x8b\x9bGx\xf0\x9b\xd7,p\x9c\xbc\x91p\x9d\xc0H\xf0\x9e\x89\xfep\x9f\xa0*\xf0\xa0`\xa5\xf0\xa1\x80\f\xf0\xa2.\x12\xf0\xa3zL\xf0\xa45\x81\xf0\xa5^#p\xa6%5\xf0\xa7'\x9b" + + "\xf0\xa8X&p\xa9\a}\xf0\xa9\xee4p\xaa\xe7_\xf0\xab\xd7P\xf0\xac\xc7A\xf0\xadɧ\xf0\xae\xa7#\xf0\xaf\xa0Op\xb0\x87\x05\xf0\xb1\x89k\xf0\xb2p\"p\xb3r\x88p\xb4P\x04p\xb5I/" + + "\xf0\xb6/\xe6p\xb72Lp\xb8\x0f\xc8p\xb8\xff\xb9p\xb9\xef\xaap\xba\xd6`\xf0\xbb\xd8\xc6\xf0\xbcȷ\U0003de28\xf0\xbe\x9f_p\xbf\x98\x8a\xf0\xc0\x9a\xf0\xf0\xc1xl\xf0\xc2h]\xf0\xc3XN" + + "\xf0\xc4?\x05p\xc580\xf0\xc6:\x96\xf0\xc7X\xacp\xc7\xda\t\xa0\xc8l'\xe0\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10\xd0O\xe1\xe0Љ\xf1\xf0\xd1r\x16\x10\xd2N@\x90\v\xbb9" + + "\x00\f\xab\x1b\xf0\r\xa4c\x90\x0e\x8b\x1a\x10\x0f\x84E\x90\x10t6\x90\x11d'\x90\x12T\x18\x90\x13MD\x10\x143\xfa\x90\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ" + + "\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7" + + "\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle" + + "\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5" + + "\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S" + + "\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\xc2" + + "\x90}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x04\b\x06\a\x06\a\t\x04\t\n\b\n\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v" + + "\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v" + + "\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\x00\x00\x021\x00\x00\x00\x00\x021\x00\x04\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\r\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\r\x00\x00\x0e\x10\x00\x11\x00" + + "\x00\x1c \x01\x15\x00\x00\x1c \x01\x15\x00\x00\x1c \x01\x1a\x00\x00\x0e\x10\x00\x11\x00\x00\x1c \x01\x15\x00\x00\x0e\x10\x00\x11LMT\x00PMT\x00WEST\x00WET\x00CET\x00CEST" + + "\x00WEMT\x00\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\r" + + "\x00\x00\x00\x00\x00\x00\x00\xb8\x00\x00\x00\r\x00\x00\x00\x1f\xff\xff\xff\xffk\xc8J\x8b\xff\xff\xff\xff\x91`P\x8b\xff\xff\xff\xff\x9bGx\xf0\xff\xff\xff\xff\x9b\xd7,p\xff\xff\xff\xff\x9c\xbc\x91p\xff\xff\xff\xff" + + "\x9d\xc0H\xf0\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0*\xf0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1\x80\f\xf0\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45\x81\xf0" + + "\xff\xff\xff\xff\xa5^#p\xff\xff\xff\xff\xa6%5\xf0\xff\xff\xff\xff\xa7'\x9b\xf0\xff\xff\xff\xff\xa8X&p\xff\xff\xff\xff\xa9\a}\xf0\xff\xff\xff\xff\xa9\xee4p\xff\xff\xff\xff\xaa\xe7_\xf0\xff\xff\xff\xff" + + "\xab\xd7P\xf0\xff\xff\xff\xff\xac\xc7A\xf0\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2p\"p" + + "\xff\xff\xff\xff\xb3r\x88p\xff\xff\xff\xff\xb4P\x04p\xff\xff\xff\xff\xb5I/\xf0\xff\xff\xff\xff\xb6/\xe6p\xff\xff\xff\xff\xb72Lp\xff\xff\xff\xff\xb8\x0f\xc8p\xff\xff\xff\xff\xb8\xff\xb9p\xff\xff\xff\xff" + + "\xb9\xef\xaap\xff\xff\xff\xff\xba\xd6`\xf0\xff\xff\xff\xff\xbb\xd8\xc6\xf0\xff\xff\xff\xff\xbcȷ\xf0\xff\xff\xff\xff\xbd\xb8\xa8\xf0\xff\xff\xff\xff\xbe\x9f_p\xff\xff\xff\xff\xbf\x98\x8a\xf0\xff\xff\xff\xff\xc0\x9a\xf0\xf0" + + "\xff\xff\xff\xff\xc1xl\xf0\xff\xff\xff\xff\xc2h]\xf0\xff\xff\xff\xff\xc3XN\xf0\xff\xff\xff\xff\xc4?\x05p\xff\xff\xff\xff\xc580\xf0\xff\xff\xff\xff\xc6:\x96\xf0\xff\xff\xff\xff\xc7X\xacp\xff\xff\xff\xff" + + "\xc7\xda\t\xa0\xff\xff\xff\xff\xc8l'\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0O\xe1\xe0\xff\xff\xff\xffЉ\xf1\xf0" + + "\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\v\xbb9\x00\x00\x00\x00\x00\f\xab\x1b\xf0\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00" + + "\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐" + + "\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00" + + "\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10" + + "\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00" + + "I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10" + + "\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00" + + "V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10" + + "\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00" + + "e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90" + + "\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00" + + "s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ" + + "\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\b\x06\a\x06\a\t\x04\t\n\b\n\v\f\v\f\v\f\v\f\v\f" + + "\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f" + + "\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\x00\x00\x021\x00\x00\x00\x00" + + "\x021\x00\x04\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\r\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\r\x00\x00\x0e\x10\x00\x11\x00\x00\x1c \x01\x15\x00\x00\x1c \x01\x15\x00\x00\x1c \x01\x1a\x00\x00\x0e\x10\x00\x11\x00\x00" + + "\x1c \x01\x15\x00\x00\x0e\x10\x00\x11LMT\x00PMT\x00WEST\x00WET\x00CET\x00CEST\x00WEMT\x00\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPc\xb1\xa1\x88\xff\x05\x00\x00\xff\x05\x00" + + "\x00\r\x00\x1c\x00Europe/MoscowUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00N\x00\x00\x00\x11\x00\x00\x00&\x80\x00\x00\x00\x9b_\x1eǝ>\xf2y\x9e*\xee\xf9\x9e\xf79i\x9f\x84W\xf9\xa0\xd8l\xe9\xa1\x00" + + "9\x80\xa1<\xa6@\xa4\x10m\xc0\xa4=2\xb0\xa5\x15h\xb0\xa5=\x03\xc0\xa7\x1eEP\xb5\xa4\x19`\x15'\xa7\xd0\x16\x18\xdc@\x17\b\xdbP\x17\xfa\x0f\xc0\x18\xea\x0e\xd0\x19\xdbC@\x1a̓\xd0\x1b\xbc" + + "\xa0\xf0\x1c\xac\x91\xf0\x1d\x9c\x82\xf0\x1e\x8cs\xf0\x1f|d\xf0 lU\xf0!\\F\xf0\"L7\xf0#<(\xf0$,\x19\xf0%\x1c\n\xf0&\v\xfb\xf0'\x05'p'\xf5\x18p(\xe5\x17\x80)x" + + "\xbf\x80)\xd4\xfap*\xc4\xebp+\xb4\xdcp,\xa4\xcdp-\x94\xbep.\x84\xafp/t\xa0p0d\x91p1]\xbc\xf02r\x97\xf03=\x9e\xf04Ry\xf05\x1d\x80\xf062[\xf06\xfd" + + "b\xf08\x1bxp8\xddD\xf09\xfbZp:\xbd&\xf0;\xdb\x86%p?\x9b\x00p@f\apA\x84\x1c\xf0BE\xe9pCc\xfe\xf0D%\xcbpEC" + + "\xe0\xf0F\x05\xadpG#\xc2\xf0G\xee\xc9\xf0I\x03\xa4\xf0IΫ\xf0J\xe3\x86\xf0K\xae\x8d\xf0ḶpM\x8eo\xf0TL\x1d`\x01\x03\x02\x03\x04\x02\x04\x05\x06\a\b\a\x06\t\x06\a\x06\a" + + "\x06\a\x06\a\n\v\n\v\n\v\n\v\n\v\n\v\n\f\r\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\x0e\n" + + "\x00\x00#9\x00\x00\x00\x00#9\x00\x04\x00\x001\x87\x01\b\x00\x00#w\x00\x04\x00\x00?\x97\x01\f\x00\x008@\x01\x11\x00\x00*0\x00\x15\x00\x008@\x01\x11\x00\x00FP\x01\x19\x00\x00\x1c \x00\x1d" + + "\x00\x00*0\x00\x15\x00\x008@\x01\x11\x00\x00*0\x01!\x00\x00\x1c \x00\x1d\x00\x008@\x00\x15\x00\x008@\x01\x11\x00\x00*0\x00\x15LMT\x00MMT\x00MST\x00MDST\x00M" + + "SD\x00MSK\x00+05\x00EET\x00EEST\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TZif2\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00N\x00\x00\x00\x11\x00\x00\x00&\xff\xff\xff\xffV\xb6\xc0\xc7\xff\xff\xff\xff\x9b_\x1e\xc7\xff\xff\xff\xff\x9d>" + + "\xf2y\xff\xff\xff\xff\x9e*\xee\xf9\xff\xff\xff\xff\x9e\xf79i\xff\xff\xff\xff\x9f\x84W\xf9\xff\xff\xff\xff\xa0\xd8l\xe9\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xa1<\xa6@\xff\xff\xff\xff\xa4\x10m\xc0\xff\xff" + + "\xff\xff\xa4=2\xb0\xff\xff\xff\xff\xa5\x15h\xb0\xff\xff\xff\xff\xa5=\x03\xc0\xff\xff\xff\xff\xa7\x1eEP\xff\xff\xff\xff\xb5\xa4\x19`\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b" + + "\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00" + + "\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c" + + "\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)x\xbf\x80\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00" + + "\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r" + + "\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00" + + "\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f" + + "\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00" + + "\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL" + + "\x1d`\x01\x03\x02\x03\x04\x02\x04\x05\x06\a\b\a\x06\t\x06\a\x06\a\x06\a\x06\a\n\v\n\v\n\v\n\v\n\v\n\v\n\f\r\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n" + + "\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\x0e\n\x00\x00#9\x00\x00\x00\x00#9\x00\x04\x00\x001\x87\x01\b\x00\x00#w\x00\x04\x00\x00?\x97\x01\f\x00\x008@\x01\x11\x00\x00*0" + + "\x00\x15\x00\x008@\x01\x11\x00\x00FP\x01\x19\x00\x00\x1c \x00\x1d\x00\x00*0\x00\x15\x00\x008@\x01\x11\x00\x00*0\x01!\x00\x00\x1c \x00\x1d\x00\x008@\x00\x15\x00\x008@\x01\x11\x00\x00*0" + + "\x00\x15LMT\x00MMT\x00MST\x00MDST\x00MSD\x00MSK\x00+05\x00EET\x00EEST\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00" + + "\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\nMSK-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPQ\xb0\xc3/\x82\v\x00\x00\x82\v\x00\x00\x11\x00\x1c\x00Europe/Lu" + + "xembourgUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e" + + "\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\xb7\x00\x00\x00\x0e\x00\x00\x00\x16\x84\xa2\xad\xbc\x9b\x1e\x8c`\x9b\xd5\xda\xf0\x9c\xea\xa7\xe0\x9d\xa4\x99p\x9e\xb9\x90\x90\x9f\x84\x97\x90\x9f\xe0\xc4p\xa0`\xa5\xf0\xa1~\xe5\xa0" + + "\xa2.\x12\xf0\xa3zi\x10\xa45\x81\xf0\xa5^?\x90\xa6%5\xf0\xa7'\xaa\x00\xa8*\x01\xf0\xa9\a\x9a\x10\xa9\xee4p\xaa\xe7n\x00\xabآp\xac\xc7P\x00\xadɧ\xf0\xae\xa72\x00\xaf\xa0Op" + + "\xb0\x87\x14\x00\xb1\x89k\xf0\xb2p0\x80\xb3r\x88p\xb4P.\xa0\xb5IZ \xb60\x10\xa0\xb72v\xa0\xb8\x0f\xf2\xa0\xb8\xff㠹\xefԠ\xba\u058b \xbb\xd8\xf1 \xbc\xc8\xe2 \xbd\xb8\xd3 " + + "\xbe\x9f\x89\xa0\xbf\x98\xb5 \xc0\x9b\x1b \xc1x\x97 \xc2h\x88 \xc3Xy \xc4?/\xa0\xc58[ \xc6:\xc1 \xc7X֠\xc7\xda\t\xa0\xc8B0 \xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10" + + "ϒ4\x10\xd0o\xb0\x10\xd1r\x16\x10\xd2N@\x90ӑ@\x10\xd4K#\x90\r\xa4c\x90\x0e\x8b\x1a\x10\x0f\x84E\x90\x10t6\x90\x11d'\x90\x12T\x18\x90\x13MD\x10\x143\xfa\x90\x15#\xeb\x90" + + "\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90" + + "@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10" + + "N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10" + + "\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90" + + "j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90" + + "x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x03\x04\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\v\t\n\t\n\x02\x03\x04\x03\x04\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f" + + "\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f" + + "\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\x00\x00\x05\xc4\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00" + + "\x00\x0e\x10\x00\t\x00\x00\x0e\x10\x01\r\x00\x00\x00\x00\x00\x12\x00\x00\x00\x00\x00\x12\x00\x00\x0e\x10\x01\r\x00\x00\x0e\x10\x00\x12\x00\x00\x1c \x01\r\x00\x00\x1c \x01\r\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tL" + + "MT\x00CEST\x00CET\x00WEST\x00WET\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\xb7\x00\x00\x00\x0e\x00\x00\x00\x16\xff\xff\xff\xff\x84\xa2\xad\xbc\xff\xff\xff\xff\x9b\x1e\x8c`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff" + + "\xff\x9c\xea\xa7\xe0\xff\xff\xff\xff\x9d\xa4\x99p\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\x9f\xe0\xc4p\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xe5\xa0\xff\xff\xff\xff\xa2.\x12" + + "\xf0\xff\xff\xff\xff\xa3zi\x10\xff\xff\xff\xff\xa45\x81\xf0\xff\xff\xff\xff\xa5^?\x90\xff\xff\xff\xff\xa6%5\xf0\xff\xff\xff\xff\xa7'\xaa\x00\xff\xff\xff\xff\xa8*\x01\xf0\xff\xff\xff\xff\xa9\a\x9a\x10\xff\xff\xff" + + "\xff\xa9\xee4p\xff\xff\xff\xff\xaa\xe7n\x00\xff\xff\xff\xff\xabآp\xff\xff\xff\xff\xac\xc7P\x00\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa72\x00\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x14" + + "\x00\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2p0\x80\xff\xff\xff\xff\xb3r\x88p\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff" + + "\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb8\xff\xe3\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\u058b \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xc8\xe2 \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\x9f\x89" + + "\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2h\x88 \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4?/\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff" + + "\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xc8B0 \xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4" + + "\x10\xff\xff\xff\xff\xd0o\xb0\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\xff\xff\xff\xffӑ@\x10\xff\xff\xff\xff\xd4K#\x90\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00" + + "\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13\xdc" + + "\x90\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00" + + "\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#" + + "\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00" + + "\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1" + + "\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00" + + "\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11" + + "\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00" + + "\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT" + + "\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00" + + "\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4" + + "\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x02\x01\x02" + + "\x01\x02\x03\x04\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\v\t\n\t\n\x02\x03\x04\x03\x04\f\r" + + "\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r" + + "\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r" + + "\x00\x00\x05\xc4\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x0e\x10\x01\r\x00\x00\x00\x00\x00\x12\x00\x00\x00\x00\x00\x12\x00\x00\x0e\x10\x01\r\x00\x00\x0e\x10\x00\x12" + + "\x00\x00\x1c \x01\r\x00\x00\x1c \x01\r\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00WEST\x00WET\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x01\x01\x00\x01\x01" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xcd\xc6J\xc3" + + "\x80\a\x00\x00\x80\a\x00\x00\x10\x00\x1c\x00Europe/LjubljanaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif" + + "2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00w\x00\x00\x00\a\x00\x00\x00\r\x80\x00\x00\x00\xca\x025\xe0\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10" + + "ϒ4\x10Ђ%\x10ѡ\x8c\x10\xd2N@\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10" + + "#\x86A\x90" + + "?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90" + + "M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90" + + "[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90" + + "i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10" + + "x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x04\x02\x03\x02\x03\x02\x03\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\b\x00" + + "\x00\x1c \x01\b\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\x04LMT\x00CET\x00CEST\x00\x00\x00\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00w\x00\x00\x00\a\x00\x00\x00\r\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90" + + "\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xffѡ\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00" + + "\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10" + + "\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00" + + "EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10" + + "\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00" + + "S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10" + + "\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00" + + "a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐" + + "\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00" + + "oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90" + + "\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00" + + "}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x04\x02\x03\x02\x03\x02\x03\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\b\x00\x00\x1c \x01\b\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00" + + "\x04LMT\x00CET\x00CEST\x00\x00\x00\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04" + + "\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf9\xe6\xa9\xc7l\a\x00\x00l\a\x00\x00\x0f\x00\x1c\x00Europe/HelsinkiUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04" + + "\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00v\x00\x00\x00\x06\x00\x00\x00\x11\x80\x00\x00\x00\xa4so" + + "\x1b\xcb\xceQ`\xcc\xc0\xe5`\x15#݀\x16\x13\u0380\x17\x03\xbf\x80\x17\xf3\xb0\x80\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr" + + "\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3" + + "\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12" + + "\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90" + + "\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00" + + "\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x03\x02\x03\x02\x03\x02\x03\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x00\x00\x17e\x00\x00\x00\x00\x17e\x00\x04\x00\x00*0\x01" + + "\b\x00\x00\x1c \x00\r\x00\x00*0\x01\b\x00\x00\x1c \x00\rLMT\x00HMT\x00EEST\x00EET\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00v\x00\x00\x00\x06\x00\x00\x00\x11\xff\xff\xff\xffS\xba&\x9b\xff\xff\xff\xff\xa4so\x1b\xff\xff\xff\xff\xcb\xceQ`\xff\xff\xff\xff" + + "\xcc\xc0\xe5`\x00\x00\x00\x00\x15#݀\x00\x00\x00\x00\x16\x13\u0380\x00\x00\x00\x00\x17\x03\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90" + + "\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00" + + "\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10" + + "\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00" + + "L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90" + + "\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00" + + "Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90" + + "\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00" + + "h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90" + + "\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00" + + "v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90" + + "\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x03\x02\x03\x02\x03\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x00\x00\x17e\x00\x00\x00\x00\x17e\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x01\b\x00\x00\x1c \x00\rLMT\x00HMT\x00EE" + + "ST\x00EET\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x01\x01\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5" + + "F\x9cP%\xad\xddU)\x05\x00\x00)\x05\x00\x00\f\x00\x1c\x00Europe/MinskUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00T" + + "Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00E\x00\x00\x00\r\x00\x00\x00&\x80\x00\x00\x00\xaa\x19\xaa8\xb5\xa4\x19`\xca^p\xd0\xcc" + + "\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10\xd0\n\x02`\x15'\xa7\xd0\x16\x18\xdc@\x17\b\xdbP\x17\xfa\x0f\xc0\x18\xea\x0e\xd0\x19\xdbC@\x1a̓\xd0\x1b\xbc\xa0\xf0\x1c\xac\x91\xf0\x1d\x9c\x82\xf0\x1e" + + "\x8cs\xf0\x1f|d\xf0 lU\xf0!\\F\xf0\"L7\xf0#<(\xf0$,\x19\xf0%\x1c\n\xf0'\xf5\x18p(\xe5\x17\x80)\xd5\b\x80*\xc4\xf9\x80+\xb4\xea\x80,\xa4ۀ-\x94̀." + + "\x84\xbd\x80/t\xae\x800d\x9f\x801]\xcb\x002r\xa6\x003=\xad\x004R\x88\x005\x1d\x8f\x0062j\x006\xfdq\x008\x1b\x86\x808\xddS\x009\xfbh\x80:\xbd5\x00;\xdbJ\x80<" + + "\xa6Q\x80=\xbb,\x80>\x863\x80?\x9b\x0e\x80@f\x15\x80A\x84+\x00BE\xf7\x80Cd\r\x00D%ـEC\xef\x00F\x05\xbb\x80G#\xd1\x00G\xee\xd8\x00I\x03\xb3\x00Iκ\x00J" + + "\xe3\x95\x00K\xae\x9c\x00Ḻ\x80M\x8e~\x00\u007f\xff\xff\xff\x01\x02\x03\x06\x04\x05\x04\x05\x03\a\x03\a\x03\a\x03\a\b\t\b\t\b\t\b\t\b\t\b\n\v\n\v\n\v\n\v\n\v\n\v\n\v" + + "\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\f\f\x00\x00\x19\xd8\x00\x00\x00\x00\x19\xc8\x00\x04\x00\x00\x1c \x00\b\x00\x00*0\x00\f\x00\x00\x0e\x10\x00\x10\x00\x00" + + "\x1c \x01\x14\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x00\f\x00\x008@\x01\x19\x00\x00*0\x01\x1d\x00\x00\x1c \x00\b\x00\x00*0\x00\"LMT\x00MMT\x00EET\x00MS" + + "K\x00CET\x00CEST\x00MSD\x00EEST\x00+03\x00\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00E\x00\x00\x00\r\x00\x00\x00&\xff\xff\xff\xffV\xb6\xca(\xff\xff\xff\xff\xaa\x19\xaa8\xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xff\xca^p\xd0\xff\xff\xff\xff\xcc\xe7K" + + "\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0\n\x02`\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00" + + "\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs" + + "\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00" + + "\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd" + + "\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xa6\x00\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x8f\x00\x00\x00\x00" + + "\x0062j\x00\x00\x00\x00\x006\xfdq\x00\x00\x00\x00\x008\x1b\x86\x80\x00\x00\x00\x008\xddS\x00\x00\x00\x00\x009\xfbh\x80\x00\x00\x00\x00:\xbd5\x00\x00\x00\x00\x00;\xdbJ\x80\x00\x00\x00\x00<\xa6Q" + + "\x80\x00\x00\x00\x00=\xbb,\x80\x00\x00\x00\x00>\x863\x80\x00\x00\x00\x00?\x9b\x0e\x80\x00\x00\x00\x00@f\x15\x80\x00\x00\x00\x00A\x84+\x00\x00\x00\x00\x00BE\xf7\x80\x00\x00\x00\x00Cd\r\x00\x00\x00\x00" + + "\x00D%ـ\x00\x00\x00\x00EC\xef\x00\x00\x00\x00\x00F\x05\xbb\x80\x00\x00\x00\x00G#\xd1\x00\x00\x00\x00\x00G\xee\xd8\x00\x00\x00\x00\x00I\x03\xb3\x00\x00\x00\x00\x00Iκ\x00\x00\x00\x00\x00J\xe3\x95" + + "\x00\x00\x00\x00\x00K\xae\x9c\x00\x00\x00\x00\x00Ḻ\x80\x00\x00\x00\x00M\x8e~\x00\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x06\x04\x05\x04\x05\x03\a\x03\a\x03\a\x03\a\b\t\b\t\b\t\b\t\b\t\b" + + "\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\f\f\x00\x00\x19\xd8\x00\x00\x00\x00\x19\xc8\x00\x04\x00\x00\x1c \x00\b" + + "\x00\x00*0\x00\f\x00\x00\x0e\x10\x00\x10\x00\x00\x1c \x01\x14\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x00\f\x00\x008@\x01\x19\x00\x00*0\x01\x1d\x00\x00\x1c \x00\b\x00\x00*0\x00\"" + + "LMT\x00MMT\x00EET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00+03\x00\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x01\x01\x01\n<+03>-3\n" + + "PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xcd\xc6JÀ\a\x00\x00\x80\a\x00\x00\r\x00\x1c\x00Europe/SkopjeUT\t\x00\x03nӧ^nӧ^ux\v\x00" + + "\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00w\x00\x00\x00\a\x00\x00\x00\r\x80\x00\x00\x00\xca" + + "\x025\xe0\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10Ђ%\x10ѡ\x8c\x10\xd2N@\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f" + + "|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I" + + "\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X" + + "\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f" + + "\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10t" + + "E\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x04\x02\x03\x02\x03\x02\x03\x02" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\x138\x00\x00\x00\x00\x0e\x10" + + "\x00\x04\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\b\x00\x00\x1c \x01\b\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\x04LMT\x00CET\x00CEST\x00\x00\x00\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01T" + + "Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00w\x00\x00\x00\a\x00\x00\x00\r\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff" + + "\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xffѡ\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18" + + "㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00" + + "\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00C" + + "d\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00" + + "\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00Q" + + "W\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00" + + "\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_" + + "\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00" + + "\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m" + + "\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00" + + "\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{" + + "λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x04\x02\x03\x02\x03\x02\x03\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\b\x00\x00" + + "\x1c \x01\b\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\x04LMT\x00CET\x00CEST\x00\x00\x00\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0" + + ",M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf2(l\xe9\xa4\r\x00\x00\xa4\r\x00\x00\r\x00\x1c\x00Europe/DublinUT\t\x00\x03n" + + "ӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\xe4\x00\x00" + + "\x00\t\x00\x00\x00\x14\x80\x00\x00\x00\x9b&\xb3\x91\x9b\xd6\v\x11\x9c\xcf0\xa0\x9d\xa4à\x9e\x9c\x9d\xa0\x9f\x97\x1a\xa0\xa0\x85\xba \xa1v\xfc\xa0\xa2e\x9c \xa3{Ƞ\xa4N\xb8\xa0\xa5?\xfb \xa6%" + + "` \xa7'\xc6 \xa8*, \xa8\xeb\xf8\xa0\xaa\x00Ӡ\xaa\xd5\x15 \xab\xe9\xf0 \xac\xc7l \xad\xc9\xd2 \xae\xa7N \xaf\xa0y\xa0\xb0\x870 \xb1\x92Р\xb2pL\xa0\xb3r\xb2\xa0\xb4P" + + ".\xa0\xb5IZ \xb60\x10\xa0\xb72v\xa0\xb8\x0f\xf2\xa0\xb9\x12X\xa0\xb9\xefԠ\xba\xe9\x00 \xbb\xd8\xf1 \xbc\xdbW \xbd\xb8\xd3 \xbe\xb1\xfe\xa0\xbf\x98\xb5 \xc0\x9b\x1b \xc1x\x97 \xc2z" + + "\xfd \xc3Xy \xc4Q\xa4\xa0\xc58[ \xc6:\xc1 \xc7X֠\xc7\xda\t\xa0\xd4I\xe0 \xd5\x1e!\xa0\xd6N\xac \xd7,( \xd8.\x8e \xd8\xf9\x95 \xda\x0ep \xda\xeb\xec \xdb\xe5" + + "\x17\xa0\xdc\xcb\xce \xdd\xc4\xf9\xa0\u07b4\xea\xa0߮\x16 \xe0\x94̠\xe1rH\xa0\xe2kt \xe3R*\xa0\xe4T\x90\xa0\xe52\f\xa0\xe6=\xad \xe7\x1b) \xe8\x14T\xa0\xe8\xfb\v \xe9\xfd" + + "q \xea\xda\xed \xeb\xddS \xec\xba\xcf \xed\xb3\xfa\xa0\ue6b1 \xef\x81g\xa0\xf0\x9f} \xf1aI\xa0\xf2\u007f_ \xf3Jf \xf4_A \xf5!\r\xa0\xf6?# \xf7\x00\xef\xa0\xf8\x1f" + + "\x05 \xf8\xe0Ѡ\xf9\xfe\xe7 \xfa\xc0\xb3\xa0\xfb\xe8\x03\xa0\xfc{\xab\xa0\xfdǻp\x03p\xc6 \x04)X \x05P\xa8 \x06\t: \a0\x8a \a\xe9\x1c \t\x10l \t\xc8\xfe \n\xf0" + + "N \v\xb2\x1a\xa0\f\xd00 \r\x91\xfc\xa0\x0e\xb0\x12 \x0fqޠ\x10\x99.\xa0\x11Q\xc0\xa0\x12y\x10\xa0\x131\xa2\xa0\x14X\xf2\xa0\x15#\xeb\x90\x168Ɛ\x17\x03͐\x18\x18\xa8\x90\x18\xe3" + + "\xaf\x90\x19\xf8\x8a\x90\x1aÑ\x90\x1b\xe1\xa7\x10\x1c\xac\xae\x10\x1d\xc1\x89\x10\x1e\x8c\x90\x10\x1f\xa1k\x10 lr\x10!\x81M\x10\"LT\x10#a/\x10$,6\x10%JK\x90&\f\x18\x10'*" + + "-\x90'\xf54\x90)\n\x0f\x90)\xd5\x16\x90*\xe9\xf1\x90+\xb4\xf8\x90,\xc9Ӑ-\x94ڐ.\xa9\xb5\x90/t\xbc\x900\x89\x97\x901]\xd9\x102r\xb4\x103=\xbb\x104R\x96\x105\x1d" + + "\x9d\x1062x\x106\xfd\u007f\x108\x1b\x94\x908\xdda\x109\xfbv\x90:\xbdC\x10;\xdbX\x90<\xa6_\x90=\xbb:\x90>\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd" + + "\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW" + + "\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94" + + "\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88" + + "=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{\xce" + + "\xbb\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\b\x06\a\x06\a\x06\a\x06" + + "\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" + + "\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" + + "\a\x06\a\x06\a\x06\xff\xff\xfa$\x00\x00\xff\xff\xfa\x0f\x00\x04\x00\x00\b\x1f\x01\b\x00\x00\x0e\x10\x01\f\x00\x00\x00\x00\x00\x10\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x01\x10\x00\x00\x0e\x10\x00\b\x00\x00\x0e\x10\x00\b" + + "LMT\x00DMT\x00IST\x00BST\x00GMT\x00\x00\x00\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\t\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\xe4\x00\x00\x00\t\x00\x00\x00\x14\xff\xff\xff\xffW\xd1\n\xdc\xff\xff\xff\xff\x9b&\xb3\x91\xff\xff\xff\xff\x9b\xd6\v\x11\xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4" + + "à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff" + + "\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9" + + "\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff" + + "\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xef" + + "Ԡ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff" + + "\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda" + + "\t\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd7,( \xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff" + + "\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1r" + + "H\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff" + + "\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81" + + "g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\u007f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff" + + "\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfd\xc7" + + "\xbbp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00" + + "\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\x00\x00\x00\x00\x10\x99" + + ".\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x168Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00" + + "\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c" + + "\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00" + + "\x00\x00&\f\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xc9" + + "Ӑ\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00\x00\x001]\xd9\x10\x00\x00\x00\x002r\xb4\x10\x00\x00\x00\x003=\xbb\x10\x00\x00" + + "\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\u007f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbd" + + "C\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00" + + "\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03" + + "\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00" + + "\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf7" + + "0\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00" + + "\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=" + + "\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00" + + "\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1" + + "\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00" + + "\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\b\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" + + "\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" + + "\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\xff\xff\xfa$\x00\x00\xff\xff\xfa\x0f\x00\x04\x00\x00\b\x1f\x01\b\x00\x00\x0e\x10\x01\f\x00\x00" + + "\x00\x00\x00\x10\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x01\x10\x00\x00\x0e\x10\x00\b\x00\x00\x0e\x10\x00\bLMT\x00DMT\x00IST\x00BST\x00GMT\x00\x00\x00\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00" + + "\x00\x00\x00\x01\x01\x00\nIST-1GMT0,M10.5.0,M3.5.0/1\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa5\xa2\x06\xaf@\x0e\x00\x00@\x0e\x00\x00" + + "\r\x00\x1c\x00Europe/JerseyUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xf2\x00\x00\x00\a\x00\x00\x00\x11\x80\x00\x00\x00\x9b&\xad\xa0\x9b\xd6\x05 \x9c\xcf0\xa0\x9d\xa4à\x9e\x9c\x9d\xa0\x9f\x97\x1a\xa0\xa0\x85\xba" + + " \xa1v\xfc\xa0\xa2e\x9c \xa3{Ƞ\xa4N\xb8\xa0\xa5?\xfb \xa6%` \xa7'\xc6 \xa8*, \xa8\xeb\xf8\xa0\xaa\x00Ӡ\xaa\xd5\x15 \xab\xe9\xf0 \xac\xc7l \xad\xc9\xd2 \xae\xa7N" + + " \xaf\xa0y\xa0\xb0\x870 \xb1\x92Р\xb2pL\xa0\xb3r\xb2\xa0\xb4P.\xa0\xb5IZ \xb60\x10\xa0\xb72v\xa0\xb8\x0f\xf2\xa0\xb9\x12X\xa0\xb9\xefԠ\xba\xe9\x00 \xbb\xd8\xf1 \xbc\xdbW" + + " \xbd\xb8\xd3 \xbe\xb1\xfe\xa0\xbf\x98\xb5 \xc0\x9b\x1b \xc1x\x97 \xc2z\xfd \xc3Xy \xc4Q\xa4\xa0\xc58[ \xc6:\xc1 \xc7X֠\xc7\xda\t\xa0\xca\x16&\x90ʗY\x90\xcb\xd1\x1e" + + "\x90\xccw;\x90ͱ\x00\x90\xce`X\x10ϐ\xe2\x90\xd0n^\x90\xd1r\x16\x10\xd1\xfb2\x10\xd2i\xfe \xd3c)\xa0\xd4I\xe0 \xd5\x1e!\xa0\xd5B\xfd\x90\xd5\xdf\xe0\x10\xd6N\xac \xd6\xfe\x03" + + "\xa0\xd8.\x8e \xd8\xf9\x95 \xda\x0ep \xda\xeb\xec \xdb\xe5\x17\xa0\xdc\xcb\xce \xdd\xc4\xf9\xa0\u07b4\xea\xa0߮\x16 \xe0\x94̠\xe1rH\xa0\xe2kt \xe3R*\xa0\xe4T\x90\xa0\xe52\f" + + "\xa0\xe6=\xad \xe7\x1b) \xe8\x14T\xa0\xe8\xfb\v \xe9\xfdq \xea\xda\xed \xeb\xddS \xec\xba\xcf \xed\xb3\xfa\xa0\ue6b1 \xef\x81g\xa0\xf0\x9f} \xf1aI\xa0\xf2\u007f_ \xf3Jf" + + " \xf4_A \xf5!\r\xa0\xf6?# \xf7\x00\xef\xa0\xf8\x1f\x05 \xf8\xe0Ѡ\xf9\xfe\xe7 \xfa\xc0\xb3\xa0\xfb\xe8\x03\xa0\xfc{\xab\xa0\xfdǻp\x03p\xc6 \x04)X \x05P\xa8 \x06\t:" + + " \a0\x8a \a\xe9\x1c \t\x10l \t\xc8\xfe \n\xf0N \v\xb2\x1a\xa0\f\xd00 \r\x91\xfc\xa0\x0e\xb0\x12 \x0fqޠ\x10\x99.\xa0\x11Q\xc0\xa0\x12y\x10\xa0\x131\xa2\xa0\x14X\xf2" + + "\xa0\x15#\xeb\x90\x168Ɛ\x17\x03͐\x18\x18\xa8\x90\x18㯐\x19\xf8\x8a\x90\x1aÑ\x90\x1b\xe1\xa7\x10\x1c\xac\xae\x10\x1d\xc1\x89\x10\x1e\x8c\x90\x10\x1f\xa1k\x10 lr\x10!\x81M\x10\"LT" + + "\x10#a/\x10$,6\x10%JK\x90&\f\x18\x10'*-\x90'\xf54\x90)\n\x0f\x90)\xd5\x16\x90*\xe9\xf1\x90+\xb4\xf8\x90,\xc9Ӑ-\x94ڐ.\xa9\xb5\x90/t\xbc\x900\x89\x97" + + "\x901]\xd9\x102r\xb4\x103=\xbb\x104R\x96\x105\x1d\x9d\x1062x\x106\xfd\u007f\x108\x1b\x94\x908\xdda\x109\xfbv\x90:\xbdC\x10;\xdbX\x90<\xa6_\x90=\xbb:\x90>\x86A" + + "\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿" + + "\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4" + + "\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr" + + "\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2" + + "\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x06\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c" + + " \x01\f\x00\x00\x0e\x10\x00\x04\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\bLMT\x00BST\x00GMT\x00BDST\x00\x00\x01\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xf2\x00\x00\x00\a\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 " + + "\xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff" + + "\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ" + + "\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff" + + "\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0" + + "\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff" + + "\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 " + + "\xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff" + + "\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 " + + "\xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff" + + "\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠" + + "\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff" + + "\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 " + + "\xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\u007f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff" + + "\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0" + + "\xff\xff\xff\xff\xfdǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00" + + "\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ" + + "\x00\x00\x00\x00\x10\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x168Ɛ\x00\x00\x00\x00" + + "\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10" + + "\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00" + + "%JK\x90\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90" + + "\x00\x00\x00\x00,\xc9Ӑ\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00\x00\x001]\xd9\x10\x00\x00\x00\x002r\xb4\x10\x00\x00\x00\x00" + + "3=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\u007f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90" + + "\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00" + + "A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10" + + "\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00" + + "Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90" + + "\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00" + + "]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10" + + "\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00" + + "k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10" + + "\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00" + + "y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x06\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xff\xb5\x00\x00" + + "\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\bLMT\x00BST\x00GMT\x00BDST\x00\x00\x01\x01\x01\x00\x01\x01" + + "\x00\x00\x00\x00\x00\x01\x01\nGMT0BST,M3.5.0/1,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfcc!\x8eQ\n\x00\x00Q\n\x00\x00\x11" + + "\x00\x1c\x00Europe/San_MarinoUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xa9\x00\x00\x00\a\x00\x00\x00\r\x80\x00\x00\x00\x9b8\xf8p\x9b\xd5\xcc\xe0\x9c\xc5\xcb\xf0\x9d\xb7\x00`\x9e\x89\xfep\x9f\xa0\x1c\xe0" + + "\xa0`\xa5\xf0\xa1~\xad`\xa2\\7p\xa3L\x1a`\xc8l5\xf0\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10\xd0n^\x90\xd1r\x16\x10\xd2L\xd2\xf0\xd3>1\x90\xd4I\xd2\x10\xd5\x1d\xf7p" + + "\xd6)\x97\xf0\xd6뀐\xd8\t\x96\x10\xf93\xb5\xf0\xf9\xd9\xc4\xe0\xfb\x1c\xd2p\xfb\xb9\xb4\xf0\xfc\xfc\xb4p\xfd\x99\x96\xf0\xfe\xe5\xd0\xf0\xff\x82\xb3p\x00Ų\xf0\x01b\x95p\x02\x9cZp\x03Bwp" + + "\x04\x85v\xf0\x05+\x93\xf0\x06n\x93p\a\vu\xf0\bE:\xf0\b\xebW\xf0\n.Wp\n\xcb9\xf0\f\x0e9p\f\xab\x1b\xf0\r\xe4\xe0\xf0\x0e\x8a\xfd\xf0\x0f\xcd\xfdp\x10t\x1ap\x11\xad\xdfp" + + "\x12S\xfcp\x13MD\x10\x143\xfa\x90\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10" + + " lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10" + + "J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10" + + "X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90" + + "g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10" + + "u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x03\x04\x03\x04\x03\x01\x02\x04\x03\x04\x03\x04\x03\x04\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\v\xb4\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x0e\x10\x00" + + "\t\x00\x00\x1c \x01\x04\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\xaa\x00\x00\x00\b\x00\x00\x00\x11\xff\xff\xff\xff>(\xe8L\xff\xff\xff\xffp\xbc\x81p\xff\xff\xff\xff\x9b8\xf8p\xff\xff\xff\xff\x9b\xd5" + + "\xcc\xe0\xff\xff\xff\xff\x9c\xc5\xcb\xf0\xff\xff\xff\xff\x9d\xb7\x00`\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0\x1c\xe0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xad`\xff\xff\xff\xff\xa2\\7p\xff\xff" + + "\xff\xff\xa3L\x1a`\xff\xff\xff\xff\xc8l5\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r" + + "\x16\x10\xff\xff\xff\xff\xd2L\xd2\xf0\xff\xff\xff\xff\xd3>1\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd5\x1d\xf7p\xff\xff\xff\xff\xd6)\x97\xf0\xff\xff\xff\xff\xd6뀐\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff" + + "\xff\xff\xf93\xb5\xf0\xff\xff\xff\xff\xf9\xd9\xc4\xe0\xff\xff\xff\xff\xfb\x1c\xd2p\xff\xff\xff\xff\xfb\xb9\xb4\xf0\xff\xff\xff\xff\xfc\xfc\xb4p\xff\xff\xff\xff\xfd\x99\x96\xf0\xff\xff\xff\xff\xfe\xe5\xd0\xf0\xff\xff\xff\xff\xff\x82" + + "\xb3p\x00\x00\x00\x00\x00Ų\xf0\x00\x00\x00\x00\x01b\x95p\x00\x00\x00\x00\x02\x9cZp\x00\x00\x00\x00\x03Bwp\x00\x00\x00\x00\x04\x85v\xf0\x00\x00\x00\x00\x05+\x93\xf0\x00\x00\x00\x00\x06n\x93p\x00\x00" + + "\x00\x00\a\vu\xf0\x00\x00\x00\x00\bE:\xf0\x00\x00\x00\x00\b\xebW\xf0\x00\x00\x00\x00\n.Wp\x00\x00\x00\x00\n\xcb9\xf0\x00\x00\x00\x00\f\x0e9p\x00\x00\x00\x00\f\xab\x1b\xf0\x00\x00\x00\x00\r\xe4" + + "\xe0\xf0\x00\x00\x00\x00\x0e\x8a\xfd\xf0\x00\x00\x00\x00\x0f\xcd\xfdp\x00\x00\x00\x00\x10t\x1ap\x00\x00\x00\x00\x11\xad\xdfp\x00\x00\x00\x00\x12S\xfcp\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00" + + "\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc" + + "\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00" + + "\x00\x00#\x86A\x90\x00\x00" + + "\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05" + + "ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00" + + "\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TL" + + "G\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00" + + "\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?" + + "\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00" + + "\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x86" + + "5\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00" + + "\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y" + + "\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x02\x03\x05\x04\x05\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" + + "\x00\x00\v\xb4\x00\x00\x00\x00\v\xb4\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x01\b\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00RMT\x00CEST" + + "\x00CET\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5" + + "F\x9cP\xb1\xb5z\xa7\xec\v\x00\x00\xec\v\x00\x00\x10\x00\x1c\x00Europe/GibraltarUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14" + + "\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xc6\x00\x00\x00\a\x00\x00\x00\x1a\x80\x00\x00\x00\x9b&\xad\xa0\x9b\xd6\x05 \x9c" + + "\xcf0\xa0\x9d\xa4à\x9e\x9c\x9d\xa0\x9f\x97\x1a\xa0\xa0\x85\xba \xa1v\xfc\xa0\xa2e\x9c \xa3{Ƞ\xa4N\xb8\xa0\xa5?\xfb \xa6%` \xa7'\xc6 \xa8*, \xa8\xeb\xf8\xa0\xaa\x00Ӡ\xaa" + + "\xd5\x15 \xab\xe9\xf0 \xac\xc7l \xad\xc9\xd2 \xae\xa7N \xaf\xa0y\xa0\xb0\x870 \xb1\x92Р\xb2pL\xa0\xb3r\xb2\xa0\xb4P.\xa0\xb5IZ \xb60\x10\xa0\xb72v\xa0\xb8\x0f\xf2\xa0\xb9" + + "\x12X\xa0\xb9\xefԠ\xba\xe9\x00 \xbb\xd8\xf1 \xbc\xdbW \xbd\xb8\xd3 \xbe\xb1\xfe\xa0\xbf\x98\xb5 \xc0\x9b\x1b \xc1x\x97 \xc2z\xfd \xc3Xy \xc4Q\xa4\xa0\xc58[ \xc6:\xc1 \xc7" + + "X֠\xc7\xda\t\xa0\xca\x16&\x90ʗY\x90\xcb\xd1\x1e\x90\xccw;\x90ͱ\x00\x90\xce`X\x10ϐ\xe2\x90\xd0n^\x90\xd1r\x16\x10\xd1\xfb2\x10\xd2i\xfe \xd3c)\xa0\xd4I\xe0 \xd5" + + "\x1e!\xa0\xd5B\xfd\x90\xd5\xdf\xe0\x10\xd6N\xac \xd6\xfe\x03\xa0\xd8.\x8e \xd8\xf9\x95 \xda\x0ep \xda\xeb\xec \xdb\xe5\x17\xa0\xdc\xcb\xce \xdd\xc4\xf9\xa0\u07b4\xea\xa0߮\x16 \xe0\x94̠\xe1" + + "rH\xa0\xe2kt \xe3R*\xa0\xe4T\x90\xa0\xe52\f\xa0\xe6=\xad \xe7\x1b) \xe8\x14T\xa0\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d" + + "\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G" + + "\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V" + + ",)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d" + + "\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10r" + + "f\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02" + + "\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xfa\xfc\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x11\x00\x00\x1c \x01\x15\x00\x00\x0e\x10\x00\x11L" + + "MT\x00BST\x00GMT\x00BDST\x00CET\x00CEST\x00\x00\x01\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xc6\x00\x00\x00\a\x00\x00\x00\x1a\xff\xff\xff\xffW\xd1\n\x04\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d" + + "\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff" + + "\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab" + + "\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff" + + "\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9" + + "\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff" + + "\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7" + + "\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff" + + "\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5" + + "B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff" + + "\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2" + + "kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\x00\x00\x00\x00\x17\x03͐\x00" + + "\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e" + + "\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00" + + "\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I" + + "\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00" + + "\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V" + + "\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00" + + "\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e" + + "=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00" + + "\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s" + + "1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00" + + "\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\xff\xff\xfa\xfc\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x11\x00\x00\x1c \x01\x15\x00\x00\x0e\x10\x00\x11LMT\x00BST\x00GMT\x00B" + + "DST\x00CET\x00CEST\x00\x00\x01\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n" + + "\x00\x00\x00\x00\x00\xf5F\x9cP\xcd\xc6JÀ\a\x00\x00\x80\a\x00\x00\x0f\x00\x1c\x00Europe/BelgradeUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5" + + "\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00w\x00\x00\x00\a\x00\x00\x00\r\x80\x00\x00\x00\xca\x025\xe0" + + "\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10Ђ%\x10ѡ\x8c\x10\xd2N@\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10" + + " lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10" + + "J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10" + + "X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90" + + "g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10" + + "u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x04\x02\x03\x02\x03\x02\x03\x02\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00" + + "\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\b\x00\x00\x1c \x01\b\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\x04LMT\x00CET\x00CEST\x00\x00\x00\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01TZif" + + "2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00w\x00\x00\x00\a\x00\x00\x00\r\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff" + + "\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xffѡ\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18㯐" + + "\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00" + + " lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10" + + "\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00" + + "J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90" + + "\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00" + + "X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10" + + "\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00" + + "g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90" + + "\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00" + + "u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90" + + "\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x04\x02\x03\x02\x03\x02\x03\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\b\x00\x00\x1c \x01" + + "\b\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\x04LMT\x00CET\x00CEST\x00\x00\x00\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M1" + + "0.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa5\xa2\x06\xaf@\x0e\x00\x00@\x0e\x00\x00\x0f\x00\x1c\x00Europe/GuernseyUT\t\x00\x03n\xd3" + + "\xa7^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xf2\x00\x00\x00" + + "\a\x00\x00\x00\x11\x80\x00\x00\x00\x9b&\xad\xa0\x9b\xd6\x05 \x9c\xcf0\xa0\x9d\xa4à\x9e\x9c\x9d\xa0\x9f\x97\x1a\xa0\xa0\x85\xba \xa1v\xfc\xa0\xa2e\x9c \xa3{Ƞ\xa4N\xb8\xa0\xa5?\xfb \xa6%`" + + " \xa7'\xc6 \xa8*, \xa8\xeb\xf8\xa0\xaa\x00Ӡ\xaa\xd5\x15 \xab\xe9\xf0 \xac\xc7l \xad\xc9\xd2 \xae\xa7N \xaf\xa0y\xa0\xb0\x870 \xb1\x92Р\xb2pL\xa0\xb3r\xb2\xa0\xb4P." + + "\xa0\xb5IZ \xb60\x10\xa0\xb72v\xa0\xb8\x0f\xf2\xa0\xb9\x12X\xa0\xb9\xefԠ\xba\xe9\x00 \xbb\xd8\xf1 \xbc\xdbW \xbd\xb8\xd3 \xbe\xb1\xfe\xa0\xbf\x98\xb5 \xc0\x9b\x1b \xc1x\x97 \xc2z\xfd" + + " \xc3Xy \xc4Q\xa4\xa0\xc58[ \xc6:\xc1 \xc7X֠\xc7\xda\t\xa0\xca\x16&\x90ʗY\x90\xcb\xd1\x1e\x90\xccw;\x90ͱ\x00\x90\xce`X\x10ϐ\xe2\x90\xd0n^\x90\xd1r\x16" + + "\x10\xd1\xfb2\x10\xd2i\xfe \xd3c)\xa0\xd4I\xe0 \xd5\x1e!\xa0\xd5B\xfd\x90\xd5\xdf\xe0\x10\xd6N\xac \xd6\xfe\x03\xa0\xd8.\x8e \xd8\xf9\x95 \xda\x0ep \xda\xeb\xec \xdb\xe5\x17\xa0\xdc\xcb\xce" + + " \xdd\xc4\xf9\xa0\u07b4\xea\xa0߮\x16 \xe0\x94̠\xe1rH\xa0\xe2kt \xe3R*\xa0\xe4T\x90\xa0\xe52\f\xa0\xe6=\xad \xe7\x1b) \xe8\x14T\xa0\xe8\xfb\v \xe9\xfdq \xea\xda\xed" + + " \xeb\xddS \xec\xba\xcf \xed\xb3\xfa\xa0\ue6b1 \xef\x81g\xa0\xf0\x9f} \xf1aI\xa0\xf2\u007f_ \xf3Jf \xf4_A \xf5!\r\xa0\xf6?# \xf7\x00\xef\xa0\xf8\x1f\x05 \xf8\xe0\xd1" + + "\xa0\xf9\xfe\xe7 \xfa\xc0\xb3\xa0\xfb\xe8\x03\xa0\xfc{\xab\xa0\xfdǻp\x03p\xc6 \x04)X \x05P\xa8 \x06\t: \a0\x8a \a\xe9\x1c \t\x10l \t\xc8\xfe \n\xf0N \v\xb2\x1a" + + "\xa0\f\xd00 \r\x91\xfc\xa0\x0e\xb0\x12 \x0fqޠ\x10\x99.\xa0\x11Q\xc0\xa0\x12y\x10\xa0\x131\xa2\xa0\x14X\xf2\xa0\x15#\xeb\x90\x168Ɛ\x17\x03͐\x18\x18\xa8\x90\x18㯐\x19\xf8\x8a" + + "\x90\x1aÑ\x90\x1b\xe1\xa7\x10\x1c\xac\xae\x10\x1d\xc1\x89\x10\x1e\x8c\x90\x10\x1f\xa1k\x10 lr\x10!\x81M\x10\"LT\x10#a/\x10$,6\x10%JK\x90&\f\x18\x10'*-\x90'\xf54" + + "\x90)\n\x0f\x90)\xd5\x16\x90*\xe9\xf1\x90+\xb4\xf8\x90,\xc9Ӑ-\x94ڐ.\xa9\xb5\x90/t\xbc\x900\x89\x97\x901]\xd9\x102r\xb4\x103=\xbb\x104R\x96\x105\x1d\x9d\x1062x" + + "\x106\xfd\u007f\x108\x1b\x94\x908\xdda\x109\xfbv\x90:\xbdC\x10;\xdbX\x90<\xa6_\x90=\xbb:\x90>\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7" + + "\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle" + + "\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5" + + "\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S" + + "\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\xc2" + + "\x90}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x04\x06\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\bLMT" + + "\x00BST\x00GMT\x00BDST\x00\x00\x01\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00" + + "\x00\x00\x00\xf2\x00\x00\x00\a\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0" + + "\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff" + + "\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l " + + "\xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff" + + "\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 " + + "\xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff" + + "\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90" + + "\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff" + + "\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10" + + "\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff" + + "\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0" + + "\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff" + + "\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0" + + "\xff\xff\xff\xff\xf2\u007f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff" + + "\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfdǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X " + + "\x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00" + + "\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\x00\x00\x00\x00\x10\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0" + + "\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x168Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00" + + "\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10" + + "\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00" + + "'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xc9Ӑ\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90" + + "\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00\x00\x001]\xd9\x10\x00\x00\x00\x002r\xb4\x10\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x00" + + "62x\x10\x00\x00\x00\x006\xfd\u007f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90" + + "\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00" + + "D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10" + + "\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00" + + "Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90" + + "\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00" + + "`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90" + + "\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00" + + "n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10" + + "\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00" + + "|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x06\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04" + + "\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\bLMT\x00BST\x00GMT\x00BDST\x00\x00\x01\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01\nGMT0BST,M3.5.0/1" + + ",M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPx\xefo`\xf3\x04\x00\x00\xf3\x04\x00\x00\x10\x00\x1c\x00Europe/UlyanovskUT\t\x00\x03" + + "nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00C\x00" + + "\x00\x00\f\x00\x00\x00\x14\xa1\x009\x80\xb5\xa4\vP\x15'\x99\xc0\x16\x18\xce0\x17\b\xcd@\x17\xfa\x01\xb0\x18\xea\x00\xc0\x19\xdb50\x1a̅\xc0\x1b\xbc\x92\xe0\x1c\xac\x83\xe0\x1d\x9ct\xe0\x1e\x8ce\xe0\x1f" + + "|V\xe0 lG\xe0!\\8\xe0\"L)\xe0#<\x1a\xe0$,\v\xe0%\x1c\n\xf0&\v\xfb\xf0'\x05'p'\xf5\x18p(\xe5\x17\x80)x\xbf\x80)\xd4\xfap*\xc4\xebp+\xb4\xdcp," + + "\xa4\xcdp-\x94\xbep.\x84\xafp/t\xa0p0d\x91p1]\xbc\xf02r\x97\xf03=\x9e\xf04Ry\xf05\x1d\x80\xf062[\xf06\xfdb\xf08\x1bxp8\xddD\xf09\xfbZp:" + + "\xbd&\xf0;\xdb\x86%p?\x9b\x00p@f\apA\x84\x1c\xf0BE\xe9pCc\xfe\xf0D%\xcbpEC\xe0\xf0F\x05\xadpG#\xc2\xf0G\xee\xc9\xf0I" + + "\x03\xa4\xf0IΫ\xf0J\xe3\x86\xf0K\xae\x8d\xf0ḶpM\x8eo\xf0TL\x1d`V\xf7\x14p\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x06\a\b\t\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x04\a\x04\x04\x00\x00-`\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\b" + + "\x00\x008@\x00\f\x00\x008@\x00\f\x00\x00FP\x01\b\x00\x008@\x01\f\x00\x00*0\x00\x04\x00\x00*0\x01\x04\x00\x00\x1c \x00\x10\x00\x008@\x01\f\x00\x008@\x00\fLMT\x00+0" + + "3\x00+05\x00+04\x00+02\x00\x00\x01\x00\x00\x01\x01\x01\x01\x01\x01\x01\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\f\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\f\x00\x00\x00\x14\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b" + + "\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00" + + "\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1c" + + "\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)x\xbf\x80\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00" + + "\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r" + + "\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00" + + "\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f" + + "\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00" + + "\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL" + + "\x1d`\x00\x00\x00\x00V\xf7\x14p\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x06\a\b\t\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" + + "\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x04\a\x04\x04\x00\x00-`\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x00\f\x00\x00FP\x01" + + "\b\x00\x008@\x01\f\x00\x00*0\x00\x04\x00\x00*0\x01\x04\x00\x00\x1c \x00\x10\x00\x008@\x01\f\x00\x008@\x00\fLMT\x00+03\x00+05\x00+04\x00+02\x00\x00\x01\x00" + + "\x00\x01\x01\x01\x01\x01\x01\x01\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n<+04>-4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPp\xfe'd\x9f\x04\x00\x00\x9f\x04\x00\x00\x0e\x00\x1c\x00" + + "Europe/SaratovUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\t\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x00\t\x00\x00\x00\x10\xa1\x009\x80\xb5\xa4\vP\x15'\x99\xc0\x16\x18\xce0\x17\b\xcd@\x17\xfa\x01\xb0\x18\xea\x00\xc0\x19\xdb50\x1a\xcc" + + "\x85\xc0\x1b\xbc\x92\xe0\x1c\xac\x83\xe0\x1d\x9ct\xe0\x1e\x8ce\xe0\x1f|V\xe0 lG\xe0!\\8\xe0\"L)\xe0#<(\xf0$,\x19\xf0%\x1c\n\xf0&\v\xfb\xf0'\x05'p'\xf5\x18p)\xd4" + + "\xec`*\xc4\xebp+\xb4\xdcp,\xa4\xcdp-\x94\xbep.\x84\xafp/t\xa0p0d\x91p1]\xbc\xf02r\x97\xf03=\x9e\xf04Ry\xf05\x1d\x80\xf062[\xf06\xfdb\xf08\x1b" + + "xp8\xddD\xf09\xfbZp:\xbd&\xf0;\xdb\x86%p?\x9b\x00p@f\apA\x84\x1c\xf0BE\xe9pCc\xfe\xf0D%\xcbpEC\xe0\xf0F\x05" + + "\xadpG#\xc2\xf0G\xee\xc9\xf0I\x03\xa4\xf0IΫ\xf0J\xe3\x86\xf0K\xae\x8d\xf0ḶpM\x8eo\xf0TL\x1d`XCNp\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04" + + "\x05\x04\x06\a\x06\a\x06\a\x04\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x04\a\x04\x04\x00\x00+2\x00\x00\x00\x00*" + + "0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x00\f\x00\x00FP\x01\b\x00\x008@\x01\f\x00\x00*0\x00\x04\x00\x008@\x00\fLMT\x00+03\x00+05\x00+04" + + "\x00\x00\x01\x00\x00\x01\x01\x01\x01\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x00\t\x00" + + "\x00\x00\x10\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00" + + "\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 " + + "lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00" + + "\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/" + + "t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00" + + "\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00" + + "\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K" + + "\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x00\x00\x00\x00XCNp\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x06" + + "\a\x06\a\x06\a\x04\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x04\a\x04\x04\x00\x00+2\x00\x00\x00\x00*0\x00\x04" + + "\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x00\f\x00\x00FP\x01\b\x00\x008@\x01\f\x00\x00*0\x00\x04\x00\x008@\x00\fLMT\x00+03\x00+05\x00+04\x00\x00\x01" + + "\x00\x00\x01\x01\x01\x01\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\n<+04>-4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPy\xcc\x01\x9du\a\x00\x00u\a\x00\x00\f\x00\x1c\x00Europ" + + "e/VaduzUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00" + + "\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00w\x00\x00\x00\x05\x00\x00\x00\r\x80\x00\x00\x00\xca\x17j\x00\xca\xe2q\x00\xcb\xf7L\x00\xcc\xc2S\x00\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19" + + "Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D" + + "%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90R" + + "le\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`" + + "_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n" + + "\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|" + + "\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\b\x00\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\x00\x00\x00" + + "\x01\x01\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00x\x00\x00\x00\x06\x00\x00\x00\x11\xff\xff\xff\xff$\xf0\xea\x80\xff" + + "\xff\xff\xffq\xd4\x06\x86\xff\xff\xff\xff\xca\x17j\x00\xff\xff\xff\xff\xca\xe2q\x00\xff\xff\xff\xff\xcb\xf7L\x00\xff\xff\xff\xff\xcc\xc2S\x00\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17" + + "\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00" + + "\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A" + + "\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00" + + "\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00O" + + "nn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00" + + "\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]" + + "\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00" + + "\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k" + + "\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00" + + "\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y" + + "\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x03\x02\x03\x02\x03\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x00\x00\b\x00\x00\x00\x00\x00\x06" + + "\xfa\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00BMT\x00CEST\x00CET\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x01\x01\nCET" + + "-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc2\xf47\xbd\x9b\a\x00\x00\x9b\a\x00\x00\x0f\x00\x1c\x00Europe" + + "/IstanbulUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\v\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00t\x00\x00\x00\v\x00\x00\x00\x19\x80\x00\x00\x00\x90\x8b\xf5\x98\x9b\f\x17`\x9bվТec\xe0\xa3{\x82P\xa4N\x80`\xa5?\xb4Ц%'\xe0\xa7'\u007f" + + "Ъ((`\xaa\xe1\xfdЫ\xf9\x89\xe0\xac\xc31Pȁ?\xe0\xc9\x01\x13P\xc9J\xf5`\xca\u0380P\xcbˮ`\xd2k\tPӢ9`\xd4C\x02P\xd5L\r\xe0\xd6){\xd0\xd7+\xef" + + "\xe0\xd8\t]\xd0\xd9\x02\x97`\xd9\xe9?\xd0\xda\xeb\xb3\xe0\xdb\xd2\\P\xdc\xd4\xd0`ݲ>P\xf1\xf4\xb9`\xf4b\xefP\xf5h\x06`\xf6\x1f8\xd0\x06n\x93p\a9\x9ap\a\xfbu\x00\t\x19|" + + "p\t\xd0\xcb\x00\n\xf9^p\v\xb1\xfe\x80\f\xd9@p\r\xa4U\x80\x0e\xa6\xadp\x0f\x847\x80\x0f\xf8\x11P\x19\x89\xb0p\x19ܰ\xe0\x1b\xe6\xd0\xf0\x1c\xc6\xef\xf0\x1d\x9b1p\x1e\x8cs\xf0\x1f|d" + + "\xf0 lU\xf0!\\F\xf0\"L7\xf0#<(\xf0$,\x19\xf0%\x1c\n\xf0&\v\xfb\xf0'\x05'p'\xf5\x18p(\xe5\tp)\xd4\xfap*\xc4\xebp+\xb4\xdcp,\xa4\xcdp-\x8b\x83" + + "\xf0.\x84\xafp/t\xa0p0d\x91p1]\xbc\xf02r\x97\xf03=\x9e\xf04Ry\xf05\x1d\x80\xf062[\xf06\xfdb\xf08\x1bxp8\xddD\xf09\xfbZp:\xbd&\xf0;\xdb<" + + "p<\xa6Cp=\xbb\x1ep>\x86%p?\x9b\x00p@f\apA\x84\x1c\xf0BE\xe9pCc\xfe\xf0D%\xcbpEC\xe0\xf0F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8" + + "\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8fݐN\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S8\xbe\x10TLG\x90U\x17N\x90V>\x9e\x90V\xf70\x90W\xcf." + + "P\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x03\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\x04" + + "\x04\x00\x00\x1b(\x00\x00\x00\x00\x1bh\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x00\x11\x00\x008@\x01\x15\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x01\b\x00\x00\x1c \x00" + + "\r\x00\x00*0\x00\x11LMT\x00IMT\x00EEST\x00EET\x00+03\x00+04\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00TZif2\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00t\x00\x00\x00\v\x00\x00\x00\x19\xff\xff\xff\xffV\xb6\xc8\xd8\xff\xff\xff\xff\x90\x8b\xf5\x98\xff\xff\xff\xff\x9b\f" + + "\x17`\xff\xff\xff\xff\x9bվ\xd0\xff\xff\xff\xff\xa2ec\xe0\xff\xff\xff\xff\xa3{\x82P\xff\xff\xff\xff\xa4N\x80`\xff\xff\xff\xff\xa5?\xb4\xd0\xff\xff\xff\xff\xa6%'\xe0\xff\xff\xff\xff\xa7'\u007f\xd0\xff\xff" + + "\xff\xff\xaa((`\xff\xff\xff\xff\xaa\xe1\xfd\xd0\xff\xff\xff\xff\xab\xf9\x89\xe0\xff\xff\xff\xff\xac\xc31P\xff\xff\xff\xffȁ?\xe0\xff\xff\xff\xff\xc9\x01\x13P\xff\xff\xff\xff\xc9J\xf5`\xff\xff\xff\xff\xca\xce" + + "\x80P\xff\xff\xff\xff\xcbˮ`\xff\xff\xff\xff\xd2k\tP\xff\xff\xff\xffӢ9`\xff\xff\xff\xff\xd4C\x02P\xff\xff\xff\xff\xd5L\r\xe0\xff\xff\xff\xff\xd6){\xd0\xff\xff\xff\xff\xd7+\xef\xe0\xff\xff" + + "\xff\xff\xd8\t]\xd0\xff\xff\xff\xff\xd9\x02\x97`\xff\xff\xff\xff\xd9\xe9?\xd0\xff\xff\xff\xff\xda\xeb\xb3\xe0\xff\xff\xff\xff\xdb\xd2\\P\xff\xff\xff\xff\xdc\xd4\xd0`\xff\xff\xff\xffݲ>P\xff\xff\xff\xff\xf1\xf4" + + "\xb9`\xff\xff\xff\xff\xf4b\xefP\xff\xff\xff\xff\xf5h\x06`\xff\xff\xff\xff\xf6\x1f8\xd0\x00\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\a9\x9ap\x00\x00\x00\x00\a\xfbu\x00\x00\x00\x00\x00\t\x19|p\x00\x00" + + "\x00\x00\t\xd0\xcb\x00\x00\x00\x00\x00\n\xf9^p\x00\x00\x00\x00\v\xb1\xfe\x80\x00\x00\x00\x00\f\xd9@p\x00\x00\x00\x00\r\xa4U\x80\x00\x00\x00\x00\x0e\xa6\xadp\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x0f\xf8" + + "\x11P\x00\x00\x00\x00\x19\x89\xb0p\x00\x00\x00\x00\x19ܰ\xe0\x00\x00\x00\x00\x1b\xe6\xd0\xf0\x00\x00\x00\x00\x1c\xc6\xef\xf0\x00\x00\x00\x00\x1d\x9b1p\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00" + + "\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05" + + "'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\tp\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x8b\x83\xf0\x00\x00" + + "\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d" + + "\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc" + + "\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00" + + "\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8fݐ\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW" + + "\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S8\xbe\x10\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V>\x9e\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00W\xcf.P\x00\x00" + + "\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x03\x06\a\x06" + + "\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b" + + "\x04\x04\x00\x00\x1b(\x00\x00\x00\x00\x1bh\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x00\x11\x00\x008@\x01\x15\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x01\b\x00\x00\x1c " + + "\x00\r\x00\x00*0\x00\x11LMT\x00IMT\x00EEST\x00EET\x00+03\x00+04\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\n<+03" + + ">-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf2J꿍\r\x00\x00\x8d\r\x00\x00\r\x00\x1c\x00Europe/LisbonUT\t\x00\x03nӧ^nӧ^" + + "ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\xde\x00\x00\x00\f\x00\x00\x00\x1b\x80" + + "\x00\x00\x00\x92掀\x9bKmp\x9b\xfeǀ\x9c\x9c\xedp\x9dɃp\x9e\u007frp\x9f\xaa\xb6\xf0\xa0_Tp\xa1\x8b\xeap\xa2A\xd9p\xa3nop\xa4#\f\xf0\xa5O\xa2\xf0\xaa\x05\xefp\xaa" + + "\xf4\x8e\xf0\xadɧ\xf0\xae\xa7#\xf0\xaf\xa0Op\xb0\x87\x05\xf0\xb1\x89k\xf0\xb2p\"p\xb3r\x88p\xb4P\x04p\xb72Lp\xb8\x0f\xc8p\xb8\xff\xb9p\xb9\xef\xaap\xbcȷ\U0003de28\xf0\xbe" + + "\x9f_p\xbf\x98\x8a\xf0\xc0\x9a\xf0\xf0\xc1xl\xf0\xc2h]\xf0\xc3XN\xf0\xc4?\x05p\xc580\xf0\xc6:\x96\xf0\xc7X\xacp\xc7\xd9\xdfp\xc9\x01/p\xc9\xf1 p\xca\xe2b\xf0˵R\xf0\xcb" + + "\xec\xa3\xe0̀K\xe0\xccܢ\xf0͕4\xf0\xcd\xc3K`\xcer\xa2\xe0\xceſp\xcfu\x16\xf0Ϭg\xe0\xd0R\x84\xe0Х\xa1p\xd1T\xf8\xf0ьI\xe0\xd22f\xe0҅\x83p\xd3" + + "Y\xc4\xf0\xd4I\xb5\xf0\xd59\xd1 \xd6)\xc2 \xd7\x19\xb3 \xd8\t\xa4 \xd8\xf9\x95 \xd9\xe9\x86 ܹY ݲ\x84\xa0ޢu\xa0ߒf\xa0\xe0\x82W\xa0\xe1rH\xa0\xe2b9\xa0\xe3" + + "R*\xa0\xe4B\x1b\xa0\xe52\f\xa0\xe6!\xfd\xa0\xe7\x1b) \xe8\v\x1a \xe8\xfb\v \xe9\xea\xfc \xea\xda\xed \xeb\xca\xde \xec\xba\xcf \xed\xaa\xc0 \ue6b1 \uf2a2 \xf0z\x93 \xf1" + + "j\x84 \xf2c\xaf\xa0\xf3S\xa0\xa0\xf4C\x91\xa0\xf53\x82\xa0\xf6#s\xa0\xf7\x13d\xa0\xf8\x03U\xa0\xf8\xf3F\xa0\f\xab*\x00\r\x9b\x1b\x00\x0e\x8b\f\x00\x0f\x847\x80\x10t(\x80\x11d\x19\x80\x12" + + "T\x18\x90\x13C\xfb\x80\x143\xfa\x90\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㽠\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 " + + "lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J" + + "\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X" + + "\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g" + + "\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u" + + "\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x00\x06\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x03\x04\x03\x05\x03\x04\x03\x05\x03\x04\x03\x05\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\a\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\b\t" + + "\b\t\b\t\b\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n" + + "\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\xff\xff\xf7c\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\t\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\t\x00" + + "\x00\x1c \x01\r\x00\x00\x00\x00\x00\t\x00\x00\x0e\x10\x00\x12\x00\x00\x0e\x10\x00\x12\x00\x00\x1c \x01\x16\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\tLMT\x00WEST\x00WET\x00WEMT\x00C" + + "ET\x00CEST\x00\x00\x00\x00\x01\x01\x01\x01\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x01\x00\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\f" + + "\x00\x00\x00\x00\x00\x00\x00\xde\x00\x00\x00\f\x00\x00\x00\x1b\xff\xff\xff\xff^=\f\x1d\xff\xff\xff\xff\x92掀\xff\xff\xff\xff\x9bKmp\xff\xff\xff\xff\x9b\xfeǀ\xff\xff\xff\xff\x9c\x9c\xedp\xff\xff\xff\xff" + + "\x9dɃp\xff\xff\xff\xff\x9e\u007frp\xff\xff\xff\xff\x9f\xaa\xb6\xf0\xff\xff\xff\xff\xa0_Tp\xff\xff\xff\xff\xa1\x8b\xeap\xff\xff\xff\xff\xa2A\xd9p\xff\xff\xff\xff\xa3nop\xff\xff\xff\xff\xa4#\f\xf0" + + "\xff\xff\xff\xff\xa5O\xa2\xf0\xff\xff\xff\xff\xaa\x05\xefp\xff\xff\xff\xff\xaa\xf4\x8e\xf0\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff" + + "\xb1\x89k\xf0\xff\xff\xff\xff\xb2p\"p\xff\xff\xff\xff\xb3r\x88p\xff\xff\xff\xff\xb4P\x04p\xff\xff\xff\xff\xb72Lp\xff\xff\xff\xff\xb8\x0f\xc8p\xff\xff\xff\xff\xb8\xff\xb9p\xff\xff\xff\xff\xb9\xef\xaap" + + "\xff\xff\xff\xff\xbcȷ\xf0\xff\xff\xff\xff\xbd\xb8\xa8\xf0\xff\xff\xff\xff\xbe\x9f_p\xff\xff\xff\xff\xbf\x98\x8a\xf0\xff\xff\xff\xff\xc0\x9a\xf0\xf0\xff\xff\xff\xff\xc1xl\xf0\xff\xff\xff\xff\xc2h]\xf0\xff\xff\xff\xff" + + "\xc3XN\xf0\xff\xff\xff\xff\xc4?\x05p\xff\xff\xff\xff\xc580\xf0\xff\xff\xff\xff\xc6:\x96\xf0\xff\xff\xff\xff\xc7X\xacp\xff\xff\xff\xff\xc7\xd9\xdfp\xff\xff\xff\xff\xc9\x01/p\xff\xff\xff\xff\xc9\xf1 p" + + "\xff\xff\xff\xff\xca\xe2b\xf0\xff\xff\xff\xff˵R\xf0\xff\xff\xff\xff\xcb\xec\xa3\xe0\xff\xff\xff\xff̀K\xe0\xff\xff\xff\xff\xccܢ\xf0\xff\xff\xff\xff͕4\xf0\xff\xff\xff\xff\xcd\xc3K`\xff\xff\xff\xff" + + "\xcer\xa2\xe0\xff\xff\xff\xff\xceſp\xff\xff\xff\xff\xcfu\x16\xf0\xff\xff\xff\xffϬg\xe0\xff\xff\xff\xff\xd0R\x84\xe0\xff\xff\xff\xffХ\xa1p\xff\xff\xff\xff\xd1T\xf8\xf0\xff\xff\xff\xffьI\xe0" + + "\xff\xff\xff\xff\xd22f\xe0\xff\xff\xff\xff҅\x83p\xff\xff\xff\xff\xd3Y\xc4\xf0\xff\xff\xff\xff\xd4I\xb5\xf0\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd6)\xc2 \xff\xff\xff\xff\xd7\x19\xb3 \xff\xff\xff\xff" + + "\xd8\t\xa4 \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xd9\xe9\x86 \xff\xff\xff\xffܹY \xff\xff\xff\xffݲ\x84\xa0\xff\xff\xff\xffޢu\xa0\xff\xff\xff\xffߒf\xa0\xff\xff\xff\xff\xe0\x82W\xa0" + + "\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2b9\xa0\xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4B\x1b\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6!\xfd\xa0\xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff" + + "\xe8\v\x1a \xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xea\xfc \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xca\xde \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xaa\xc0 \xff\xff\xff\xff\ue6b1 " + + "\xff\xff\xff\xff\uf2a2 \xff\xff\xff\xff\xf0z\x93 \xff\xff\xff\xff\xf1j\x84 \xff\xff\xff\xff\xf2c\xaf\xa0\xff\xff\xff\xff\xf3S\xa0\xa0\xff\xff\xff\xff\xf4C\x91\xa0\xff\xff\xff\xff\xf53\x82\xa0\xff\xff\xff\xff" + + "\xf6#s\xa0\xff\xff\xff\xff\xf7\x13d\xa0\xff\xff\xff\xff\xf8\x03U\xa0\xff\xff\xff\xff\xf8\xf3F\xa0\x00\x00\x00\x00\f\xab*\x00\x00\x00\x00\x00\r\x9b\x1b\x00\x00\x00\x00\x00\x0e\x8b\f\x00\x00\x00\x00\x00\x0f\x847\x80" + + "\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11d\x19\x80\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13C\xfb\x80\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00" + + "\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㽠\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10" + + "\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00" + + "A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10" + + "\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00" + + "Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90" + + "\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00" + + "]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10" + + "\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00" + + "k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10" + + "\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00" + + "y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x00\x06\x01\x02\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x03\x04\x03\x05\x03\x04\x03\x05\x03\x04\x03\x05\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\a\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\b\t\b\t\b\t\b\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06" + + "\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\xff\xff\xf7c\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\t\x00\x00\x0e\x10\x01\x04\x00\x00" + + "\x00\x00\x00\t\x00\x00\x1c \x01\r\x00\x00\x00\x00\x00\t\x00\x00\x0e\x10\x00\x12\x00\x00\x0e\x10\x00\x12\x00\x00\x1c \x01\x16\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\tLMT\x00WEST\x00WET\x00W" + + "EMT\x00CET\x00CEST\x00\x00\x00\x00\x01\x01\x01\x01\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x01\x00\x01\x01\x01\x01\nWET0WEST,M3.5.0/1,M10." + + "5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xecD\xba\xc2\x02\b\x00\x00\x02\b\x00\x00\x0f\x00\x1c\x00Europe/UzhgorodUT\t\x00\x03nӧ^n\xd3" + + "\xa7^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00x\x00\x00\x00\f\x00\x00\x00" + + "\x1e\x80\x00\x00\x00\xc8\tq\x90\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10С\x9e\xe0\xd1\xe5\xfd\xf0\x15'\xa7\xd0\x16\x18\xdc@\x17\b\xdbP\x17\xfa\x0f\xc0\x18\xea\x0e\xd0\x19\xdbC@\x1a̓" + + "\xd0\x1b\xbc\xa0\xf0\x1c\xac\x91\xf0\x1d\x9c\x82\xf0\x1e\x8cs\xf0\x1f|d\xf0 lU\xf0!\\F\xf0\"L7\xf0#<(\xf0$,\x19\xf0%\x1c\n\xf0&\x8d.\xf0'\xf5B\xa0)\xd4\xec`*\xc4\xcf" + + "P+\xb4\xce`,\xa4\xb1P-\x94\xb0`.\x84\x93P/t\xbc\x900d\xad\x901]\xd9\x102r\xb4\x103=\xbb\x104R\x96\x105\x1d\x9d\x1062x\x106\xfd\u007f\x108\x1b\x94\x908\xdda" + + "\x109\xfbv\x90:\xbdC\x10;\xdbX\x90<\xa6_\x90=\xbb:\x90>\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf" + + "\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N" + + "\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]\xcc" + + "\x90d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<" + + "\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f" + + "\x90\x01\x02\x03\x02\x03\x02\x01\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x06\a\x06\a\x06\a\x06\a\x06\x01\b\t\b\t\b\t\b\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n" + + "\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n" + + "\v\x00\x00\x14\xe8\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\x04\x00\x008@\x01\r\x00\x00*0\x00\x11\x00\x00*0\x00\x11\x00\x008@\x01\r\x00\x00\x1c \x00\x15\x00\x00*0\x01" + + "\x19\x00\x00*0\x01\x19\x00\x00\x1c \x00\x15LMT\x00CET\x00CEST\x00MSD\x00MSK\x00EET\x00EEST\x00\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00x\x00\x00\x00\f\x00\x00\x00\x1e\xff\xff\xff\xffj\xee\xb0\x18\xff" + + "\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffС\x9e\xe0\xff\xff\xff\xff\xd1\xe5\xfd\xf0\x00\x00\x00\x00\x15" + + "'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00" + + "\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#" + + "<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\x8d.\xf0\x00\x00\x00\x00'\xf5B\xa0\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00" + + "\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x00\x00\x00\x002r\xb4\x10\x00\x00\x00\x003" + + "=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\u007f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00" + + "\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A" + + "\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00" + + "\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00O" + + "nn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00" + + "\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]" + + "\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00" + + "\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k" + + "\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00" + + "\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y" + + "\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x02\x03\x02\x03\x02\x01\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x06\a\x06\a\x06\a\x06\a\x06\a\x06\x01\b\t\b\t\b\t\b\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n" + + "\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\x00\x00\x14\xe8\x00\x00\x00\x00\x0e" + + "\x10\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\x04\x00\x008@\x01\r\x00\x00*0\x00\x11\x00\x00*0\x00\x11\x00\x008@\x01\r\x00\x00\x1c \x00\x15\x00\x00*0\x01\x19\x00\x00*0\x01\x19\x00\x00\x1c" + + " \x00\x15LMT\x00CET\x00CEST\x00MSD\x00MSK\x00EET\x00EEST\x00\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\nEE" + + "T-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP)\x1eCk\x81\x04\x00\x00\x81\x04\x00\x00\f\x00\x1c\x00Eur" + + "ope/KirovUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\b\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\b\x00\x00\x00\x10\xa1\x009\x80\xb5\xa4\vP\x15'\x99\xc0\x16\x18\xce0\x17\b\xcd@\x17\xfa\x01\xb0\x18\xea\x00\xc0\x19\xdb50\x1a̅\xc0\x1b\xbc\x92" + + "\xe0\x1c\xac\x83\xe0\x1d\x9ct\xe0\x1e\x8ce\xe0\x1f|V\xe0 lG\xe0!\\8\xe0\"L)\xe0#<\x1a\xe0$,\v\xe0%\x1c\n\xf0&\v\xfb\xf0'\x05'p'\xf5\x18p)\xd4\xec`*\xc4\xeb" + + "p+\xb4\xdcp,\xa4\xcdp-\x94\xbep.\x84\xafp/t\xa0p0d\x91p1]\xbc\xf02r\x97\xf03=\x9e\xf04Ry\xf05\x1d\x80\xf062[\xf06\xfdb\xf08\x1bxp8\xddD" + + "\xf09\xfbZp:\xbd&\xf0;\xdb\x86%p?\x9b\x00p@f\apA\x84\x1c\xf0BE\xe9pCc\xfe\xf0D%\xcbpEC\xe0\xf0F\x05\xadpG#\xc2" + + "\xf0G\xee\xc9\xf0I\x03\xa4\xf0IΫ\xf0J\xe3\x86\xf0K\xae\x8d\xf0ḶpM\x8eo\xf0TL\x1d`\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x06\a\x04" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x04\a\a\x00\x00.\x98\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00" + + "\x008@\x00\f\x00\x008@\x00\f\x00\x00FP\x01\b\x00\x008@\x01\f\x00\x00*0\x00\x04LMT\x00+03\x00+05\x00+04\x00\x00\x01\x00\x00\x01\x01\x01\x01\x00\x01\x00\x00\x00\x00\x00" + + "\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\b\x00\x00\x00\x10\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xb5\xa4\v" + + "P\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00" + + "\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)" + + "\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00" + + "\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc" + + "\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00" + + "\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb\x86%p\x00\x00\x00\x00?\x9b\x00" + + "p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00" + + "\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo" + + "\xf0\x00\x00\x00\x00TL\x1d`\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x06\a\x04\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x04\a\a\x00\x00.\x98\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x00\f\x00\x00FP\x01\b\x00\x008" + + "@\x01\f\x00\x00*0\x00\x04LMT\x00+03\x00+05\x00+04\x00\x00\x01\x00\x00\x01\x01\x01\x01\x00\x01\x00\x00\x00\x00\x00\x00\n<+03>-3\nPK\x03\x04\n\x00\x00\x00\x00\x00" + + "\xf5F\x9cP\xc1\x8c\xea\x8d$\b\x00\x00$\b\x00\x00\r\x00\x1c\x00Europe/TiraneUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00" + + "\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x85\x00\x00\x00\x05\x00\x00\x00\r\x96\xaa4h\xc8m\x87p\xcc\xe7K\x10ͩ\x17" + + "\x90\u0378\xe9\x90\b(9\xf0\b\xef>`\n\x05x\xf0\n\xd0q\xe0\v\xe9Op\f\xb4H`\r\xd2k\xf0\x0e\x94*`\x0f\xb0\xfcp\x10t\f`\x11\x90\xdep\x12S\xee`\x13p\xc0p\x14;\xb9" + + "`\x15H\xb9p\x16\x13\xb2`\x171\xd5\xf0\x17\xfc\xce\xe0\x19\x00\x94p\x19\xdb_`\x1a̯\xf0\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT" + + "\x10#\x86A" + + "\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿" + + "\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4" + + "\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr" + + "\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2" + + "\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x12\x98\x00\x00\x00\x00\x0e\x10" + + "\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLMT\x00CET\x00CEST\x00\x00\x00\x00\x01\x01\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x85\x00\x00\x00\x05\x00\x00\x00\r\xff\xff\xff\xff\x96\xaa4h\xff\xff\xff\xff\xc8m\x87p\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff" + + "\xff\xff\xff\u0378\xe9\x90\x00\x00\x00\x00\b(9\xf0\x00\x00\x00\x00\b\xef>`\x00\x00\x00\x00\n\x05x\xf0\x00\x00\x00\x00\n\xd0q\xe0\x00\x00\x00\x00\v\xe9Op\x00\x00\x00\x00\f\xb4H`\x00\x00\x00\x00\r" + + "\xd2k\xf0\x00\x00\x00\x00\x0e\x94*`\x00\x00\x00\x00\x0f\xb0\xfcp\x00\x00\x00\x00\x10t\f`\x00\x00\x00\x00\x11\x90\xdep\x00\x00\x00\x00\x12S\xee`\x00\x00\x00\x00\x13p\xc0p\x00\x00\x00\x00\x14;\xb9`\x00" + + "\x00\x00\x00\x15H\xb9p\x00\x00\x00\x00\x16\x13\xb2`\x00\x00\x00\x00\x171\xd5\xf0\x00\x00\x00\x00\x17\xfc\xce\xe0\x00\x00\x00\x00\x19\x00\x94p\x00\x00\x00\x00\x19\xdb_`\x00\x00\x00\x00\x1a̯\xf0\x00\x00\x00\x00\x1b" + + "\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00" + + "\x00\x00\x00#\x86A\x90\x00" + + "\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F" + + "\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00" + + "\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00T" + + "LG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00" + + "\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b" + + "?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00" + + "\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p" + + "\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00" + + "\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~" + + "y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x12\x98\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLMT\x00CE" + + "T\x00CEST\x00\x00\x00\x00\x01\x01\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPe" + + "\x8d\x0fgV\t\x00\x00V\t\x00\x00\x0f\x00\x1c\x00Europe/TiraspolUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZ" + + "if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x8d\x00\x00\x00\x10\x00\x00\x00&\x80\x00\x00\x00\x9ek\x9f\f\xb7\xb0\xd2\b\xb9>\xf3`\xb9\xef" + + "\x9c`\xbaߍ`\xbb\xcf~`\xbcȩླྀ\x9aྨ\x8b࿘|\xe0\xc0\x88m\xe0\xc1x^\xe0\xc2hO\xe0\xc3X@\xe0\xc4H1\xe0\xc58\"\xe0\xc6(\x13\xe0\xc7\x18\x04\xe0ȼ" + + "\x93`\xcaw}P\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10\xd0N\x90`\x15'\xa7\xd0\x16\x18\xdc@\x17\b\xdbP\x17\xfa\x0f\xc0\x18\xea\x0e\xd0\x19\xdbC@\x1a̓\xd0\x1b\xbc\xa0\xf0\x1c\xac" + + "\x91\xf0\x1d\x9c\x82\xf0\x1e\x8cs\xf0\x1f|d\xf0 lU\xf0!\\F\xf0\"L7\xf0#<(\xf0$,\x19\xf0%\x1c\n\xf0&\v\xfb\xf0&CL\xe0'\x055\x80'\xf5&\x80(\xe5\x17\x80)\xd4" + + "\xec`*\xc4\xcfP+\xb4\xce`,\xa4\xb1P-\x94\xb0`.\x84\x93P/t\x92`0duP1]\xae\xe02r{\xd03=\xad\x004R\x88\x005\x1d\x8f\x0062j\x006\xfdq\x008\x1b" + + "\x86\x808\xddS\x009\xfbh\x80:\xbd5\x00;\xdbJ\x80<\xa6Q\x80=\xbb,\x80>\x863\x80?\x9b\x0e\x80@f\x15\x80A\x84+\x00BE\xf7\x80Cd\r\x00D%ـEC\xef\x00F\x05" + + "\xbb\x80G#\xd1\x00G\xee\xd8\x00I\x03\xb3\x00Iκ\x00J\xe3\x95\x00K\xae\x9c\x00Ḻ\x80M\x8e~\x00N\xac\x93\x80On`\x00P\x8cu\x80QW|\x80RlW\x80S7^\x80TL" + + "9\x80U\x17@\x80V,\x1b\x80V\xf7\"\x80X\x158\x00X\xd7\x04\x80Y\xf5\x1a\x00Z\xb6\xe6\x80[\xd4\xfc\x00\\\xa0\x03\x00]\xb4\xde\x00^\u007f\xe5\x00_\x94\xc0\x00`_\xc7\x00a}܀b?" + + "\xa9\x00c]\xbe\x80d\x1f\x8b\x00e=\xa0\x80f\b\xa7\x80g\x1d\x82\x80g艀h\xfdd\x80i\xc8k\x80j\xddF\x80k\xa8M\x80l\xc6c\x00m\x88/\x80n\xa6E\x00oh\x11\x80p\x86" + + "'\x00qQ.\x00rf\t\x00s1\x10\x00tE\xeb\x00u\x10\xf2\x00v/\a\x80v\xf0\xd4\x00x\x0e\xe9\x80xж\x00y\xeeˀz\xb0\x98\x00{έ\x80|\x99\xb4\x80}\xae\x8f\x80~y" + + "\x96\x80\u007f\x8eq\x80\x01\x02\x05\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x06\t\a\b\a\b\v\n\v\n\v\n\v\n\f\r\f\r\f\r\f\r\f\r\f\r\x06\x04\x03\x04\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x00\x00\x1b\b\x00\x00\x00\x00\x1a\xf4\x00\x04\x00\x00\x18x\x00\b\x00\x00*0\x01\f\x00\x00\x1c \x00\x11\x00\x00\x1c" + + " \x00\x11\x00\x00*0\x01\f\x00\x00\x0e\x10\x00\x15\x00\x00\x1c \x01\x19\x00\x00\x1c \x01\x19\x00\x008@\x01\x1e\x00\x00*0\x00\"\x00\x00*0\x00\"\x00\x008@\x01\x1e\x00\x00*0\x01\f\x00\x00\x1c" + + " \x00\x11LMT\x00CMT\x00BMT\x00EEST\x00EET\x00CET\x00CEST\x00MSD\x00MSK\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x01\x01\x00\x00TZi" + + "f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x8d\x00\x00\x00\x10\x00\x00\x00&\xff\xff\xff\xffV\xb6\xc8\xf8\xff\xff\xff\xff\x9ek\x9f\f\xff\xff\xff" + + "\xff\xb7\xb0\xd2\b\xff\xff\xff\xff\xb9>\xf3`\xff\xff\xff\xff\xb9\xef\x9c`\xff\xff\xff\xff\xbaߍ`\xff\xff\xff\xff\xbb\xcf~`\xff\xff\xff\xff\xbcȩ\xe0\xff\xff\xff\xff\xbd\xb8\x9a\xe0\xff\xff\xff\xff\xbe\xa8\x8b" + + "\xe0\xff\xff\xff\xff\xbf\x98|\xe0\xff\xff\xff\xff\xc0\x88m\xe0\xff\xff\xff\xff\xc1x^\xe0\xff\xff\xff\xff\xc2hO\xe0\xff\xff\xff\xff\xc3X@\xe0\xff\xff\xff\xff\xc4H1\xe0\xff\xff\xff\xff\xc58\"\xe0\xff\xff\xff" + + "\xff\xc6(\x13\xe0\xff\xff\xff\xff\xc7\x18\x04\xe0\xff\xff\xff\xffȼ\x93`\xff\xff\xff\xff\xcaw}P\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4" + + "\x10\xff\xff\xff\xff\xd0N\x90`\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00" + + "\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F" + + "\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00&CL\xe0\x00\x00\x00\x00'\x055\x80\x00\x00\x00" + + "\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93" + + "P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x8f\x00\x00\x00\x00" + + "\x0062j\x00\x00\x00\x00\x006\xfdq\x00\x00\x00\x00\x008\x1b\x86\x80\x00\x00\x00\x008\xddS\x00\x00\x00\x00\x009\xfbh\x80\x00\x00\x00\x00:\xbd5\x00\x00\x00\x00\x00;\xdbJ\x80\x00\x00\x00\x00<\xa6Q" + + "\x80\x00\x00\x00\x00=\xbb,\x80\x00\x00\x00\x00>\x863\x80\x00\x00\x00\x00?\x9b\x0e\x80\x00\x00\x00\x00@f\x15\x80\x00\x00\x00\x00A\x84+\x00\x00\x00\x00\x00BE\xf7\x80\x00\x00\x00\x00Cd\r\x00\x00\x00\x00" + + "\x00D%ـ\x00\x00\x00\x00EC\xef\x00\x00\x00\x00\x00F\x05\xbb\x80\x00\x00\x00\x00G#\xd1\x00\x00\x00\x00\x00G\xee\xd8\x00\x00\x00\x00\x00I\x03\xb3\x00\x00\x00\x00\x00Iκ\x00\x00\x00\x00\x00J\xe3\x95" + + "\x00\x00\x00\x00\x00K\xae\x9c\x00\x00\x00\x00\x00Ḻ\x80\x00\x00\x00\x00M\x8e~\x00\x00\x00\x00\x00N\xac\x93\x80\x00\x00\x00\x00On`\x00\x00\x00\x00\x00P\x8cu\x80\x00\x00\x00\x00QW|\x80\x00\x00\x00" + + "\x00RlW\x80\x00\x00\x00\x00S7^\x80\x00\x00\x00\x00TL9\x80\x00\x00\x00\x00U\x17@\x80\x00\x00\x00\x00V,\x1b\x80\x00\x00\x00\x00V\xf7\"\x80\x00\x00\x00\x00X\x158\x00\x00\x00\x00\x00X\xd7\x04" + + "\x80\x00\x00\x00\x00Y\xf5\x1a\x00\x00\x00\x00\x00Z\xb6\xe6\x80\x00\x00\x00\x00[\xd4\xfc\x00\x00\x00\x00\x00\\\xa0\x03\x00\x00\x00\x00\x00]\xb4\xde\x00\x00\x00\x00\x00^\u007f\xe5\x00\x00\x00\x00\x00_\x94\xc0\x00\x00\x00\x00" + + "\x00`_\xc7\x00\x00\x00\x00\x00a}܀\x00\x00\x00\x00b?\xa9\x00\x00\x00\x00\x00c]\xbe\x80\x00\x00\x00\x00d\x1f\x8b\x00\x00\x00\x00\x00e=\xa0\x80\x00\x00\x00\x00f\b\xa7\x80\x00\x00\x00\x00g\x1d\x82" + + "\x80\x00\x00\x00\x00g艀\x00\x00\x00\x00h\xfdd\x80\x00\x00\x00\x00i\xc8k\x80\x00\x00\x00\x00j\xddF\x80\x00\x00\x00\x00k\xa8M\x80\x00\x00\x00\x00l\xc6c\x00\x00\x00\x00\x00m\x88/\x80\x00\x00\x00" + + "\x00n\xa6E\x00\x00\x00\x00\x00oh\x11\x80\x00\x00\x00\x00p\x86'\x00\x00\x00\x00\x00qQ.\x00\x00\x00\x00\x00rf\t\x00\x00\x00\x00\x00s1\x10\x00\x00\x00\x00\x00tE\xeb\x00\x00\x00\x00\x00u\x10\xf2" + + "\x00\x00\x00\x00\x00v/\a\x80\x00\x00\x00\x00v\xf0\xd4\x00\x00\x00\x00\x00x\x0e\xe9\x80\x00\x00\x00\x00xж\x00\x00\x00\x00\x00y\xeeˀ\x00\x00\x00\x00z\xb0\x98\x00\x00\x00\x00\x00{έ\x80\x00\x00\x00" + + "\x00|\x99\xb4\x80\x00\x00\x00\x00}\xae\x8f\x80\x00\x00\x00\x00~y\x96\x80\x00\x00\x00\x00\u007f\x8eq\x80\x01\x02\x05\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x06\t\a\b\a\b\v\n\v\n\v\n" + + "\v\n\f\r\f\r\f\r\f\r\f\r\f\r\x06\x04\x03\x04\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x00\x00\x1b\b\x00\x00\x00\x00\x1a\xf4" + + "\x00\x04\x00\x00\x18x\x00\b\x00\x00*0\x01\f\x00\x00\x1c \x00\x11\x00\x00\x1c \x00\x11\x00\x00*0\x01\f\x00\x00\x0e\x10\x00\x15\x00\x00\x1c \x01\x19\x00\x00\x1c \x01\x19\x00\x008@\x01\x1e\x00\x00*0" + + "\x00\"\x00\x00*0\x00\"\x00\x008@\x01\x1e\x00\x00*0\x01\f\x00\x00\x1c \x00\x11LMT\x00CMT\x00BMT\x00EEST\x00EET\x00CET\x00CEST\x00MSD\x00" + + "MSK\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x01\x01\x00\x00\nEET-2EEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F" + + "\x9cP\xcd\xc6JÀ\a\x00\x00\x80\a\x00\x00\x0f\x00\x1c\x00Europe/SarajevoUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00" + + "\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00w\x00\x00\x00\a\x00\x00\x00\r\x80\x00\x00\x00\xca\x025\xe0\xcc\xe7K\x10ͩ\x17" + + "\x90\u03a2C\x10ϒ4\x10Ђ%\x10ѡ\x8c\x10\xd2N@\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c" + + "\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa" + + "\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(" + + "\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g\xe8\x97" + + "\x90h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15" + + "\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x04\x02\x03\x02\x03\x02\x03\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x0e\x10\x00\x04\x00\x00" + + "\x1c \x01\b\x00\x00\x1c \x01\b\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\x04LMT\x00CET\x00CEST\x00\x00\x00\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00w\x00\x00\x00\a\x00\x00\x00\r\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff" + + "\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xffѡ\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ" + + "\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00" + + "\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7" + + "\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00" + + "\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle" + + "\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00" + + "\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5" + + "\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00" + + "\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S" + + "\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00" + + "\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\xc2" + + "\x90\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x04\x02\x03\x02\x03\x02\x03\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\b\x00\x00\x1c \x01\b\x00\x00\x1c \x01\b" + + "\x00\x00\x0e\x10\x00\x04LMT\x00CET\x00CEST\x00\x00\x00\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M10.5.0/3" + + "\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x93>\xe656\n\x00\x006\n\x00\x00\r\x00\x1c\x00Europe/MadridUT\t\x00\x03nӧ^nӧ^ux\v" + + "\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x00\x00\v\x00\x00\x00\x1b\x80\x00\x00\x00" + + "\x9e\xba\xc5\xf0\x9f\xa09\x00\xa0\x90\x1b\xf0\xa1\x81l\x80\xaa\x05\xefp\xaa\xe7n\x00\xadɧ\xf0\xae\xa72\x00\xaf\xa0Op\xb0\x87\x14\x00\xb1\x89z\x00\xb2p0\x80\xb3r\x88p\xb4P\x12\x80\xc2\xc9\xec\xf0" + + "\xc3X]\x00\xc4H?\xf0\xc4m\x1b\xe0\xc59t`\xc7![\x80\xc7\xf5\x8e\xf0\xcb\xf5\xde`̕q\xf0\xcd\xc3K`Π\xd5pϣ-`Ѐ\xb7pу\x0f`\xd2`\x99p\xd3b\xf1`" + + "\xd4@{p\xd9\x1eF\xe0\xd9\xe9[\xf0\b\r\xcd\xe0\b\xf4\x92p\t\xed\xaf\xe0\n\xd4tp\v\xbb\x1c\xe0\f\xab\x1b\xf0\r\xa49`\x0e\x8a\xfd\xf0\x0f\x84E\x90\x10t6\x90\x11d'\x90\x12T\x18\x90" + + "\x13MD\x10\x143\xfa\x90\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10" + + "!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10" + + "K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90" + + "Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90" + + "g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10" + + "v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x04\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x03\x01\x02\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\a\b\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n" + + "\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n" + + "\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\xff\xff\xfc\x8c\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\t\x00\x00\x1c \x01\r\x00\x00\x00\x00\x00\t\x00\x00\x1c " + + "\x01\x12\x00\x00\x0e\x10\x00\x17\x00\x00\x1c \x01\x12\x00\x00\x0e\x10\x00\x17\x00\x00\x1c \x01\x12\x00\x00\x0e\x10\x00\x17LMT\x00WEST\x00WET\x00WEMT\x00CEST\x00CET\x00\x00" + + "\x00\x01\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x00\x00" + + "\v\x00\x00\x00\x1b\xff\xff\xff\xff~6\xb5\x00\xff\xff\xff\xff\x9e\xba\xc5\xf0\xff\xff\xff\xff\x9f\xa09\x00\xff\xff\xff\xff\xa0\x90\x1b\xf0\xff\xff\xff\xff\xa1\x81l\x80\xff\xff\xff\xff\xaa\x05\xefp\xff\xff\xff\xff\xaa\xe7n" + + "\x00\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa72\x00\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x14\x00\xff\xff\xff\xff\xb1\x89z\x00\xff\xff\xff\xff\xb2p0\x80\xff\xff\xff\xff\xb3r\x88p\xff\xff\xff" + + "\xff\xb4P\x12\x80\xff\xff\xff\xff\xc2\xc9\xec\xf0\xff\xff\xff\xff\xc3X]\x00\xff\xff\xff\xff\xc4H?\xf0\xff\xff\xff\xff\xc4m\x1b\xe0\xff\xff\xff\xff\xc59t`\xff\xff\xff\xff\xc7![\x80\xff\xff\xff\xff\xc7\xf5\x8e" + + "\xf0\xff\xff\xff\xff\xcb\xf5\xde`\xff\xff\xff\xff̕q\xf0\xff\xff\xff\xff\xcd\xc3K`\xff\xff\xff\xffΠ\xd5p\xff\xff\xff\xffϣ-`\xff\xff\xff\xffЀ\xb7p\xff\xff\xff\xffу\x0f`\xff\xff\xff" + + "\xff\xd2`\x99p\xff\xff\xff\xff\xd3b\xf1`\xff\xff\xff\xff\xd4@{p\xff\xff\xff\xff\xd9\x1eF\xe0\xff\xff\xff\xff\xd9\xe9[\xf0\x00\x00\x00\x00\b\r\xcd\xe0\x00\x00\x00\x00\b\xf4\x92p\x00\x00\x00\x00\t\xed\xaf" + + "\xe0\x00\x00\x00\x00\n\xd4tp\x00\x00\x00\x00\v\xbb\x1c\xe0\x00\x00\x00\x00\f\xab\x1b\xf0\x00\x00\x00\x00\r\xa49`\x00\x00\x00\x00\x0e\x8a\xfd\xf0\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00" + + "\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe" + + "\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00" + + "\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05" + + "\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00" + + "\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83" + + "\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00" + + "\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3" + + "\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00" + + "\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q" + + "\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00" + + "\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6" + + "\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x04\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03" + + "\x01\x02\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\a\b\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t" + + "\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t" + + "\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\xff\xff\xfc\x8c\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\t\x00\x00\x1c \x01\r\x00\x00\x00\x00\x00\t\x00\x00\x1c \x01\x12\x00" + + "\x00\x0e\x10\x00\x17\x00\x00\x1c \x01\x12\x00\x00\x0e\x10\x00\x17\x00\x00\x1c \x01\x12\x00\x00\x0e\x10\x00\x17LMT\x00WEST\x00WET\x00WEMT\x00CEST\x00CET\x00\x00\x00\x01\x00" + + "\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP" + + "\xcd\xc6JÀ\a\x00\x00\x80\a\x00\x00\x10\x00\x1c\x00Europe/PodgoricaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00" + + "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00w\x00\x00\x00\a\x00\x00\x00\r\x80\x00\x00\x00\xca\x025\xe0\xcc\xe7K\x10ͩ\x17\x90" + + "\u03a2C\x10ϒ4\x10Ђ%\x10ѡ\x8c\x10\xd2N@\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10" + + "\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10" + + "L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10" + + "Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐" + + "h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90" + + "v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x04\x02\x03\x02\x03\x02\x03\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x0e\x10\x00\x04\x00\x00\x1c" + + " \x01\b\x00\x00\x1c \x01\b\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\x04LMT\x00CET\x00CEST\x00\x00\x00\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00w\x00\x00\x00\a\x00\x00\x00\r\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff" + + "ͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xffѡ\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90" + + "\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00" + + "!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90" + + "\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00" + + "K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90" + + "\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00" + + "Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10" + + "\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00" + + "g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10" + + "\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00" + + "v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090" + + "\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x04\x02\x03\x02\x03\x02\x03\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\b\x00\x00\x1c \x01\b\x00\x00\x1c \x01\b\x00" + + "\x00\x0e\x10\x00\x04LMT\x00CET\x00CEST\x00\x00\x00\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M10.5.0/3\n" + + "PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPy\xcc\x01\x9du\a\x00\x00u\a\x00\x00\x0f\x00\x1c\x00Europe/BusingenUT\t\x00\x03nӧ^nӧ^ux" + + "\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00w\x00\x00\x00\x05\x00\x00\x00\r\x80\x00\x00" + + "\x00\xca\x17j\x00\xca\xe2q\x00\xcb\xf7L\x00\xcc\xc2S\x00\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90" + + "\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1" + + "\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70" + + "\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae" + + "\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e" + + "\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\b\x00\x00\x00\x00\x00" + + "\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\x00\x00\x00\x01\x01\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00x\x00\x00\x00\x06\x00\x00\x00\x11\xff\xff\xff\xff$\xf0\xea\x80\xff\xff\xff\xffq\xd4\x06\x86\xff\xff\xff\xff\xca\x17j\x00\xff\xff\xff\xff\xca\xe2q" + + "\x00\xff\xff\xff\xff\xcb\xf7L\x00\xff\xff\xff\xff\xcc\xc2S\x00\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00" + + "\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr" + + "\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00" + + "\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3" + + "\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00" + + "\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12" + + "\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00" + + "\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90" + + "\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00" + + "\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00" + + "\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00" + + "\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x03\x02\x03\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x00\x00\b\x00\x00\x00\x00\x00\x06\xfa\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x01\b\x00" + + "\x00\x0e\x10\x00\rLMT\x00BMT\x00CEST\x00CET\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M10.5.0/" + + "3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfcc!\x8eQ\n\x00\x00Q\n\x00\x00\x0e\x00\x1c\x00Europe/VaticanUT\t\x00\x03nӧ^nӧ^u" + + "x\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xa9\x00\x00\x00\a\x00\x00\x00\r\x80\x00" + + "\x00\x00\x9b8\xf8p\x9b\xd5\xcc\xe0\x9c\xc5\xcb\xf0\x9d\xb7\x00`\x9e\x89\xfep\x9f\xa0\x1c\xe0\xa0`\xa5\xf0\xa1~\xad`\xa2\\7p\xa3L\x1a`\xc8l5\xf0\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ" + + "4\x10\xd0n^\x90\xd1r\x16\x10\xd2L\xd2\xf0\xd3>1\x90\xd4I\xd2\x10\xd5\x1d\xf7p\xd6)\x97\xf0\xd6뀐\xd8\t\x96\x10\xf93\xb5\xf0\xf9\xd9\xc4\xe0\xfb\x1c\xd2p\xfb\xb9\xb4\xf0\xfc\xfc\xb4p\xfd\x99" + + "\x96\xf0\xfe\xe5\xd0\xf0\xff\x82\xb3p\x00Ų\xf0\x01b\x95p\x02\x9cZp\x03Bwp\x04\x85v\xf0\x05+\x93\xf0\x06n\x93p\a\vu\xf0\bE:\xf0\b\xebW\xf0\n.Wp\n\xcb9\xf0\f\x0e" + + "9p\f\xab\x1b\xf0\r\xe4\xe0\xf0\x0e\x8a\xfd\xf0\x0f\xcd\xfdp\x10t\x1ap\x11\xad\xdfp\x12S\xfcp\x13MD\x10\x143\xfa\x90\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19\xd3" + + "\xa0\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%" + + "\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rl" + + "e\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_" + + "\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6" + + "S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99" + + "\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x01\x02\x04\x03\x04\x03\x04\x03\x04\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x00\x00\v\xb4\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\x00\x00" + + "\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\xaa\x00\x00\x00\b\x00\x00\x00\x11\xff\xff\xff\xff" + + ">(\xe8L\xff\xff\xff\xffp\xbc\x81p\xff\xff\xff\xff\x9b8\xf8p\xff\xff\xff\xff\x9b\xd5\xcc\xe0\xff\xff\xff\xff\x9c\xc5\xcb\xf0\xff\xff\xff\xff\x9d\xb7\x00`\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0\x1c\xe0" + + "\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xad`\xff\xff\xff\xff\xa2\\7p\xff\xff\xff\xff\xa3L\x1a`\xff\xff\xff\xff\xc8l5\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff" + + "\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2L\xd2\xf0\xff\xff\xff\xff\xd3>1\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd5\x1d\xf7p" + + "\xff\xff\xff\xff\xd6)\x97\xf0\xff\xff\xff\xff\xd6뀐\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xf93\xb5\xf0\xff\xff\xff\xff\xf9\xd9\xc4\xe0\xff\xff\xff\xff\xfb\x1c\xd2p\xff\xff\xff\xff\xfb\xb9\xb4\xf0\xff\xff\xff\xff" + + "\xfc\xfc\xb4p\xff\xff\xff\xff\xfd\x99\x96\xf0\xff\xff\xff\xff\xfe\xe5\xd0\xf0\xff\xff\xff\xff\xff\x82\xb3p\x00\x00\x00\x00\x00Ų\xf0\x00\x00\x00\x00\x01b\x95p\x00\x00\x00\x00\x02\x9cZp\x00\x00\x00\x00\x03Bwp" + + "\x00\x00\x00\x00\x04\x85v\xf0\x00\x00\x00\x00\x05+\x93\xf0\x00\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\a\vu\xf0\x00\x00\x00\x00\bE:\xf0\x00\x00\x00\x00\b\xebW\xf0\x00\x00\x00\x00\n.Wp\x00\x00\x00\x00" + + "\n\xcb9\xf0\x00\x00\x00\x00\f\x0e9p\x00\x00\x00\x00\f\xab\x1b\xf0\x00\x00\x00\x00\r\xe4\xe0\xf0\x00\x00\x00\x00\x0e\x8a\xfd\xf0\x00\x00\x00\x00\x0f\xcd\xfdp\x00\x00\x00\x00\x10t\x1ap\x00\x00\x00\x00\x11\xad\xdfp" + + "\x00\x00\x00\x00\x12S\xfcp\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00" + + "\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10" + + "\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00" + + "Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10" + + "\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00" + + "QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10" + + "\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00" + + "_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90" + + "\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00" + + "m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10" + + "\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00" + + "{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x02\x03\x05\x04\x05\x04" + + "\x05\x04\x05\x03\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x00\x00\v\xb4\x00\x00\x00\x00\v\xb4\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x0e\x10\x00\r\x00\x00\x1c " + + "\x01\b\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00RMT\x00CEST\x00CET\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3" + + ".5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa5\xa2\x06\xaf@\x0e\x00\x00@\x0e\x00\x00\x0e\x00\x1c\x00Europe/BelfastU" + + "T\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00" + + "\x00\x00\xf2\x00\x00\x00\a\x00\x00\x00\x11\x80\x00\x00\x00\x9b&\xad\xa0\x9b\xd6\x05 \x9c\xcf0\xa0\x9d\xa4à\x9e\x9c\x9d\xa0\x9f\x97\x1a\xa0\xa0\x85\xba \xa1v\xfc\xa0\xa2e\x9c \xa3{Ƞ\xa4N\xb8\xa0\xa5" + + "?\xfb \xa6%` \xa7'\xc6 \xa8*, \xa8\xeb\xf8\xa0\xaa\x00Ӡ\xaa\xd5\x15 \xab\xe9\xf0 \xac\xc7l \xad\xc9\xd2 \xae\xa7N \xaf\xa0y\xa0\xb0\x870 \xb1\x92Р\xb2pL\xa0\xb3" + + "r\xb2\xa0\xb4P.\xa0\xb5IZ \xb60\x10\xa0\xb72v\xa0\xb8\x0f\xf2\xa0\xb9\x12X\xa0\xb9\xefԠ\xba\xe9\x00 \xbb\xd8\xf1 \xbc\xdbW \xbd\xb8\xd3 \xbe\xb1\xfe\xa0\xbf\x98\xb5 \xc0\x9b\x1b \xc1" + + "x\x97 \xc2z\xfd \xc3Xy \xc4Q\xa4\xa0\xc58[ \xc6:\xc1 \xc7X֠\xc7\xda\t\xa0\xca\x16&\x90ʗY\x90\xcb\xd1\x1e\x90\xccw;\x90ͱ\x00\x90\xce`X\x10ϐ\xe2\x90\xd0" + + "n^\x90\xd1r\x16\x10\xd1\xfb2\x10\xd2i\xfe \xd3c)\xa0\xd4I\xe0 \xd5\x1e!\xa0\xd5B\xfd\x90\xd5\xdf\xe0\x10\xd6N\xac \xd6\xfe\x03\xa0\xd8.\x8e \xd8\xf9\x95 \xda\x0ep \xda\xeb\xec \xdb" + + "\xe5\x17\xa0\xdc\xcb\xce \xdd\xc4\xf9\xa0\u07b4\xea\xa0߮\x16 \xe0\x94̠\xe1rH\xa0\xe2kt \xe3R*\xa0\xe4T\x90\xa0\xe52\f\xa0\xe6=\xad \xe7\x1b) \xe8\x14T\xa0\xe8\xfb\v \xe9" + + "\xfdq \xea\xda\xed \xeb\xddS \xec\xba\xcf \xed\xb3\xfa\xa0\ue6b1 \xef\x81g\xa0\xf0\x9f} \xf1aI\xa0\xf2\u007f_ \xf3Jf \xf4_A \xf5!\r\xa0\xf6?# \xf7\x00\xef\xa0\xf8" + + "\x1f\x05 \xf8\xe0Ѡ\xf9\xfe\xe7 \xfa\xc0\xb3\xa0\xfb\xe8\x03\xa0\xfc{\xab\xa0\xfdǻp\x03p\xc6 \x04)X \x05P\xa8 \x06\t: \a0\x8a \a\xe9\x1c \t\x10l \t\xc8\xfe \n" + + "\xf0N \v\xb2\x1a\xa0\f\xd00 \r\x91\xfc\xa0\x0e\xb0\x12 \x0fqޠ\x10\x99.\xa0\x11Q\xc0\xa0\x12y\x10\xa0\x131\xa2\xa0\x14X\xf2\xa0\x15#\xeb\x90\x168Ɛ\x17\x03͐\x18\x18\xa8\x90\x18" + + "㯐\x19\xf8\x8a\x90\x1aÑ\x90\x1b\xe1\xa7\x10\x1c\xac\xae\x10\x1d\xc1\x89\x10\x1e\x8c\x90\x10\x1f\xa1k\x10 lr\x10!\x81M\x10\"LT\x10#a/\x10$,6\x10%JK\x90&\f\x18\x10'" + + "*-\x90'\xf54\x90)\n\x0f\x90)\xd5\x16\x90*\xe9\xf1\x90+\xb4\xf8\x90,\xc9Ӑ-\x94ڐ.\xa9\xb5\x90/t\xbc\x900\x89\x97\x901]\xd9\x102r\xb4\x103=\xbb\x104R\x96\x105" + + "\x1d\x9d\x1062x\x106\xfd\u007f\x108\x1b\x94\x908\xdda\x109\xfbv\x90:\xbdC\x10;\xdbX\x90<\xa6_\x90=\xbb:\x90>\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90C" + + "d\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90Q" + + "W\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_" + + "\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m" + + "\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{" + + "λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x04\x06\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04\x00\x00\x0e\x10\x01\x04\x00\x00\x00" + + "\x00\x00\bLMT\x00BST\x00GMT\x00BDST\x00\x00\x01\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00" + + "\x00\a\x00\x00\x00\x00\x00\x00\x00\xf2\x00\x00\x00\a\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff" + + "\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?" + + "\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff" + + "\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r" + + "\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff" + + "\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x" + + "\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff" + + "\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n" + + "^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff" + + "\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5" + + "\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff" + + "\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfd" + + "q \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff" + + "\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\u007f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f" + + "\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfdǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00" + + "\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0" + + "N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\x00\x00\x00\x00\x10\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00" + + "\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x168Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18\xe3" + + "\xaf\x90\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00" + + "\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'*" + + "-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xc9Ӑ\x00\x00\x00\x00-\x94ڐ\x00\x00" + + "\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00\x00\x001]\xd9\x10\x00\x00\x00\x002r\xb4\x10\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d" + + "\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\u007f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00" + + "\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd" + + "\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00" + + "\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW" + + "\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00" + + "\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94" + + "\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00" + + "\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88" + + "=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00" + + "\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{\xce" + + "\xbb\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x06\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f" + + "\x00\x00\x0e\x10\x00\x04\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\bLMT\x00BST\x00GMT\x00BDST\x00\x00\x01\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01\nGMT0BST,M3" + + ".5.0/1,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe59\xab\xf0\xfd\b\x00\x00\xfd\b\x00\x00\x11\x00\x1c\x00Europe/Bratisla" + + "vaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\b\x00\x00" + + "\x00\x00\x00\x00\x00\x8f\x00\x00\x00\b\x00\x00\x00\x11\x80\x00\x00\x00\x9b\f\x17`\x9b\xd5\xda\xf0\x9cٮ\x90\x9d\xa4\xb5\x90\x9e\xb9\x90\x90\x9f\x84\x97\x90\xc8\tq\x90\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ" + + "4\x10Ђ%\x10\xd1r\x16\x10\xd2b\a\x10Ӏ\x1c\x90\xd4I\xd2\x10ԓ\xb4 \xd5\x02r \xd5L8\x10\xd6)\xb4\x10\xd7,\x1a\x10\xd8\t\x96\x10\xd9\x01p\x10\xd9\xe9x\x10\x11d'\x90\x12T" + + "\x18\x90\x13MD\x10\x143\xfa\x90\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 l" + + "r\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3" + + "\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7" + + "\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d" + + "\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11" + + "\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x05\x02\x03\x04\x03\x04\x03\x04\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" + + "\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" + + "\a\x06\a\x06\a\x06\a\x06\a\x00\x00\r\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x00\x00\x01\r\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT" + + "\x00CEST\x00CET\x00GMT\x00\x00\x00\x00\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\t\x00\x00" + + "\x00\x00\x00\x00\x00\x90\x00\x00\x00\t\x00\x00\x00\x15\xff\xff\xff\xff\x1eI\x92\xf8\xff\xff\xff\xffl\xcf\xea\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4" + + "\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff" + + "\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2b\a\x10\xff\xff\xff\xffӀ\x1c\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xffԓ\xb4 \xff\xff\xff\xff\xd5\x02r \xff\xff\xff\xff\xd5L" + + "8\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x01p\x10\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00" + + "\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xd3" + + "\xa0\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00" + + "\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%" + + "\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00" + + "\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rl" + + "e\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00" + + "\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_" + + "\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00" + + "\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6" + + "S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00" + + "\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99" + + "\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x03\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x06\x03\x04\x05\x04\x05\x04\x05\a\b\a\b\a\b\a\b" + + "\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b" + + "\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\x00\x00\r\x88\x00\x00\x00\x00\r\x88" + + "\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x00\x00\x01\x11\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00PMT\x00CEST\x00CET" + + "\x00GMT\x00\x00\x00\x00\x00\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00" + + "\x00\xf5F\x9cPp\xbc&\f(\b\x00\x00(\b\x00\x00\v\x00\x1c\x00Europe/KievUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00" + + "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00y\x00\x00\x00\r\x00\x00\x00\"\x80\x00\x00\x00\xaa\x19\xa7d\xb5\xa4\x19`\xca\xcd.\xd0" + + "\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10\xceͨp\x15'\xa7\xd0\x16\x18\xdc@\x17\b\xdbP\x17\xfa\x0f\xc0\x18\xea\x0e\xd0\x19\xdbC@\x1a̓\xd0\x1b\xbc\xa0\xf0\x1c\xac\x91\xf0\x1d\x9c\x82\xf0\x1e\x8cs\xf0" + + "\x1f|d\xf0 lU\xf0!\\F\xf0\"L7\xf0#<(\xf0$,\x19\xf0%\x1c\n\xf0&\v\xfb\xf0&\x8d \xe0(\xe5\x17\x80)\xd4\xec`*\xc4\xcfP+\xb4\xce`,\xa4\xb1P-\x94\xb0`" + + ".\x84\x93P/t\xbc\x900d\xad\x901]\xd9\x102r\xb4\x103=\xbb\x104R\x96\x105\x1d\x9d\x1062x\x106\xfd\u007f\x108\x1b\x94\x908\xdda\x109\xfbv\x90:\xbdC\x10;\xdbX\x90" + + "<\xa6_\x90=\xbb:\x90>\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10" + + "J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10" + + "X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90" + + "g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10" + + "u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x02\x03\x06\x04\x05\x04\x03\a\x03\a\x03" + + "\a\x03\a\b\t\b\t\b\t\b\t\b\t\b\t\n\x02\n\x02\n\x02\n\x02\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v" + + "\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\x00\x00\x1c\x9c\x00\x00\x00\x00\x1c\x9c\x00" + + "\x04\x00\x00\x1c \x00\b\x00\x00*0\x00\f\x00\x00\x0e\x10\x00\x10\x00\x00\x1c \x01\x14\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x00\f\x00\x008@\x01\x19\x00\x00*0\x01\x1d\x00\x00*0\x01" + + "\x1d\x00\x00\x1c \x00\bLMT\x00KMT\x00EET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00y\x00\x00\x00\r\x00\x00\x00\"\xff\xff\xff\xffV\xb6\xc7d\xff" + + "\xff\xff\xff\xaa\x19\xa7d\xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xff\xca\xcd.\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xff\xceͨp\x00\x00\x00\x00\x15" + + "'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00" + + "\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#" + + "<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00&\x8d \xe0\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00" + + "\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x00\x00\x00\x002" + + "r\xb4\x10\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\u007f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00" + + "\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@" + + "f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00" + + "\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N" + + "\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00" + + "\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\" + + "\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00" + + "\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j" + + "\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00" + + "\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x" + + "\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01" + + "\x02\x03\x06\x04\x05\x04\x03\a\x03\a\x03\a\x03\a\b\t\b\t\b\t\b\t\b\t\b\t\n\x02\n\x02\n\x02\n\x02\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f" + + "\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f" + + "\x00\x00\x1c\x9c\x00\x00\x00\x00\x1c\x9c\x00\x04\x00\x00\x1c \x00\b\x00\x00*0\x00\f\x00\x00\x0e\x10\x00\x10\x00\x00\x1c \x01\x14\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x00\f\x00\x008@\x01\x19" + + "\x00\x00*0\x01\x1d\x00\x00*0\x01\x1d\x00\x00\x1c \x00\bLMT\x00KMT\x00EET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00\x00\x00\x00\x00\x01\x01\x00\x00" + + "\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F" + + "\x9cP\xc5^+J\xd5\x05\x00\x00\xd5\x05\x00\x00\x12\x00\x1c\x00Europe/KaliningradUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04" + + "\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00P\x00\x00\x00\x0f\x00\x00\x00\"\x80\x00\x00\x00\x9b\f\x17`\x9b\xd5\xda\xf0" + + "\x9cٮ\x90\x9d\xa4\xb5\x90\x9e\xb9\x90\x90\x9f\x84\x97\x90\xc8\tq\x90\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10Ђ%\x10\xd1r\x16\x10\xd1|w\xe0ѕ\x84`Ҋ\xadP\xd3Y\xb6\xe0" + + "\x15'\xa7\xd0\x16\x18\xdc@\x17\b\xdbP\x17\xfa\x0f\xc0\x18\xea\x0e\xd0\x19\xdbC@\x1a̓\xd0\x1b\xbc\xa0\xf0\x1c\xac\x91\xf0\x1d\x9c\x82\xf0\x1e\x8cs\xf0\x1f|d\xf0 lU\xf0!\\F\xf0\"L7\xf0" + + "#<(\xf0$,\x19\xf0%\x1c\x19\x00&\f\n\x00'\x055\x80'\xf5&\x80(\xe5\x17\x80)\xd5\b\x80*\xc4\xf9\x80+\xb4\xea\x80,\xa4ۀ-\x94̀.\x84\xbd\x80/t\xae\x800d\x9f\x80" + + "1]\xcb\x002r\xa6\x003=\xad\x004R\x88\x005\x1d\x8f\x0062j\x006\xfdq\x008\x1b\x86\x808\xddS\x009\xfbh\x80:\xbd5\x00;\xdbJ\x80<\xa6Q\x80=\xbb,\x80>\x863\x80" + + "?\x9b\x0e\x80@f\x15\x80A\x84+\x00BE\xf7\x80Cd\r\x00D%ـEC\xef\x00F\x05\xbb\x80G#\xd1\x00G\xee\xd8\x00I\x03\xb3\x00Iκ\x00J\xe3\x95\x00K\xae\x9c\x00Ḻ\x80" + + "M\x8e~\x00TL+p\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x06\x05\x06\b\a\b\a\b\a\b\a\t\n\t\n\t\n\t\n\t\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f" + + "\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\r\f\x00\x00\x138\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00" + + "*0\x01\r\x00\x00\x1c \x00\x12\x00\x008@\x01\x16\x00\x00*0\x00\x1a\x00\x00*0\x00\x1a\x00\x008@\x01\x16\x00\x00*0\x01\r\x00\x00\x1c \x00\x12\x00\x00*0\x00\x1e\x00\x00\x1c \x00\x12LM" + + "T\x00CEST\x00CET\x00EEST\x00EET\x00MSD\x00MSK\x00+03\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00P\x00\x00\x00\x0f\x00\x00\x00\"\xff\xff\xff\xffo\xa2[H\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9c" + + "ٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff" + + "\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1|w\xe0\xff\xff\xff\xffѕ\x84`\xff\xff\xff\xffҊ\xadP\xff\xff\xff\xff\xd3Y\xb6\xe0\x00\x00\x00\x00\x15" + + "'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00" + + "\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#" + + "<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\f\n\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80\x00" + + "\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001" + + "]\xcb\x00\x00\x00\x00\x002r\xa6\x00\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x8f\x00\x00\x00\x00\x0062j\x00\x00\x00\x00\x006\xfdq\x00\x00\x00\x00\x008\x1b\x86\x80\x00" + + "\x00\x00\x008\xddS\x00\x00\x00\x00\x009\xfbh\x80\x00\x00\x00\x00:\xbd5\x00\x00\x00\x00\x00;\xdbJ\x80\x00\x00\x00\x00<\xa6Q\x80\x00\x00\x00\x00=\xbb,\x80\x00\x00\x00\x00>\x863\x80\x00\x00\x00\x00?" + + "\x9b\x0e\x80\x00\x00\x00\x00@f\x15\x80\x00\x00\x00\x00A\x84+\x00\x00\x00\x00\x00BE\xf7\x80\x00\x00\x00\x00Cd\r\x00\x00\x00\x00\x00D%ـ\x00\x00\x00\x00EC\xef\x00\x00\x00\x00\x00F\x05\xbb\x80\x00" + + "\x00\x00\x00G#\xd1\x00\x00\x00\x00\x00G\xee\xd8\x00\x00\x00\x00\x00I\x03\xb3\x00\x00\x00\x00\x00Iκ\x00\x00\x00\x00\x00J\xe3\x95\x00\x00\x00\x00\x00K\xae\x9c\x00\x00\x00\x00\x00Ḻ\x80\x00\x00\x00\x00M" + + "\x8e~\x00\x00\x00\x00\x00TL+p\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x06\x05\x06\b\a\b\a\b\a\b\a\t\n\t\n\t\n\t\n\t\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v" + + "\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\r\f\x00\x00\x138\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00" + + "\t\x00\x00*0\x01\r\x00\x00\x1c \x00\x12\x00\x008@\x01\x16\x00\x00*0\x00\x1a\x00\x00*0\x00\x1a\x00\x008@\x01\x16\x00\x00*0\x01\r\x00\x00\x1c \x00\x12\x00\x00*0\x00\x1e\x00\x00\x1c \x00" + + "\x12LMT\x00CEST\x00CET\x00EEST\x00EET\x00MSD\x00MSK\x00+03\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\nEET-2\nPK\x03" + + "\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb6\x92}\xbe:\b\x00\x00:\b\x00\x00\x11\x00\x1c\x00Europe/ZaporozhyeUT\t\x00\x03nӧ^nӧ^ux\v" + + "\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00z\x00\x00\x00\r\x00\x00\x00$\x80\x00\x00\x00" + + "\xaa\x19\xa30\xb5\xa4\x19`ʪ\xe7\xd0\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ν\xd6p\x15'\xa7\xd0\x16\x18\xdc@\x17\b\xdbP\x17\xfa\x0f\xc0\x18\xea\x0e\xd0\x19\xdbC@\x1a̓\xd0\x1b\xbc\xa0\xf0" + + "\x1c\xac\x91\xf0\x1d\x9c\x82\xf0\x1e\x8cs\xf0\x1f|d\xf0 lU\xf0!\\F\xf0\"L7\xf0#<(\xf0$,\x19\xf0%\x1c\n\xf0&\v\xfb\xf0'\x05'p'\xf5\x18p(\xe4\xedP)\xd4\xec`" + + "*\xc4\xcfP+\xb4\xce`,\xa4\xb1P-\x94\xb0`.\x84\x93P/t\xbc\x900d\xad\x901]\xd9\x102r\xb4\x103=\xbb\x104R\x96\x105\x1d\x9d\x1062x\x106\xfd\u007f\x108\x1b\x94\x90" + + "8\xdda\x109\xfbv\x90:\xbdC\x10;\xdbX\x90<\xa6_\x90=\xbb:\x90>\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐ" + + "G#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90" + + "U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10" + + "c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10" + + "qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90" + + "\u007f\x8e\u007f\x90\x01\x02\x03\x06\x04\x05\x04\x03\a\x03\a\x03\a\x03\a\b\t\b\t\b\t\b\t\b\t\b\t\b\n\x02\n\x02\n\x02\n\x02\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f" + + "\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f" + + "\v\f\v\f\v\f\x00\x00 \xf8\x00\x00\x00\x00 \xd0\x00\x04\x00\x00\x1c \x00\n\x00\x00*0\x00\x0e\x00\x00\x0e\x10\x00\x12\x00\x00\x1c \x01\x16\x00\x00\x1c \x01\x16\x00\x008@\x01\x1b\x00\x00*0\x00\x0e" + + "\x00\x008@\x01\x1b\x00\x00*0\x01\x1f\x00\x00*0\x01\x1f\x00\x00\x1c \x00\nLMT\x00+0220\x00EET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00" + + "\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\r\x00\x00\x00\x00\x00\x00" + + "\x00z\x00\x00\x00\r\x00\x00\x00$\xff\xff\xff\xffV\xb6\xc3\b\xff\xff\xff\xff\xaa\x19\xa30\xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xffʪ\xe7\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff" + + "\xff\xff\u03a2C\x10\xff\xff\xff\xffν\xd6p\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdb" + + "C@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00" + + "\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5" + + "\x18p\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00" + + "\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x00\x00\x00\x002r\xb4\x10\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062" + + "x\x10\x00\x00\x00\x006\xfd\u007f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00" + + "\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%" + + "\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00" + + "\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rl" + + "e\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00" + + "\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_" + + "\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00" + + "\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6" + + "S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00" + + "\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99" + + "\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x02\x03\x06\x04\x05\x04\x03\a\x03\a\x03\a\x03\a\b\t\b\t\b\t\b\t\b\t\b\t\b\n\x02\n\x02\n\x02" + + "\n\x02\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f" + + "\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\x00\x00 \xf8\x00\x00\x00\x00 \xd0\x00\x04\x00\x00\x1c \x00\n\x00\x00*0\x00\x0e\x00\x00\x0e\x10\x00\x12\x00\x00" + + "\x1c \x01\x16\x00\x00\x1c \x01\x16\x00\x008@\x01\x1b\x00\x00*0\x00\x0e\x00\x008@\x01\x1b\x00\x00*0\x01\x1f\x00\x00*0\x01\x1f\x00\x00\x1c \x00\nLMT\x00+0220\x00EET\x00" + + "MSK\x00CET\x00CEST\x00MSD\x00EEST\x00\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\nEET-2EEST,M" + + "3.5.0/3,M10.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x8btѪ\x98\b\x00\x00\x98\b\x00\x00\r\x00\x1c\x00Europe/Vienn" + + "aUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00" + + "\x00\x00\x00\x00\x8b\x00\x00\x00\a\x00\x00\x00\r\x80\x00\x00\x00\x9b\f\x17`\x9b\xd5\xda\xf0\x9cٮ\x90\x9d\xa4\xb5\x90\x9e\xb9\x90\x90\x9f\x84\x97\x90\xa2p\x1a\x10\xa3D[\x90\xc8\tq\x90\xcc\xe7K\x10ͩ\x17" + + "\x90\u03a2C\x10ϒ4\x10Ђ%\x10\xd1r\x16\x10\xd1\u007fE\x10\xd3c\x1b\x90\xd4K#\x90\xd59\xc3\x10\xd6)\xb4\x10\xd7,\x1a\x10\xd8\t\x96\x10\x13M'\xf0\x143\xd0`\x15#\xeb\x90\x16\x13\xdc" + + "\x90\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#" + + "\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1" + + "\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11" + + "\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT" + + "\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4" + + "\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x01\x02\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\x0fQ\x00\x00\x00\x00\x1c \x01\x04" + + "\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x01\x01TZi" + + "f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x8b\x00\x00\x00\a\x00\x00\x00\r\xff\xff\xff\xffo\xa2_/\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff" + + "\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xa2p\x1a\x10\xff\xff\xff\xff\xa3D[\x90\xff\xff\xff\xff\xc8\tq" + + "\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\u007fE\x10\xff\xff\xff" + + "\xff\xd3c\x1b\x90\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd59\xc3\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\x00\x00\x00\x00\x13M'\xf0\x00\x00\x00\x00\x143\xd0" + + "`\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00" + + "\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT" + + "\x10\x00\x00\x00\x00#\x86A" + + "\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00" + + "\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿" + + "\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00" + + "\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4" + + "\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00" + + "\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr" + + "\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00" + + "\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2" + + "\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00" + + "\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x01\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\x0fQ\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x0e\x10" + + "\x00\t\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M" + + "10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x9d\x8f\xfd_@\t\x00\x00@\t\x00\x00\x0f\x00\x1c\x00Europe/BudapestUT\t\x00\x03n" + + "ӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x97\x00\x00" + + "\x00\a\x00\x00\x00\r\x80\x00\x00\x00\x9b\f\x17`\x9b\xd5\xda\xf0\x9cٮ\x90\x9d\xa4\xb5\x90\x9e\xa7)\xa0\x9f\x84\x97\x90\xa0\x9a\xd2 \xa1\xc0\u0090\xc9\xf3\xc3p\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ" + + "4\x10Ђ%\x10љx\xe0Ҋ\xbb`\xd3P\xa6\x90\xd4I\xd2\x10\xd59\xc3\x10\xd6)\xb4\x10\xd7\x19\xa5\x10\xd8\t\x96\x10\xd9\x02\xc1\x90\xd9\xe9x\x10\xda\xed/\x90\xdb\xe6[\x10⢨\xf0\xe3Q" + + "\xf2`\xe4\x83\xdcp\xe53%\xe0\xe6t\xe1\xf0\xe7\x11\xb6`\xe8T\xd2\x00\xe8\xf1\u0090\x13M6\x00\x143\xfa\x90\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1a\xc3" + + "\x91\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC" + + "\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7" + + "l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}" + + "\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh" + + "\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae" + + "\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x03\x04\x01\x02\x01\x02\x01\x04\x03\x04\x03\x04\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x01\x02\x01\x02\x01\x02\x01\x02\x01\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x00\x00\x11\xe4\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00" + + "\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04LMT\x00CEST\x00CET\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x97\x00\x00\x00\a\x00\x00\x00\r\xff\xff\xff\xffj\xee\xb3\x1c\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff" + + "\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xa7)\xa0\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xa0\x9a\xd2 \xff\xff\xff\xff\xa1\xc0\u0090\xff\xff\xff\xff\xc9\xf3\xc3p\xff\xff\xff\xff\xcc\xe7" + + "K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xffљx\xe0\xff\xff\xff\xffҊ\xbb`\xff\xff\xff\xff\xd3P\xa6\x90\xff\xff" + + "\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd59\xc3\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7\x19\xa5\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\xff\xff\xff\xff\xda\xed" + + "/\x90\xff\xff\xff\xff\xdb\xe6[\x10\xff\xff\xff\xff⢨\xf0\xff\xff\xff\xff\xe3Q\xf2`\xff\xff\xff\xff\xe4\x83\xdcp\xff\xff\xff\xff\xe53%\xe0\xff\xff\xff\xff\xe6t\xe1\xf0\xff\xff\xff\xff\xe7\x11\xb6`\xff\xff" + + "\xff\xff\xe8T\xd2\x00\xff\xff\xff\xff\xe8\xf1\u0090\x00\x00\x00\x00\x13M6\x00\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3" + + "\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00" + + "\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF" + + "\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00" + + "\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c" + + "\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00" + + "\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f" + + "\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00" + + "\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6" + + "q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00" + + "\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0" + + "\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x02\x01\x02\x03\x04\x01\x02\x01\x02\x01\x04\x03\x04\x03\x04\x01\x02\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x01\x02\x01\x02\x01\x02\x01\x02\x01\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x00\x00\x11\xe4\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04LMT\x00C" + + "EST\x00CET\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00" + + "\xf5F\x9cP\xec\xe5\x98\xc7r\b\x00\x00r\b\x00\x00\x0e\x00\x1c\x00Europe/VilniusUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00" + + "\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00x\x00\x00\x00\x12\x00\x00\x00&\x80\x00\x00\x00\x9cO\x1fP\xa1\x85J\x98\xa2\xf1" + + "0\xf0\xa3fx`Ȭ\xcfp\xcaY*\xd0\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10\xd00=\xe0\x15'\xa7\xd0\x16\x18\xdc@\x17\b\xdbP\x17\xfa\x0f\xc0\x18\xea\x0e\xd0\x19\xdbC@\x1a\xcc" + + "\x93\xd0\x1b\xbc\xa0\xf0\x1c\xac\x91\xf0\x1d\x9c\x82\xf0\x1e\x8cs\xf0\x1f|d\xf0 lU\xf0!\\F\xf0\"L7\xf0#<(\xf0$,\x19\xf0%\x1c\x19\x00&\f\n\x00'\x055\x80'\xf5&\x80(\xe5" + + "\x17\x80)\xd5\b\x80*\xc4\xf9\x80+\xb4\xea\x80,\xa4ۀ-\x94̀.\x84\xbd\x80/t\xae\x800d\x9f\x801]\xcb\x002r\xa6\x003=\xad\x004R\x88\x005\x1d\x9d\x1062x\x106\xfd" + + "\u007f\x108\x1b\x94\x90>\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3" + + "\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7" + + "\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d" + + "\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11" + + "\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x02\x03\x04\x03\x05\b\x06\a\x06\a\x05\t\x05" + + "\t\x05\t\x05\t\n\v\n\v\n\v\n\v\n\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\x0e\x0f\x0e\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10" + + "\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x00\x00\x17\xbc\x00\x00\x00\x00\x13\xb0\x00\x04\x00\x00" + + "\x16h\x00\b\x00\x00\x0e\x10\x00\f\x00\x00\x1c \x00\x10\x00\x00*0\x00\x14\x00\x00\x0e\x10\x00\f\x00\x00\x1c \x01\x18\x00\x00\x1c \x01\x18\x00\x008@\x01\x1d\x00\x00*0\x00\x14\x00\x008@\x01\x1d\x00\x00" + + "*0\x01!\x00\x00\x1c \x00\x10\x00\x00\x1c \x01\x18\x00\x00\x0e\x10\x00\f\x00\x00\x1c \x00\x10\x00\x00*0\x01!LMT\x00WMT\x00KMT\x00CET\x00EET\x00MSK\x00CE" + + "ST\x00MSD\x00EEST\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00x\x00\x00\x00\x12\x00\x00\x00&\xff\xff\xff\xffV\xb6\xccD\xff\xff\xff\xff\x9cO\x1fP\xff\xff\xff\xff\xa1\x85J\x98\xff\xff\xff\xff" + + "\xa2\xf10\xf0\xff\xff\xff\xff\xa3fx`\xff\xff\xff\xffȬ\xcfp\xff\xff\xff\xff\xcaY*\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10" + + "\xff\xff\xff\xff\xd00=\xe0\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00" + + "\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0" + + "\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\f\n\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00" + + "(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80" + + "\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xa6\x00\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x00" + + "6\xfd\u007f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10" + + "\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00" + + "J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90" + + "\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00" + + "X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10" + + "\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00" + + "g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90" + + "\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00" + + "u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90" + + "\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x02\x03\x04\x03\x05\b\x06\a\x06\a\x05\t\x05\t\x05\t\x05\t\n\v\n\v\n\v\n\v\n" + + "\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\f\r\x0e\x0f\x0e\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10" + + "\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x11\x10\x00\x00\x17\xbc\x00\x00\x00\x00\x13\xb0\x00\x04\x00\x00\x16h\x00\b\x00\x00\x0e\x10\x00\f\x00\x00\x1c " + + "\x00\x10\x00\x00*0\x00\x14\x00\x00\x0e\x10\x00\f\x00\x00\x1c \x01\x18\x00\x00\x1c \x01\x18\x00\x008@\x01\x1d\x00\x00*0\x00\x14\x00\x008@\x01\x1d\x00\x00*0\x01!\x00\x00\x1c \x00\x10\x00\x00\x1c " + + "\x01\x18\x00\x00\x0e\x10\x00\f\x00\x00\x1c \x00\x10\x00\x00*0\x01!LMT\x00WMT\x00KMT\x00CET\x00EET\x00MSK\x00CEST\x00MSD\x00EEST\x00\x00\x00" + + "\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\nEET-2EEST,M3.5.0/3,M10.5." + + "0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x97\xf3U}\x80\v\x00\x00\x80\v\x00\x00\r\x00\x1c\x00Europe/MonacoUT\t\x00\x03nӧ^nӧ^" + + "ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\xb9\x00\x00\x00\v\x00\x00\x00\x1f\x80" + + "\x00\x00\x00\x91`PO\x9bGx\xf0\x9b\xd7,p\x9c\xbc\x91p\x9d\xc0H\xf0\x9e\x89\xfep\x9f\xa0*\xf0\xa0`\xa5\xf0\xa1\x80\f\xf0\xa2.\x12\xf0\xa3zL\xf0\xa45\x81\xf0\xa5^#p\xa6%5\xf0\xa7" + + "'\x9b\xf0\xa8X&p\xa9\a}\xf0\xa9\xee4p\xaa\xe7_\xf0\xab\xd7P\xf0\xac\xc7A\xf0\xadɧ\xf0\xae\xa7#\xf0\xaf\xa0Op\xb0\x87\x05\xf0\xb1\x89k\xf0\xb2p\"p\xb3r\x88p\xb4P\x04p\xb5" + + "I/\xf0\xb6/\xe6p\xb72Lp\xb8\x0f\xc8p\xb8\xff\xb9p\xb9\xef\xaap\xba\xd6`\xf0\xbb\xd8\xc6\xf0\xbcȷ\U0003de28\xf0\xbe\x9f_p\xbf\x98\x8a\xf0\xc0\x9a\xf0\xf0\xc1xl\xf0\xc2h]\xf0\xc3" + + "XN\xf0\xc4?\x05p\xc580\xf0\xc6:\x96\xf0\xc7X\xacp\xc7\xda\t\xa0\xca\x17[\xf0\xca\xe2T\xe0˭i\xf0\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10Љ\xf1\xf0\xd1r\x16\x10\xd2" + + "N@\x90\v\xbb9\x00\f\xab\x1b\xf0\r\xa4c\x90\x0e\x8b\x1a\x10\x0f\x84E\x90\x10t6\x90\x11d'\x90\x12T\x18\x90\x13MD\x10\x143\xfa\x90\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18" + + "㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90C" + + "d\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90Q" + + "W\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_" + + "\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m" + + "\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{" + + "λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x06\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\b\a\b\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n" + + "\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n" + + "\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\x00\x00\x06\xec\x00\x00\x00\x00\x021\x00\x04\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\r\x00\x00\x0e\x10\x01\b\x00\x00\x1c \x01\x11" + + "\x00\x00\x00\x00\x00\r\x00\x00\x1c \x01\x16\x00\x00\x0e\x10\x00\x1b\x00\x00\x1c \x01\x16\x00\x00\x0e\x10\x00\x1bLMT\x00PMT\x00WEST\x00WET\x00WEMT\x00CEST\x00CET" + + "\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\xb9\x00" + + "\x00\x00\v\x00\x00\x00\x1f\xff\xff\xff\xffk\xc8E\x94\xff\xff\xff\xff\x91`PO\xff\xff\xff\xff\x9bGx\xf0\xff\xff\xff\xff\x9b\xd7,p\xff\xff\xff\xff\x9c\xbc\x91p\xff\xff\xff\xff\x9d\xc0H\xf0\xff\xff\xff\xff\x9e" + + "\x89\xfep\xff\xff\xff\xff\x9f\xa0*\xf0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1\x80\f\xf0\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45\x81\xf0\xff\xff\xff\xff\xa5^#p\xff" + + "\xff\xff\xff\xa6%5\xf0\xff\xff\xff\xff\xa7'\x9b\xf0\xff\xff\xff\xff\xa8X&p\xff\xff\xff\xff\xa9\a}\xf0\xff\xff\xff\xff\xa9\xee4p\xff\xff\xff\xff\xaa\xe7_\xf0\xff\xff\xff\xff\xab\xd7P\xf0\xff\xff\xff\xff\xac" + + "\xc7A\xf0\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2p\"p\xff\xff\xff\xff\xb3r\x88p\xff" + + "\xff\xff\xff\xb4P\x04p\xff\xff\xff\xff\xb5I/\xf0\xff\xff\xff\xff\xb6/\xe6p\xff\xff\xff\xff\xb72Lp\xff\xff\xff\xff\xb8\x0f\xc8p\xff\xff\xff\xff\xb8\xff\xb9p\xff\xff\xff\xff\xb9\xef\xaap\xff\xff\xff\xff\xba" + + "\xd6`\xf0\xff\xff\xff\xff\xbb\xd8\xc6\xf0\xff\xff\xff\xff\xbcȷ\xf0\xff\xff\xff\xff\xbd\xb8\xa8\xf0\xff\xff\xff\xff\xbe\x9f_p\xff\xff\xff\xff\xbf\x98\x8a\xf0\xff\xff\xff\xff\xc0\x9a\xf0\xf0\xff\xff\xff\xff\xc1xl\xf0\xff" + + "\xff\xff\xff\xc2h]\xf0\xff\xff\xff\xff\xc3XN\xf0\xff\xff\xff\xff\xc4?\x05p\xff\xff\xff\xff\xc580\xf0\xff\xff\xff\xff\xc6:\x96\xf0\xff\xff\xff\xff\xc7X\xacp\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca" + + "\x17[\xf0\xff\xff\xff\xff\xca\xe2T\xe0\xff\xff\xff\xff˭i\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЉ\xf1\xf0\xff" + + "\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\v\xbb9\x00\x00\x00\x00\x00\f\xab\x1b\xf0\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10" + + "t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00" + + "\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e" + + "\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00" + + "\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I" + + "\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00" + + "\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V" + + "\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00" + + "\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e" + + "=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00" + + "\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s" + + "1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00" + + "\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x06\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\b\a\b\t\n\t\n\t\n\t\n\t\n" + + "\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n" + + "\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\x00\x00\x06\xec\x00\x00\x00\x00" + + "\x021\x00\x04\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\r\x00\x00\x0e\x10\x01\b\x00\x00\x1c \x01\x11\x00\x00\x00\x00\x00\r\x00\x00\x1c \x01\x16\x00\x00\x0e\x10\x00\x1b\x00\x00\x1c \x01\x16\x00\x00\x0e\x10\x00\x1bLM" + + "T\x00PMT\x00WEST\x00WET\x00WEMT\x00CEST\x00CET\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\nCET-1CES" + + "T,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa7\x99\x04[\xb4\b\x00\x00\xb4\b\x00\x00\v\x00\x1c\x00Europe/Oslo" + + "UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00" + + "\x00\x00\x00\x8d\x00\x00\x00\a\x00\x00\x00\r\x80\x00\x00\x00\x9b'\xe3\x00\x9b\xd4{`ȷM`\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10Ђ%\x10\xd1r\x16\x10\xd2b\a\x10\xeb\xaf \x90" + + "\xec\xa8L\x10\xed\x98=\x10\xee\x88.\x10\xefx\x1f\x10\xf0h\x10\x10\xf1X\x01\x10\xf2G\xf2\x10\xf37\xe3\x10\xf4'\xd4\x10\xf5\x17\xc5\x10\xf6\x10\xf0\x90\xf7/\x06\x10\xf7\xf0Ґ\x13MD\x10\x143\xfa\x90" + + "\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10" + + "#\x86A\x90" + + "?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90" + + "M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90" + + "[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90" + + "i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10" + + "x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\n" + + "\x14\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\x00\x00\x00\x01\x01\x01\x01\x00" + + "\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x8d\x00\x00\x00\a\x00\x00\x00\r\xff\xff\xff\xffr\xee$l\xff\xff" + + "\xff\xff\x9b'\xe3\x00\xff\xff\xff\xff\x9b\xd4{`\xff\xff\xff\xffȷM`\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ" + + "%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2b\a\x10\xff\xff\xff\xff\xeb\xaf \x90\xff\xff\xff\xff\xec\xa8L\x10\xff\xff\xff\xff\xed\x98=\x10\xff\xff\xff\xff\xee\x88.\x10\xff\xff\xff\xff\xefx\x1f\x10\xff\xff" + + "\xff\xff\xf0h\x10\x10\xff\xff\xff\xff\xf1X\x01\x10\xff\xff\xff\xff\xf2G\xf2\x10\xff\xff\xff\xff\xf37\xe3\x10\xff\xff\xff\xff\xf4'\xd4\x10\xff\xff\xff\xff\xf5\x17\xc5\x10\xff\xff\xff\xff\xf6\x10\xf0\x90\xff\xff\xff\xff\xf7/" + + "\x06\x10\xff\xff\xff\xff\xf7\xf0Ґ\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00" + + "\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|" + + "\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00" + + "\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce" + + "\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00" + + "\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15" + + "F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00" + + "\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b" + + "\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00" + + "\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE" + + "\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00" + + "\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00" + + "\x00\n\x14\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\x00\x00\x00\x01\x01\x01" + + "\x01\x00\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPokI-\x8d\x04\x00\x00\x8d\x04" + + "\x00\x00\x10\x00\x1c\x00Europe/AstrakhanUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x00\t\x00\x00\x00\x10\xaa\x18Et\xb5\xa4\vP\x15'\x99\xc0\x16\x18\xce0\x17\b\xcd@\x17\xfa\x01\xb0\x18\xea" + + "\x00\xc0\x19\xdb50\x1a̅\xc0\x1b\xbc\x92\xe0\x1c\xac\x83\xe0\x1d\x9ct\xe0\x1e\x8ce\xe0\x1f|V\xe0 lG\xe0!\\8\xe0\"L)\xe0#<\x1a\xe0$,\v\xe0%\x1c\n\xf0&\v\xfb\xf0'\x05" + + "'p'\xf5\x18p)\xd4\xec`*\xc4\xebp+\xb4\xdcp,\xa4\xcdp-\x94\xbep.\x84\xafp/t\xa0p0d\x91p1]\xbc\xf02r\x97\xf03=\x9e\xf04Ry\xf05\x1d\x80\xf062" + + "[\xf06\xfdb\xf08\x1bxp8\xddD\xf09\xfbZp:\xbd&\xf0;\xdb\x86%p?\x9b\x00p@f\apA\x84\x1c\xf0BE\xe9pCc\xfe\xf0D%" + + "\xcbpEC\xe0\xf0F\x05\xadpG#\xc2\xf0G\xee\xc9\xf0I\x03\xa4\xf0IΫ\xf0J\xe3\x86\xf0K\xae\x8d\xf0ḶpM\x8eo\xf0TL\x1d`V\xf7\x14p\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x06\a\x04\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x04\a\x04\x04\x00" + + "\x00-\f\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x00\f\x00\x00FP\x01\b\x00\x008@\x01\f\x00\x00*0\x00\x04\x00\x008@\x00\fLMT\x00+03" + + "\x00+05\x00+04\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x00\t\x00\x00" + + "\x00\x10\xff\xff\xff\xff\xaa\x18Et\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00" + + "\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 l" + + "G\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00" + + "\x00\x00'\xf5\x18p\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t" + + "\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00" + + "\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00" + + "\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae" + + "\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x00\x00\x00\x00V\xf7\x14p\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x06\a\x06\a\x04\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x04\a\x04\x04\x00\x00-\f\x00\x00\x00\x00*0\x00\x04\x00" + + "\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x00\f\x00\x00FP\x01\b\x00\x008@\x01\f\x00\x00*0\x00\x04\x00\x008@\x00\fLMT\x00+03\x00+05\x00+04\x00\x00\x00\x00" + + "\x00\x01\x01\x01\x01\x01\n<+04>-4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPSSc.\xad\x05\x00\x00\xad\x05\x00\x00\x11\x00\x1c\x00Europe/Simferop" + + "olUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00" + + "\x00\x00\x00\x00\x00K\x00\x00\x00\x0f\x00\x00\x00\"\x80\x00\x00\x00\xaa\x19\xa4 \xb5\xa4\x19`\xcb\x04\x8d\xd0\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10ϟ8\xe0\x15'\xa7\xd0\x16\x18\xdc@\x17\b" + + "\xdbP\x17\xfa\x0f\xc0\x18\xea\x0e\xd0\x19\xdbC@\x1a̓\xd0\x1b\xbc\xa0\xf0\x1c\xac\x91\xf0\x1d\x9c\x82\xf0\x1e\x8cs\xf0\x1f|d\xf0 lU\xf0!\\F\xf0\"L7\xf0#<(\xf0$,\x19\xf0%\x1c" + + "\n\xf0&\x8d.\xf0)\xd4\xec`*\xc4\xcfP+\xb4\xce`,\xa4\xb1P-\x94\xb0`-\xc2\xc6\xd0.\x84\x85@/t\x84P0dg@1]\xa0\xd02r\xa6\x003=\xbb\x104R\x96\x105\x1d" + + "\x9d\x1062x\x106\xfd\u007f\x108\x1b\x94\x908\xdda\x109\xfbv\x90:\xbdC\x10;\xdbX\x90<\xa6_\x90=\xbb:\x90>\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd" + + "\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW" + + "\x8a\x90Rle\x90S7^\x80TL\x1d`\x01\x02\x03\x06\x04\x05\x04\x05\x03\a\x03\a\x03\a\x03\a\b\t\b\t\b\t\b\t\b\t\b\x02\n\x02\n\x02\n\a\x03\a\x03\t\b\v\f\v\f\v\f\v" + + "\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\r\b\x00\x00\x1f\xf8\x00\x00\x00\x00\x1f\xe0\x00\x04\x00\x00\x1c \x00\b\x00\x00*0\x00\f\x00\x00\x0e\x10\x00\x10\x00" + + "\x00\x1c \x01\x14\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x00\f\x00\x008@\x01\x19\x00\x00*0\x01\x1d\x00\x00*0\x01\x1d\x00\x00\x1c \x00\b\x00\x008@\x00\f\x00\x00*0\x00\fL" + + "MT\x00SMT\x00EET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x00\x01\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" + + "\x01\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00K\x00\x00\x00\x0f\x00\x00\x00\"\xff\xff\xff\xffV\xb6\xc4\b\xff\xff\xff\xff\xaa" + + "\x19\xa4 \xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xff\xcb\x04\x8d\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffϟ8\xe0\x00" + + "\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b" + + "\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00" + + "\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\x8d.\xf0\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00," + + "\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00-\xc2\xc6\xd0\x00\x00\x00\x00.\x84\x85@\x00\x00\x00\x00/t\x84P\x00\x00\x00\x000dg@\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r\xa6\x00\x00" + + "\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\u007f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009" + + "\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00" + + "\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G" + + "\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00" + + "\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7^\x80\x00\x00\x00\x00TL\x1d`\x01\x02\x03\x06\x04\x05\x04\x05\x03\a\x03\a\x03" + + "\a\x03\a\b\t\b\t\b\t\b\t\b\t\b\x02\n\x02\n\x02\n\a\x03\a\x03\t\b\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f" + + "\r\b\x00\x00\x1f\xf8\x00\x00\x00\x00\x1f\xe0\x00\x04\x00\x00\x1c \x00\b\x00\x00*0\x00\f\x00\x00\x0e\x10\x00\x10\x00\x00\x1c \x01\x14\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x00\f\x00\x008@" + + "\x01\x19\x00\x00*0\x01\x1d\x00\x00*0\x01\x1d\x00\x00\x1c \x00\b\x00\x008@\x00\f\x00\x00*0\x00\fLMT\x00SMT\x00EET\x00MSK\x00CET\x00CEST\x00MSD" + + "\x00EEST\x00\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x00\x01\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\nMSK-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPi\xd8V" + + "\xbf\x8d\x04\x00\x00\x8d\x04\x00\x00\x10\x00\x1c\x00Europe/VolgogradUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZi" + + "f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x00\t\x00\x00\x00\x10\xa1\xf5Fܵ\xa4\vP\x15'\x99\xc0\x16\x18\xce0\x17\b\xcd" + + "@\x17\xfa\x01\xb0\x18\xea\x00\xc0\x19\xdb50\x1a̅\xc0\x1b\xbc\x92\xe0\x1c\xac\x83\xe0\x1d\x9ct\xe0\x1e\x8ce\xe0\x1f|V\xe0 lG\xe0!\\8\xe0\"L)\xe0#<(\xf0$,\x19\xf0%\x1c\n" + + "\xf0&\v\xfb\xf0'\x05'p'\xf5\x18p)\xd4\xec`*\xc4\xebp+\xb4\xdcp,\xa4\xcdp-\x94\xbep.\x84\xafp/t\xa0p0d\x91p1]\xbc\xf02r\x97\xf03=\x9e\xf04Ry" + + "\xf05\x1d\x80\xf062[\xf06\xfdb\xf08\x1bxp8\xddD\xf09\xfbZp:\xbd&\xf0;\xdb\x86%p?\x9b\x00p@f\apA\x84\x1c\xf0BE\xe9" + + "pCc\xfe\xf0D%\xcbpEC\xe0\xf0F\x05\xadpG#\xc2\xf0G\xee\xc9\xf0I\x03\xa4\xf0IΫ\xf0J\xe3\x86\xf0K\xae\x8d\xf0ḶpM\x8eo\xf0TL\x1d`[\xd4\xed\xf0\u007f\xff\xff" + + "\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x04\x05\x04\x05\x04\x06\a\x06\a\x06\a\x04\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" + + "\x06\a\x04\a\x04\x04\x00\x00)\xa4\x00\x00\x00\x00*0\x00\x04\x00\x008@\x00\b\x00\x00FP\x01\f\x00\x008@\x00\b\x00\x00FP\x01\f\x00\x008@\x01\b\x00\x00*0\x00\x04\x00\x008@\x00\b" + + "LMT\x00+03\x00+04\x00+05\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00" + + "A\x00\x00\x00\t\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xf5F\xdc\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00" + + "\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V" + + "\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00" + + "\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xaf" + + "p\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00" + + "\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00" + + "\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86" + + "\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x00\x00\x00\x00[\xd4\xed\xf0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05" + + "\x04\x05\x04\x05\x04\x06\a\x06\a\x06\a\x04\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x04\a\x04\x04\x00\x00)\xa4\x00\x00" + + "\x00\x00*0\x00\x04\x00\x008@\x00\b\x00\x00FP\x01\f\x00\x008@\x00\b\x00\x00FP\x01\f\x00\x008@\x01\b\x00\x00*0\x00\x04\x00\x008@\x00\bLMT\x00+03\x00+04\x00" + + "+05\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\n<+04>-4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa5\xa2\x06\xaf@\x0e\x00\x00@\x0e\x00\x00\x12\x00\x1c\x00Europe/I" + + "sle_of_ManUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xf2\x00\x00\x00\a\x00\x00\x00\x11\x80\x00\x00\x00\x9b&\xad\xa0\x9b\xd6\x05 \x9c\xcf0\xa0\x9d\xa4à\x9e\x9c\x9d\xa0\x9f\x97\x1a\xa0\xa0\x85\xba \xa1v\xfc\xa0\xa2e" + + "\x9c \xa3{Ƞ\xa4N\xb8\xa0\xa5?\xfb \xa6%` \xa7'\xc6 \xa8*, \xa8\xeb\xf8\xa0\xaa\x00Ӡ\xaa\xd5\x15 \xab\xe9\xf0 \xac\xc7l \xad\xc9\xd2 \xae\xa7N \xaf\xa0y\xa0\xb0\x87" + + "0 \xb1\x92Р\xb2pL\xa0\xb3r\xb2\xa0\xb4P.\xa0\xb5IZ \xb60\x10\xa0\xb72v\xa0\xb8\x0f\xf2\xa0\xb9\x12X\xa0\xb9\xefԠ\xba\xe9\x00 \xbb\xd8\xf1 \xbc\xdbW \xbd\xb8\xd3 \xbe\xb1" + + "\xfe\xa0\xbf\x98\xb5 \xc0\x9b\x1b \xc1x\x97 \xc2z\xfd \xc3Xy \xc4Q\xa4\xa0\xc58[ \xc6:\xc1 \xc7X֠\xc7\xda\t\xa0\xca\x16&\x90ʗY\x90\xcb\xd1\x1e\x90\xccw;\x90ͱ" + + "\x00\x90\xce`X\x10ϐ\xe2\x90\xd0n^\x90\xd1r\x16\x10\xd1\xfb2\x10\xd2i\xfe \xd3c)\xa0\xd4I\xe0 \xd5\x1e!\xa0\xd5B\xfd\x90\xd5\xdf\xe0\x10\xd6N\xac \xd6\xfe\x03\xa0\xd8.\x8e \xd8\xf9" + + "\x95 \xda\x0ep \xda\xeb\xec \xdb\xe5\x17\xa0\xdc\xcb\xce \xdd\xc4\xf9\xa0\u07b4\xea\xa0߮\x16 \xe0\x94̠\xe1rH\xa0\xe2kt \xe3R*\xa0\xe4T\x90\xa0\xe52\f\xa0\xe6=\xad \xe7\x1b" + + ") \xe8\x14T\xa0\xe8\xfb\v \xe9\xfdq \xea\xda\xed \xeb\xddS \xec\xba\xcf \xed\xb3\xfa\xa0\ue6b1 \xef\x81g\xa0\xf0\x9f} \xf1aI\xa0\xf2\u007f_ \xf3Jf \xf4_A \xf5!" + + "\r\xa0\xf6?# \xf7\x00\xef\xa0\xf8\x1f\x05 \xf8\xe0Ѡ\xf9\xfe\xe7 \xfa\xc0\xb3\xa0\xfb\xe8\x03\xa0\xfc{\xab\xa0\xfdǻp\x03p\xc6 \x04)X \x05P\xa8 \x06\t: \a0\x8a \a\xe9" + + "\x1c \t\x10l \t\xc8\xfe \n\xf0N \v\xb2\x1a\xa0\f\xd00 \r\x91\xfc\xa0\x0e\xb0\x12 \x0fqޠ\x10\x99.\xa0\x11Q\xc0\xa0\x12y\x10\xa0\x131\xa2\xa0\x14X\xf2\xa0\x15#\xeb\x90\x168" + + "Ɛ\x17\x03͐\x18\x18\xa8\x90\x18㯐\x19\xf8\x8a\x90\x1aÑ\x90\x1b\xe1\xa7\x10\x1c\xac\xae\x10\x1d\xc1\x89\x10\x1e\x8c\x90\x10\x1f\xa1k\x10 lr\x10!\x81M\x10\"LT\x10#a/\x10$," + + "6\x10%JK\x90&\f\x18\x10'*-\x90'\xf54\x90)\n\x0f\x90)\xd5\x16\x90*\xe9\xf1\x90+\xb4\xf8\x90,\xc9Ӑ-\x94ڐ.\xa9\xb5\x90/t\xbc\x900\x89\x97\x901]\xd9\x102r" + + "\xb4\x103=\xbb\x104R\x96\x105\x1d\x9d\x1062x\x106\xfd\u007f\x108\x1b\x94\x908\xdda\x109\xfbv\x90:\xbdC\x10;\xdbX\x90<\xa6_\x90=\xbb:\x90>\x86A\x90?\x9b\x1c\x90@f" + + "#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac" + + "\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0" + + "\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xdd" + + "T\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0" + + "\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x06\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10" + + "\x00\x04\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\bLMT\x00BST\x00GMT\x00BDST\x00\x00\x01\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xf2\x00\x00\x00\a\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0" + + "\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff" + + "\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15" + + " \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff" + + "\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X" + + "\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff" + + "\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X\xd6" + + "\xa0\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff" + + "\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!" + + "\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff" + + "\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH" + + "\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff" + + "\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g" + + "\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\u007f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff" + + "\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfdǻ" + + "p\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00" + + "\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\x00\x00\x00\x00\x10\x99." + + "\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x168Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00" + + "\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c\x90" + + "\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00" + + "\x00&\f\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xc9\xd3" + + "\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00\x00\x001]\xd9\x10\x00\x00\x00\x002r\xb4\x10\x00\x00\x00\x003=\xbb\x10\x00\x00\x00" + + "\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\u007f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC" + + "\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00" + + "\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1" + + "\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00" + + "\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70" + + "\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00" + + "\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae" + + "\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00" + + "\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e" + + "\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00" + + "\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x06\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00" + + "\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\bLMT\x00BST\x00GMT\x00BDST\x00\x00\x01\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01" + + "\nGMT0BST,M3.5.0/1,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa5\xa2\x06\xaf@\x0e\x00\x00@\x0e\x00\x00\r\x00\x1c\x00Euro" + + "pe/LondonUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xf2\x00\x00\x00\a\x00\x00\x00\x11\x80\x00\x00\x00\x9b&\xad\xa0\x9b\xd6\x05 \x9c\xcf0\xa0\x9d\xa4à\x9e\x9c\x9d\xa0\x9f\x97\x1a\xa0\xa0\x85\xba \xa1v\xfc\xa0\xa2e\x9c" + + " \xa3{Ƞ\xa4N\xb8\xa0\xa5?\xfb \xa6%` \xa7'\xc6 \xa8*, \xa8\xeb\xf8\xa0\xaa\x00Ӡ\xaa\xd5\x15 \xab\xe9\xf0 \xac\xc7l \xad\xc9\xd2 \xae\xa7N \xaf\xa0y\xa0\xb0\x870" + + " \xb1\x92Р\xb2pL\xa0\xb3r\xb2\xa0\xb4P.\xa0\xb5IZ \xb60\x10\xa0\xb72v\xa0\xb8\x0f\xf2\xa0\xb9\x12X\xa0\xb9\xefԠ\xba\xe9\x00 \xbb\xd8\xf1 \xbc\xdbW \xbd\xb8\xd3 \xbe\xb1\xfe" + + "\xa0\xbf\x98\xb5 \xc0\x9b\x1b \xc1x\x97 \xc2z\xfd \xc3Xy \xc4Q\xa4\xa0\xc58[ \xc6:\xc1 \xc7X֠\xc7\xda\t\xa0\xca\x16&\x90ʗY\x90\xcb\xd1\x1e\x90\xccw;\x90ͱ\x00" + + "\x90\xce`X\x10ϐ\xe2\x90\xd0n^\x90\xd1r\x16\x10\xd1\xfb2\x10\xd2i\xfe \xd3c)\xa0\xd4I\xe0 \xd5\x1e!\xa0\xd5B\xfd\x90\xd5\xdf\xe0\x10\xd6N\xac \xd6\xfe\x03\xa0\xd8.\x8e \xd8\xf9\x95" + + " \xda\x0ep \xda\xeb\xec \xdb\xe5\x17\xa0\xdc\xcb\xce \xdd\xc4\xf9\xa0\u07b4\xea\xa0߮\x16 \xe0\x94̠\xe1rH\xa0\xe2kt \xe3R*\xa0\xe4T\x90\xa0\xe52\f\xa0\xe6=\xad \xe7\x1b)" + + " \xe8\x14T\xa0\xe8\xfb\v \xe9\xfdq \xea\xda\xed \xeb\xddS \xec\xba\xcf \xed\xb3\xfa\xa0\ue6b1 \xef\x81g\xa0\xf0\x9f} \xf1aI\xa0\xf2\u007f_ \xf3Jf \xf4_A \xf5!\r" + + "\xa0\xf6?# \xf7\x00\xef\xa0\xf8\x1f\x05 \xf8\xe0Ѡ\xf9\xfe\xe7 \xfa\xc0\xb3\xa0\xfb\xe8\x03\xa0\xfc{\xab\xa0\xfdǻp\x03p\xc6 \x04)X \x05P\xa8 \x06\t: \a0\x8a \a\xe9\x1c" + + " \t\x10l \t\xc8\xfe \n\xf0N \v\xb2\x1a\xa0\f\xd00 \r\x91\xfc\xa0\x0e\xb0\x12 \x0fqޠ\x10\x99.\xa0\x11Q\xc0\xa0\x12y\x10\xa0\x131\xa2\xa0\x14X\xf2\xa0\x15#\xeb\x90\x168\xc6" + + "\x90\x17\x03͐\x18\x18\xa8\x90\x18㯐\x19\xf8\x8a\x90\x1aÑ\x90\x1b\xe1\xa7\x10\x1c\xac\xae\x10\x1d\xc1\x89\x10\x1e\x8c\x90\x10\x1f\xa1k\x10 lr\x10!\x81M\x10\"LT\x10#a/\x10$,6" + + "\x10%JK\x90&\f\x18\x10'*-\x90'\xf54\x90)\n\x0f\x90)\xd5\x16\x90*\xe9\xf1\x90+\xb4\xf8\x90,\xc9Ӑ-\x94ڐ.\xa9\xb5\x90/t\xbc\x900\x89\x97\x901]\xd9\x102r\xb4" + + "\x103=\xbb\x104R\x96\x105\x1d\x9d\x1062x\x106\xfd\u007f\x108\x1b\x94\x908\xdda\x109\xfbv\x90:\xbdC\x10;\xdbX\x90<\xa6_\x90=\xbb:\x90>\x86A\x90?\x9b\x1c\x90@f#" + + "\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1" + + "\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11" + + "\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT" + + "\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4" + + "\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x06\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00" + + "\x04\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\bLMT\x00BST\x00GMT\x00BDST\x00\x00\x01\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xf2\x00\x00\x00\a\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0" + + "\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff" + + "\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 " + + "\xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff" + + "\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0" + + "\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff" + + "\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠" + + "\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xff" + + "ϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0" + + "\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff" + + "\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0" + + "\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff" + + "\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0" + + "\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\u007f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff" + + "\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfdǻp" + + "\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00" + + "\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\x00\x00\x00\x00\x10\x99.\xa0" + + "\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x168Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00" + + "\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c\x90\x10" + + "\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00" + + "&\f\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xc9Ӑ" + + "\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00\x00\x001]\xd9\x10\x00\x00\x00\x002r\xb4\x10\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x00" + + "4R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\u007f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10" + + "\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00" + + "BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10" + + "\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00" + + "P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90" + + "\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00" + + "^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90" + + "\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00" + + "l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10" + + "\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00" + + "z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x06\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00" + + "\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\bLMT\x00BST\x00GMT\x00BDST\x00\x00\x01\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01\n" + + "GMT0BST,M3.5.0/1,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x94\xad\x88\x98\x96\b\x00\x00\x96\b\x00\x00\v\x00\x1c\x00Europ" + + "e/RigaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00" + + "\x00\x0f\x00\x00\x00\x00\x00\x00\x00~\x00\x00\x00\x0f\x00\x00\x00&\x80\x00\x00\x00\x9e\xb9\x87\xfe\x9f\x84\x8e\xfe\xa0\x88F~\xa0˂\xfe\xad\xe7\xf1\xdeȯd`\xcabeP\xcc\xe7K\x10ͩ\x17\x90\u03a2" + + "C\x10ϒ4\x10Ђ%\x10А\x89p\x15'\xa7\xd0\x16\x18\xdc@\x17\b\xdbP\x17\xfa\x0f\xc0\x18\xea\x0e\xd0\x19\xdbC@\x1a̓\xd0\x1b\xbc\xa0\xf0\x1c\xac\x91\xf0\x1d\x9c\x82\xf0\x1e\x8cs\xf0\x1f|" + + "d\xf0 lU\xf0!\\F\xf0\"L7\xf0#<(\xf0$,\x19\xf0%\x1c\x19\x00&\f\n\x00'\x055\x80'\xf5&\x80(\xe5\x17\x80)\xd5\b\x80*\xc4\xf9\x80+\xb4\xea\x80,\xa4ۀ-\x94" + + "̀.\x84\xbd\x80/t\xae\x800d\x9f\x801]\xcb\x002M\xbc\x003=\xbb\x104R\x96\x105\x1d\x9d\x1062x\x106\xfd\u007f\x108\x1b\x94\x90:\xbdC\x10;\xdbX\x90<\xa6_\x90=\xbb" + + ":\x90>\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae" + + "\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5" + + "(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g\xe8" + + "\x97\x90h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/" + + "\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x02\x01\x02\x01\x03\x04\a\x05\x06\x05\x06\x05\x04\b\x04\b\x04" + + "\b\x04\b\t\n\t\n\t\n\t\n\t\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e" + + "\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\x00\x00\x16\xa2\x00\x00\x00\x00\x16\xa2\x00\x04" + + "\x00\x00$\xb2\x01\b\x00\x00\x1c \x00\f\x00\x00*0\x00\x10\x00\x00\x0e\x10\x00\x14\x00\x00\x1c \x01\x18\x00\x00\x1c \x01\x18\x00\x008@\x01\x1d\x00\x00*0\x00\x10\x00\x008@\x01\x1d\x00\x00*0\x01!" + + "\x00\x00\x1c \x00\f\x00\x00*0\x01!\x00\x00\x1c \x00\fLMT\x00RMT\x00LST\x00EET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00\x00\x00\x00\x00" + + "\x00\x01\x01\x00\x00\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00" + + "\x00~\x00\x00\x00\x0f\x00\x00\x00&\xff\xff\xff\xffV\xb6\xcd^\xff\xff\xff\xff\x9e\xb9\x87\xfe\xff\xff\xff\xff\x9f\x84\x8e\xfe\xff\xff\xff\xff\xa0\x88F~\xff\xff\xff\xff\xa0˂\xfe\xff\xff\xff\xff\xad\xe7\xf1\xde\xff\xff" + + "\xff\xffȯd`\xff\xff\xff\xff\xcabeP\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xffА" + + "\x89p\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00" + + "\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L" + + "7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\f\n\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00" + + "\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d" + + "\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002M\xbc\x00\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\u007f\x10\x00\x00" + + "\x00\x008\x1b\x94\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f" + + "#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00" + + "\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac" + + "\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00" + + "\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0" + + "\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00" + + "\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xdd" + + "T\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00" + + "\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0" + + "\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x02" + + "\x01\x02\x01\x03\x04\a\x05\x06\x05\x06\x05\x04\b\x04\b\x04\b\x04\b\t\n\t\n\t\n\t\n\t\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e" + + "\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e" + + "\r\x0e\r\x0e\x00\x00\x16\xa2\x00\x00\x00\x00\x16\xa2\x00\x04\x00\x00$\xb2\x01\b\x00\x00\x1c \x00\f\x00\x00*0\x00\x10\x00\x00\x0e\x10\x00\x14\x00\x00\x1c \x01\x18\x00\x00\x1c \x01\x18\x00\x008@\x01\x1d\x00\x00" + + "*0\x00\x10\x00\x008@\x01\x1d\x00\x00*0\x01!\x00\x00\x1c \x00\f\x00\x00*0\x01!\x00\x00\x1c \x00\fLMT\x00RMT\x00LST\x00EET\x00MSK\x00CET\x00CE" + + "ST\x00MSD\x00EEST\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\nEET-2EEST,M3.5.0/" + + "3,M10.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\u07b9\x9bQ\xce\x06\x00\x00\xce\x06\x00\x00\x0e\x00\x1c\x00Europe/AndorraUT\t\x00" + + "\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00l" + + "\x00\x00\x00\x05\x00\x00\x00\x11\x80\x00\x00\x00\xd4A\xdb\x00\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90" + + "Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90" + + "QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10" + + "_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10" + + "m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10" + + "{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x01l\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\bLMT\x00WET\x00CET\x00CEST\x00\x00\x00\x00\x01\x01" + + "\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00l\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff~6\xb3\x94\xff\xff\xff" + + "\xff\xd4A\xdb\x00\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT" + + "\x10\x00\x00\x00\x00#\x86A" + + "\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00" + + "\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿" + + "\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00" + + "\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4" + + "\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00" + + "\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr" + + "\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00" + + "\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2" + + "\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00" + + "\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x00\x00\x01l\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\bLMT\x00WET\x00CET\x00CEST\x00\x00\x00\x00\x01\x01\x00\x00\x00\x01\x01\nC" + + "ET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe59\xab\xf0\xfd\b\x00\x00\xfd\b\x00\x00\r\x00\x1c\x00Euro" + + "pe/PragueUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\b\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x8f\x00\x00\x00\b\x00\x00\x00\x11\x80\x00\x00\x00\x9b\f\x17`\x9b\xd5\xda\xf0\x9cٮ\x90\x9d\xa4\xb5\x90\x9e\xb9\x90\x90\x9f\x84\x97\x90\xc8\tq\x90\xcc\xe7K\x10ͩ\x17" + + "\x90\u03a2C\x10ϒ4\x10Ђ%\x10\xd1r\x16\x10\xd2b\a\x10Ӏ\x1c\x90\xd4I\xd2\x10ԓ\xb4 \xd5\x02r \xd5L8\x10\xd6)\xb4\x10\xd7,\x1a\x10\xd8\t\x96\x10\xd9\x01p\x10\xd9\xe9x" + + "\x10\x11d'\x90\x12T\x18\x90\x13MD\x10\x143\xfa\x90\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90" + + "\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1" + + "\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70" + + "\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae" + + "\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e" + + "\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x05\x02\x03\x04\x03\x04\x03\x04\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x00\x00\r\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x00\x00\x01\r\x00\x00\x1c \x01\x04\x00\x00" + + "\x0e\x10\x00\tLMT\x00CEST\x00CET\x00GMT\x00\x00\x00\x00\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\t\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00\x00\t\x00\x00\x00\x15\xff\xff\xff\xff\x1eI\x92\xf8\xff\xff\xff\xffl\xcf\xea\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ" + + "\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff" + + "\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2b\a\x10\xff\xff\xff\xffӀ\x1c\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xffԓ\xb4 \xff\xff\xff\xff\xd5\x02r" + + " \xff\xff\xff\xff\xd5L8\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x01p\x10\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x11d'\x90\x00\x00\x00" + + "\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf" + + "\x90\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00" + + "\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b" + + "\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00" + + "\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a" + + "\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00" + + "\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce" + + "\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00" + + "\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=" + + "\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00" + + "\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ" + + "\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x03\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x06\x03\x04\x05\x04\x05\x04\x05\a" + + "\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a" + + "\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\x00\x00\r" + + "\x88\x00\x00\x00\x00\r\x88\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x00\x00\x01\x11\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00PMT\x00C" + + "EST\x00CET\x00GMT\x00\x00\x00\x00\x00\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M10.5.0/3\nPK" + + "\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP4\x91\x960\xfa\b\x00\x00\xfa\b\x00\x00\r\x00\x1c\x00Europe/BerlinUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04" + + "\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x8f\x00\x00\x00\t\x00\x00\x00\x12\x80\x00\x00\x00\x9b\f\x17" + + "`\x9b\xd5\xda\xf0\x9cٮ\x90\x9d\xa4\xb5\x90\x9e\xb9\x90\x90\x9f\x84\x97\x90\xc8\tq\x90\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10Ђ%\x10\xd1r\x16\x10Ѷ\x96\x00\xd2X\xbe\x80ҡO" + + "\x10\xd3c\x1b\x90\xd4K#\x90\xd59\xd1 \xd5g\xe7\x90ըs\x00\xd6)\xb4\x10\xd7,\x1a\x10\xd8\t\x96\x10\xd9\x02\xc1\x90\xd9\xe9x\x10\x13MD\x10\x143\xfa\x90\x15#\xeb\x90\x16\x13ܐ\x17\x03\xcd" + + "\x90\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849" + + "\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn" + + "\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec" + + "\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[" + + "\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xee\xd9" + + "\x90z\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x01\x04\x03\x04\x03\x06\x01\x04\x03\x04\x03\x04\a\b\a\b\a\b\a\b" + + "\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b" + + "\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\x00\x00\f\x88\x00\x00\x00\x00\x1c \x01\x04" + + "\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00*0\x01\r\x00\x00*0\x01\r\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00CEMT\x00" + + "\x00\x00\x00\x01\x01\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x8f\x00\x00\x00\t\x00\x00" + + "\x00\x12\xff\xff\xff\xffo\xa2a\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff" + + "\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xffѶ" + + "\x96\x00\xff\xff\xff\xff\xd2X\xbe\x80\xff\xff\xff\xffҡO\x10\xff\xff\xff\xff\xd3c\x1b\x90\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd5g\xe7\x90\xff\xff\xff\xffըs\x00\xff\xff" + + "\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#" + + "\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00" + + "\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<" + + "E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00" + + "\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]" + + "\xd9\x10\x00\x00\x00\x002r\xb4\x10\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\u007f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00" + + "\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b" + + "\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00" + + "\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e" + + "\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00" + + "\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5" + + "\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00" + + "\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8" + + "y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00" + + "\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e" + + "\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00" + + "\x00\x00\u007f\x8e\u007f\x90\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x01\x04\x03\x04\x03\x06\x01\x04\x03\x04\x03\x04\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a" + + "\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a" + + "\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\x00\x00\f\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00" + + "\x00*0\x01\r\x00\x00*0\x01\r\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00CEMT\x00\x00\x00\x00\x01\x01\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x01\x01\n" + + "CET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP[}\x0epd\b\x00\x00d\b\x00\x00\x0e\x00\x1c\x00Eur" + + "ope/TallinnUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00{\x00\x00\x00\x0f\x00\x00\x00\"\x80\x00\x00\x00\x9eY-̞\xb9\x90\x90\x9f\x84\x97\x90\xa1\x00+p\xa4soLȰ\xb5\xe0\xcaƗP\xcc\xe7K\x10\xcd" + + "\xa9\x17\x90\u03a2C\x10ϒ4\x10\xd0t\xcb\xe0\x15'\xa7\xd0\x16\x18\xdc@\x17\b\xdbP\x17\xfa\x0f\xc0\x18\xea\x0e\xd0\x19\xdbC@\x1a̓\xd0\x1b\xbc\xa0\xf0\x1c\xac\x91\xf0\x1d\x9c\x82\xf0\x1e\x8cs\xf0\x1f" + + "|d\xf0 lU\xf0!\\F\xf0\"L7\xf0#<(\xf0$,\x19\xf0%\x1c\x19\x00&\f\n\x00'\x055\x80'\xf5&\x80(\xe5\x17\x80)\xd5\b\x80*\xc4\xf9\x80+\xb4\xea\x80,\xa4ۀ-" + + "\x94̀.\x84\xbd\x80/t\xae\x800d\x9f\x801]\xcb\x002r\xa6\x003=\xad\x004R\x88\x005\x1d\x8f\x0062x\x106\xfd\u007f\x108\x1b\x94\x90<\xa6_\x90=\xbb:\x90>\x86A\x90?" + + "\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M" + + "\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[" + + "\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i" + + "\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x" + + "\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x04\x02\x03\x01\x05\x06\a\x03\x02\x03\x02\x06\b\x06\b\x06\b\x06\b\t\n\t\n\t" + + "\n\t\n\t\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\r\x0e\x05\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r" + + "\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x00\x00\x174\x00\x00\x00\x00\x174\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10" + + "\x00\r\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x00\x11\x00\x00*0\x00\x15\x00\x00\x1c \x01\b\x00\x008@\x01\x19\x00\x00*0\x00\x15\x00\x008@\x01\x19\x00\x00*0\x01\x1d\x00\x00\x1c \x00\x11\x00\x00\x1c " + + "\x00\x11\x00\x00*0\x01\x1dLMT\x00TMT\x00CEST\x00CET\x00EET\x00MSK\x00MSD\x00EEST\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00{\x00\x00\x00\x0f\x00\x00\x00\"\xff\xff\xff\xff" + + "V\xb6\xcc\xcc\xff\xff\xff\xff\x9eY-\xcc\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xa1\x00+p\xff\xff\xff\xff\xa4soL\xff\xff\xff\xffȰ\xb5\xe0\xff\xff\xff\xff\xcaƗP" + + "\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0t\xcb\xe0\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00" + + "\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0" + + "\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00" + + "%\x1c\x19\x00\x00\x00\x00\x00&\f\n\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80" + + "\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xa6\x00\x00\x00\x00\x00" + + "3=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x8f\x00\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\u007f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90" + + "\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00" + + "EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10" + + "\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00" + + "S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10" + + "\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00" + + "a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐" + + "\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00" + + "oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90" + + "\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00" + + "}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x04\x02\x03\x01\x05\x06\a\x03\x02\x03\x02\x06\b\x06\b\x06\b\x06\b\t\n\t\n\t\n\t\n\t\v\f\v\f\v\f\v\f\v\f\v" + + "\f\v\f\v\f\v\f\v\r\x0e\x05\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e" + + "\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x0e\r\x00\x00\x174\x00\x00\x00\x00\x174\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x00\x11\x00" + + "\x00*0\x00\x15\x00\x00\x1c \x01\b\x00\x008@\x01\x19\x00\x00*0\x00\x15\x00\x008@\x01\x19\x00\x00*0\x01\x1d\x00\x00\x1c \x00\x11\x00\x00\x1c \x00\x11\x00\x00*0\x01\x1dLMT\x00TMT" + + "\x00CEST\x00CET\x00EET\x00MSK\x00MSD\x00EEST\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\nEE" + + "T-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfcc!\x8eQ\n\x00\x00Q\n\x00\x00\v\x00\x1c\x00Eur" + + "ope/RomeUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a" + + "\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xa9\x00\x00\x00\a\x00\x00\x00\r\x80\x00\x00\x00\x9b8\xf8p\x9b\xd5\xcc\xe0\x9c\xc5\xcb\xf0\x9d\xb7\x00`\x9e\x89\xfep\x9f\xa0\x1c\xe0\xa0`\xa5\xf0\xa1~\xad`\xa2\\7p" + + "\xa3L\x1a`\xc8l5\xf0\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10\xd0n^\x90\xd1r\x16\x10\xd2L\xd2\xf0\xd3>1\x90\xd4I\xd2\x10\xd5\x1d\xf7p\xd6)\x97\xf0\xd6뀐\xd8\t\x96\x10" + + "\xf93\xb5\xf0\xf9\xd9\xc4\xe0\xfb\x1c\xd2p\xfb\xb9\xb4\xf0\xfc\xfc\xb4p\xfd\x99\x96\xf0\xfe\xe5\xd0\xf0\xff\x82\xb3p\x00Ų\xf0\x01b\x95p\x02\x9cZp\x03Bwp\x04\x85v\xf0\x05+\x93\xf0\x06n\x93p" + + "\a\vu\xf0\bE:\xf0\b\xebW\xf0\n.Wp\n\xcb9\xf0\f\x0e9p\f\xab\x1b\xf0\r\xe4\xe0\xf0\x0e\x8a\xfd\xf0\x0f\xcd\xfdp\x10t\x1ap\x11\xad\xdfp\x12S\xfcp\x13MD\x10\x143\xfa\x90" + + "\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10" + + "#\x86A\x90" + + "?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90" + + "M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90" + + "[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90" + + "i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10" + + "x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x01\x02\x04\x03\x04\x03\x04" + + "\x03\x04\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\v\xb4\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x1c \x01" + + "\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00" + + "\x00\b\x00\x00\x00\x00\x00\x00\x00\xaa\x00\x00\x00\b\x00\x00\x00\x11\xff\xff\xff\xff>(\xe8L\xff\xff\xff\xffp\xbc\x81p\xff\xff\xff\xff\x9b8\xf8p\xff\xff\xff\xff\x9b\xd5\xcc\xe0\xff\xff\xff\xff\x9c\xc5\xcb\xf0\xff\xff" + + "\xff\xff\x9d\xb7\x00`\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0\x1c\xe0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xad`\xff\xff\xff\xff\xa2\\7p\xff\xff\xff\xff\xa3L\x1a`\xff\xff\xff\xff\xc8l" + + "5\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2L\xd2\xf0\xff\xff" + + "\xff\xff\xd3>1\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd5\x1d\xf7p\xff\xff\xff\xff\xd6)\x97\xf0\xff\xff\xff\xff\xd6뀐\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xf93\xb5\xf0\xff\xff\xff\xff\xf9\xd9" + + "\xc4\xe0\xff\xff\xff\xff\xfb\x1c\xd2p\xff\xff\xff\xff\xfb\xb9\xb4\xf0\xff\xff\xff\xff\xfc\xfc\xb4p\xff\xff\xff\xff\xfd\x99\x96\xf0\xff\xff\xff\xff\xfe\xe5\xd0\xf0\xff\xff\xff\xff\xff\x82\xb3p\x00\x00\x00\x00\x00Ų\xf0\x00\x00" + + "\x00\x00\x01b\x95p\x00\x00\x00\x00\x02\x9cZp\x00\x00\x00\x00\x03Bwp\x00\x00\x00\x00\x04\x85v\xf0\x00\x00\x00\x00\x05+\x93\xf0\x00\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\a\vu\xf0\x00\x00\x00\x00\bE" + + ":\xf0\x00\x00\x00\x00\b\xebW\xf0\x00\x00\x00\x00\n.Wp\x00\x00\x00\x00\n\xcb9\xf0\x00\x00\x00\x00\f\x0e9p\x00\x00\x00\x00\f\xab\x1b\xf0\x00\x00\x00\x00\r\xe4\xe0\xf0\x00\x00\x00\x00\x0e\x8a\xfd\xf0\x00\x00" + + "\x00\x00\x0f\xcd\xfdp\x00\x00\x00\x00\x10t\x1ap\x00\x00\x00\x00\x11\xad\xdfp\x00\x00\x00\x00\x12S\xfcp\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13" + + "ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00" + + "\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f" + + "#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00" + + "\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac" + + "\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00" + + "\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0" + + "\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00" + + "\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xdd" + + "T\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00" + + "\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0" + + "\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x02\x03\x05\x04\x05\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x06\a\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x00\x00\v\xb4\x00\x00\x00\x00\v\xb4\x00\x04" + + "\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x01\b\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00RMT\x00CEST\x00CET\x00\x00\x00\x00\x00\x01\x01\x01" + + "\x01\x00\x00\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP_4\xf8\xf2<\n\x00\x00<" + + "\n\x00\x00\f\x00\x1c\x00Europe/MaltaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xa9\x00\x00\x00\a\x00\x00\x00\r\x80\x00\x00\x00\x9b8\xf8p\x9b\xd5\xcc\xe0\x9c\xc5\xcb\xf0\x9d\xb7\x00`\x9e\x89\xfep\x9f\xa0\x1c\xe0\xa0" + + "`\xa5\xf0\xa1~\xad`\xa2\\7p\xa3L\x1a`\xc8l5\xf0\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϐ\xe2\x90\xd0n^\x90\xd1r\x16\x10\xd2L\xd2\xf0\xd3>1\x90\xd4I\xd2\x10\xd5\x1d\xf7p\xd6" + + ")\x97\xf0\xd6뀐\xd8\t\x96\x10\xf93\xb5\xf0\xf9\xd9\xc4\xe0\xfb\x1c\xd2p\xfb\xb9\xb4\xf0\xfc\xfc\xb4p\xfd\x99\x96\xf0\xfe\xe5\xd0\xf0\xff\x82\xb3p\x00Ų\xf0\x01b\x95p\x02\x9cZp\x03Bwp\x04" + + "\x85v\xf0\x05+\x93\xf0\x06\x1a3p\a\n$p\b\x17\x16p\b\xda4p\t\xf7\x14\x90\n\xc2\r\x80\v\xd6\xf6\x90\f\xa1\xef\x80\r\xb6ؐ\x0e\x81р\x0f\x96\xba\x90\x10a\xb3\x80\x11v\x9c\x90\x12" + + "A\x95\x80\x13E[\x10\x14*\xb2\x00\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 " + + "lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J" + + "\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X" + + "\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g" + + "\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u" + + "\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03" + + "\x04\x03\x04\x03\x01\x02\x04\x03\x04\x03\x04\x03\x04\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\r\x9c\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x0e\x10\x00\t" + + "\x00\x00\x1c \x01\x04\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xa9\x00\x00\x00\a\x00\x00\x00\r\xff\xff\xff\xffp\xbd\xd3d\xff\xff\xff\xff\x9b8\xf8p\xff\xff\xff\xff\x9b\xd5\xcc\xe0\xff\xff\xff\xff\x9c\xc5\xcb" + + "\xf0\xff\xff\xff\xff\x9d\xb7\x00`\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0\x1c\xe0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xad`\xff\xff\xff\xff\xa2\\7p\xff\xff\xff\xff\xa3L\x1a`\xff\xff\xff" + + "\xff\xc8l5\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2L\xd2" + + "\xf0\xff\xff\xff\xff\xd3>1\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd5\x1d\xf7p\xff\xff\xff\xff\xd6)\x97\xf0\xff\xff\xff\xff\xd6뀐\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xf93\xb5\xf0\xff\xff\xff" + + "\xff\xf9\xd9\xc4\xe0\xff\xff\xff\xff\xfb\x1c\xd2p\xff\xff\xff\xff\xfb\xb9\xb4\xf0\xff\xff\xff\xff\xfc\xfc\xb4p\xff\xff\xff\xff\xfd\x99\x96\xf0\xff\xff\xff\xff\xfe\xe5\xd0\xf0\xff\xff\xff\xff\xff\x82\xb3p\x00\x00\x00\x00\x00Ų" + + "\xf0\x00\x00\x00\x00\x01b\x95p\x00\x00\x00\x00\x02\x9cZp\x00\x00\x00\x00\x03Bwp\x00\x00\x00\x00\x04\x85v\xf0\x00\x00\x00\x00\x05+\x93\xf0\x00\x00\x00\x00\x06\x1a3p\x00\x00\x00\x00\a\n$p\x00\x00\x00" + + "\x00\b\x17\x16p\x00\x00\x00\x00\b\xda4p\x00\x00\x00\x00\t\xf7\x14\x90\x00\x00\x00\x00\n\xc2\r\x80\x00\x00\x00\x00\v\xd6\xf6\x90\x00\x00\x00\x00\f\xa1\xef\x80\x00\x00\x00\x00\r\xb6ؐ\x00\x00\x00\x00\x0e\x81\xd1" + + "\x80\x00\x00\x00\x00\x0f\x96\xba\x90\x00\x00\x00\x00\x10a\xb3\x80\x00\x00\x00\x00\x11v\x9c\x90\x00\x00\x00\x00\x12A\x95\x80\x00\x00\x00\x00\x13E[\x10\x00\x00\x00\x00\x14*\xb2\x00\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00" + + "\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae" + + "\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00" + + "\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf" + + "\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00" + + "\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N" + + "\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00" + + "\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]\xcc" + + "\x90\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00" + + "\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<" + + "\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00" + + "\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f" + + "\x90\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x01\x02\x04\x03\x04\x03\x04\x03\x04\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\r\x9c\x00\x00\x00\x00\x1c " + + "\x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x01\x04\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x01\x01\n" + + "CET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xcd\xc6JÀ\a\x00\x00\x80\a\x00\x00\r\x00\x1c\x00Eur" + + "ope/ZagrebUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00w\x00\x00\x00\a\x00\x00\x00\r\x80\x00\x00\x00\xca\x025\xe0\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10Ђ%\x10ѡ\x8c\x10\xd2N@\x90\x18\xe3" + + "\xaf\x90\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd" + + "\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW" + + "\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94" + + "\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88" + + "=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{\xce" + + "\xbb\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x04\x02\x03\x02\x03\x02\x03\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\b\x00\x00\x1c \x01\b\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\x04L" + + "MT\x00CET\x00CEST\x00\x00\x00\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00" + + "\x00w\x00\x00\x00\a\x00\x00\x00\r\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff" + + "\xff\xffЂ%\x10\xff\xff\xff\xffѡ\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac" + + "\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00" + + "\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#" + + "\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00" + + "\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17" + + "N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00" + + "\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]" + + "̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00" + + "\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ" + + "<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00" + + "\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e" + + "\u007f\x90\x01\x04\x02\x03\x02\x03\x02\x03\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\b\x00\x00\x1c \x01\b\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\x04LMT\x00CET\x00CEST\x00\x00\x00\x01\x01" + + "\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb6\xfd\xfb\xb4^\v\x00\x00" + + "^\v\x00\x00\x10\x00\x1c\x00Europe/AmsterdamUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\xb4\x00\x00\x00\r\x00\x00\x00!\x80\x00\x00\x00\x9b\f.\xec\x9b\xd5\xd6\\\x9cٸ\f\x9d\xa4\xbf\f\x9e\xa7%\f" + + "\x9f\x97\x16\f\xa0\x90A\x8c\xa1v\xf8\f\xa2p#\x8c\xa3V\xda\f\xa4P\x05\x8c\xa56\xbc\f\xa6%[\x8c\xa7'\xc1\x8c\xa8^㌩\a\xa3\x8c\xa9\xeeZ\f\xaa煌\xac'\xe2\f\xac\xc7g\x8c" + + "\xad\xedf\f\xae\xa7I\x8c\xafΙ\x8c\xb0\x87+\x8c\xb1\xb1\x1e\x8c\xb2pH\f\xb3\x92R\f\xb4P*\f\xb5s\x85\x8c\xb60\f\f\xb7T\xb9\f\xb8\x0f\xee\f\xb9@x\x8c\xb9\xef\xd0\f\xbb\x18q\x8c" + + "\xbb\xd8쌼\xf9\xa5\f\xbd\xb8Ό\xbe\xda،\xbf\x98\xb0\x8c\xc0\xbd]\x8c\xc1x\x92\x8c§ˌ\xc2\xdc]\\\xc3Xtp\xc4\u007f\xc4p\xc58Vp\xc6`\xf7\xf0\xc7!r\xf0\xc8D\xb2P" + + "\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10Ђ%\x10\xd1r\x16\x10\xd2N@\x90\r\xa4c\x90\x0e\x8b\x1a\x10\x0f\x84E\x90\x10t6\x90\x11d'\x90\x12T\x18\x90\x13MD\x10\x143\xfa\x90" + + "\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10" + + "#\x86A\x90" + + "?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90" + + "M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90" + + "[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90" + + "i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10" + + "x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\a\x05\x06\x05\x06\x05\n\b\t\b\t\b\t\b\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f" + + "\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f" + + "\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\x00\x00\x04\x94\x00\x00\x00\x00\x12\xa4\x01\x04\x00\x00\x04\x94\x00\b\x00\x00\x12\xa4\x01\x04" + + "\x00\x00\x04\x94\x00\b\x00\x00\x04\xb0\x00\f\x00\x00\x12\xc0\x01\x12\x00\x00\x12\xc0\x01\x12\x00\x00\x0e\x10\x00\x18\x00\x00\x1c \x01\x1c\x00\x00\x1c \x01\x1c\x00\x00\x1c \x01\x1c\x00\x00\x0e\x10\x00\x18LMT\x00NS" + + "T\x00AMT\x00+0020\x00+0120\x00CET\x00CEST\x00\x00\x00\x00\x01\x01\x01\x01\x00\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\xb4\x00\x00\x00\r\x00\x00\x00!\xff\xff\xff\xff\x02\x12Ql\xff\xff\xff\xff\x9b\f.\xec\xff\xff\xff\xff\x9b\xd5\xd6" + + "\\\xff\xff\xff\xff\x9cٸ\f\xff\xff\xff\xff\x9d\xa4\xbf\f\xff\xff\xff\xff\x9e\xa7%\f\xff\xff\xff\xff\x9f\x97\x16\f\xff\xff\xff\xff\xa0\x90A\x8c\xff\xff\xff\xff\xa1v\xf8\f\xff\xff\xff\xff\xa2p#\x8c\xff\xff\xff" + + "\xff\xa3V\xda\f\xff\xff\xff\xff\xa4P\x05\x8c\xff\xff\xff\xff\xa56\xbc\f\xff\xff\xff\xff\xa6%[\x8c\xff\xff\xff\xff\xa7'\xc1\x8c\xff\xff\xff\xff\xa8^\xe3\x8c\xff\xff\xff\xff\xa9\a\xa3\x8c\xff\xff\xff\xff\xa9\xeeZ" + + "\f\xff\xff\xff\xff\xaa煌\xff\xff\xff\xff\xac'\xe2\f\xff\xff\xff\xff\xac\xc7g\x8c\xff\xff\xff\xff\xad\xedf\f\xff\xff\xff\xff\xae\xa7I\x8c\xff\xff\xff\xff\xafΙ\x8c\xff\xff\xff\xff\xb0\x87+\x8c\xff\xff\xff" + + "\xff\xb1\xb1\x1e\x8c\xff\xff\xff\xff\xb2pH\f\xff\xff\xff\xff\xb3\x92R\f\xff\xff\xff\xff\xb4P*\f\xff\xff\xff\xff\xb5s\x85\x8c\xff\xff\xff\xff\xb60\f\f\xff\xff\xff\xff\xb7T\xb9\f\xff\xff\xff\xff\xb8\x0f\xee" + + "\f\xff\xff\xff\xff\xb9@x\x8c\xff\xff\xff\xff\xb9\xef\xd0\f\xff\xff\xff\xff\xbb\x18q\x8c\xff\xff\xff\xff\xbb\xd8\xec\x8c\xff\xff\xff\xff\xbc\xf9\xa5\f\xff\xff\xff\xff\xbd\xb8Ό\xff\xff\xff\xff\xbe\xda،\xff\xff\xff" + + "\xff\xbf\x98\xb0\x8c\xff\xff\xff\xff\xc0\xbd]\x8c\xff\xff\xff\xff\xc1x\x92\x8c\xff\xff\xff\xff§ˌ\xff\xff\xff\xff\xc2\xdc]\\\xff\xff\xff\xff\xc3Xtp\xff\xff\xff\xff\xc4\u007f\xc4p\xff\xff\xff\xff\xc58V" + + "p\xff\xff\xff\xff\xc6`\xf7\xf0\xff\xff\xff\xff\xc7!r\xf0\xff\xff\xff\xff\xc8D\xb2P\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff" + + "\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'" + + "\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00" + + "\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81" + + "\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00" + + "\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8" + + "\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00" + + "\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F" + + "\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00" + + "\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5" + + "\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00" + + "\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9" + + "\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00" + + "\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\a\x05\x06\x05\x06\x05\n\b\t\b\t\b\t\b\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v" + + "\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v" + + "\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\v\f\x00\x00\x04\x94\x00\x00\x00\x00\x12\xa4\x01\x04\x00\x00\x04\x94\x00\b\x00\x00\x12\xa4\x01" + + "\x04\x00\x00\x04\x94\x00\b\x00\x00\x04\xb0\x00\f\x00\x00\x12\xc0\x01\x12\x00\x00\x12\xc0\x01\x12\x00\x00\x0e\x10\x00\x18\x00\x00\x1c \x01\x1c\x00\x00\x1c \x01\x1c\x00\x00\x1c \x01\x1c\x00\x00\x0e\x10\x00\x18LMT\x00N" + + "ST\x00AMT\x00+0020\x00+0120\x00CET\x00CEST\x00\x00\x00\x00\x01\x01\x01\x01\x00\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\nCET-1" + + "CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x83\xd5\x04\xbb\xd2\a\x00\x00\xd2\a\x00\x00\x0e\x00\x1c\x00Europe/N" + + "icosiaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00" + + "\x00\x05\x00\x00\x00\x00\x00\x00\x00\u007f\x00\x00\x00\x05\x00\x00\x00\r\xa5w\x1e\xb8\t\xed\xaf\xe0\nݒ\xd0\v\xfad\xe0\f\xbe\xc6P\r\xa49`\x0e\x8a\xe1\xd0\x0f\x84\x1b`\x10uO\xd0\x11c\xfd`\x12S" + + "\xe0P\x13M\x19\xe0\x143\xc2P\x15#\xc1`\x16\x13\xa4P\x17\x03\xa3`\x17\xf3\x86P\x18\xe3\x85`\x19\xd3hP\x1a\xc3g`\x1b\xbc\x84\xd0\x1c\xac\x83\xe0\x1d\x9cf\xd0\x1e\x8ce\xe0\x1f|H\xd0 l" + + "G\xe0!\\*\xd0\"L)\xe0#<\f\xd0$,\v\xe0%\x1b\xee\xd0&\v\xed\xe0'\x05\vP'\xf5\n`(\xe4\xedP)\xd4\xec`*\xc4\xcfP+\xb4\xce`,\xa4\xb1P-\x94\xb0`.\x84" + + "\x93P/t\x92`0duP1]\xae\xe02M\x91\xd03=\x90\xe04-s\xd05\x1dr\xe062x\x106\xfd\u007f\x108\x1b\x94\x908\xdda\x109\xfbv\x90:\xbdC\x10;\xdbX\x90<\xa6" + + "_\x90=\xbb:\x90>\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3" + + "\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7" + + "\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d" + + "\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11" + + "\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x1fH\x00\x00\x00" + + "\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00\x1c \x00\t\x00\x00*0\x01\x04LMT\x00EEST\x00EET\x00\x00\x00\x00\x01\x01\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\u007f\x00\x00\x00\x05\x00\x00\x00\r\xff\xff\xff\xff\xa5w\x1e\xb8\x00\x00\x00\x00\t\xed\xaf\xe0\x00\x00\x00\x00\nݒ\xd0\x00\x00\x00\x00\v\xfa" + + "d\xe0\x00\x00\x00\x00\f\xbe\xc6P\x00\x00\x00\x00\r\xa49`\x00\x00\x00\x00\x0e\x8a\xe1\xd0\x00\x00\x00\x00\x0f\x84\x1b`\x00\x00\x00\x00\x10uO\xd0\x00\x00\x00\x00\x11c\xfd`\x00\x00\x00\x00\x12S\xe0P\x00\x00" + + "\x00\x00\x13M\x19\xe0\x00\x00\x00\x00\x143\xc2P\x00\x00\x00\x00\x15#\xc1`\x00\x00\x00\x00\x16\x13\xa4P\x00\x00\x00\x00\x17\x03\xa3`\x00\x00\x00\x00\x17\xf3\x86P\x00\x00\x00\x00\x18\xe3\x85`\x00\x00\x00\x00\x19\xd3" + + "hP\x00\x00\x00\x00\x1a\xc3g`\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 lG\xe0\x00\x00" + + "\x00\x00!\\*\xd0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf5" + + "\n`\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00" + + "\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002M\x91\xd0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004-s\xd0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062" + + "x\x10\x00\x00\x00\x006\xfd\u007f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00" + + "\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%" + + "\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00" + + "\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rl" + + "e\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00" + + "\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_" + + "\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00" + + "\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6" + + "S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00" + + "\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99" + + "\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x1fH\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00\x1c \x00\t\x00\x00*" + + "0\x01\x04LMT\x00EEST\x00EET\x00\x00\x00\x00\x01\x01\x00\x00\x00\x01\x01\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04" + + "\n\x00\x00\x00\x00\x00\xf5F\x9cP\xff\xba\xee&\x88\b\x00\x00\x88\b\x00\x00\x10\x00\x1c\x00Europe/BucharestUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01" + + "\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x88\x00\x00\x00\b\x00\x00\x00\x11\x80\x00\x00\x00\xb7\xb0" + + "\xd2\b\xb9>\xf3`\xb9\xef\x9c`\xbaߍ`\xbb\xcf~`\xbcȩླྀ\x9aྨ\x8b࿘|\xe0\xc0\x88m\xe0\xc1x^\xe0\xc2hO\xe0\xc3X@\xe0\xc4H1\xe0\xc58\"\xe0\xc6(" + + "\x13\xe0\xc7\x18\x04\xe0\x11\xad\xd1`\x12S\xe0P\x13M\v\xd0\x143\xd0`\x15#݀\x16\x13\u0380\x17\x03\xbf\x80\x17\xf3\xb0\x80\x18㡀\x19Ӓ\x80\x1aÃ\x80\x1b\xbc\xaf\x00\x1c\xac\xa0\x00\x1d\x9c" + + "\x91\x00\x1e\x8c\x82\x00\x1f|s\x00 ld\x00!\\U\x00\"LF\x00#<7\x00$,(\x00%\x1c\x19\x00&\f\n\x00'\x055\x80'\xf5\n`(\xe4\xfb`)\xd4\xec`*\xc4\xdd`+\xb4" + + "\xce`,\xa4\xbf`-\x94\xb0`.\x84\x93P/t\x92`0duP1]\xae\xe02r{\xd03=\xbb\x104R\x96\x105\x1d\x9d\x1062x\x106\xfd\u007f\x108\x1b\x94\x908\xdda\x109\xfb" + + "v\x90:\xbdC\x10;\xdbX\x90<\xa6_\x90=\xbb:\x90>\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee" + + "\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V," + + ")\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f" + + "\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf" + + "\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x05" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x04\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x04\x05\x04\x05\x06\a\x06\a\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x00\x00\x18x\x00\x00\x00\x00\x18x\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x01\b\x00\x00\x1c " + + "\x00\rLMT\x00BMT\x00EEST\x00EET\x00\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00" + + "\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x88\x00\x00\x00\b\x00\x00\x00\x11\xff\xff\xff\xffl\xcf\xe0\b\xff\xff\xff\xff\xb7\xb0\xd2\b\xff\xff\xff\xff\xb9>\xf3`\xff\xff\xff\xff\xb9\xef\x9c`\xff\xff\xff\xff\xbaߍ`\xff" + + "\xff\xff\xff\xbb\xcf~`\xff\xff\xff\xff\xbcȩ\xe0\xff\xff\xff\xff\xbd\xb8\x9a\xe0\xff\xff\xff\xff\xbe\xa8\x8b\xe0\xff\xff\xff\xff\xbf\x98|\xe0\xff\xff\xff\xff\xc0\x88m\xe0\xff\xff\xff\xff\xc1x^\xe0\xff\xff\xff\xff\xc2" + + "hO\xe0\xff\xff\xff\xff\xc3X@\xe0\xff\xff\xff\xff\xc4H1\xe0\xff\xff\xff\xff\xc58\"\xe0\xff\xff\xff\xff\xc6(\x13\xe0\xff\xff\xff\xff\xc7\x18\x04\xe0\x00\x00\x00\x00\x11\xad\xd1`\x00\x00\x00\x00\x12S\xe0P\x00" + + "\x00\x00\x00\x13M\v\xd0\x00\x00\x00\x00\x143\xd0`\x00\x00\x00\x00\x15#݀\x00\x00\x00\x00\x16\x13\u0380\x00\x00\x00\x00\x17\x03\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18㡀\x00\x00\x00\x00\x19" + + "Ӓ\x80\x00\x00\x00\x00\x1aÃ\x80\x00\x00\x00\x00\x1b\xbc\xaf\x00\x00\x00\x00\x00\x1c\xac\xa0\x00\x00\x00\x00\x00\x1d\x9c\x91\x00\x00\x00\x00\x00\x1e\x8c\x82\x00\x00\x00\x00\x00\x1f|s\x00\x00\x00\x00\x00 ld\x00\x00" + + "\x00\x00\x00!\\U\x00\x00\x00\x00\x00\"LF\x00\x00\x00\x00\x00#<7\x00\x00\x00\x00\x00$,(\x00\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\f\n\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'" + + "\xf5\n`\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xdd`\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xbf`\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00" + + "\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x006" + + "2x\x10\x00\x00\x00\x006\xfd\u007f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00" + + "\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D" + + "%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00" + + "\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00R" + + "le\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00" + + "\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`" + + "_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00" + + "\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n" + + "\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00" + + "\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|" + + "\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x04\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x04\x05\x04\x05\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" + + "\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x00\x00\x18x\x00\x00\x00\x00\x18x\x00\x04\x00\x00*0\x01" + + "\b\x00\x00\x1c \x00\r\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x01\b\x00\x00\x1c \x00\rLMT\x00BMT\x00EEST\x00EET\x00\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x00" + + "\x00\x00\x01\x01\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc4NW\"Y\b\x00\x00Y\b\x00\x00" + + "\x11\x00\x1c\x00Europe/CopenhagenUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x85\x00\x00\x00\a\x00\x00\x00\r\x80\x00\x00\x00\x9b\x1e\x8c`\x9bվ\xd0\xc8CWp\xcc\xe7K\x10ͩ\x17\x90\u03a2C" + + "\x10ϒ4\x10Ђ%\x10\xd1r\x16\x10\xd2$\x10\x90\xd3y\x85\x10\xd4\x1b\xad\x90\xd5^\xad\x10\xd5\xdf\xe0\x10\xd7Gɐ\u05ff\xc2\x10\x13MD\x10\x143\xfa\x90\x15#\xeb\x90\x16\x13ܐ\x17\x03\xcd" + + "\x90\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849" + + "\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn" + + "\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec" + + "\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[" + + "\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xee\xd9" + + "\x90z\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x00\x00\v\xcc\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x0e\x10" + + "\x00\t\x00\x00\x1c \x01\x04\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x86\x00\x00\x00\b\x00\x00\x00\x11\xff\xff\xff\xffi\x86ϴ\xff\xff\xff\xffq\f\xef4\xff\xff\xff\xff\x9b\x1e\x8c`\xff\xff\xff\xff\x9b" + + "վ\xd0\xff\xff\xff\xff\xc8CWp\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff" + + "\xff\xff\xff\xd2$\x10\x90\xff\xff\xff\xff\xd3y\x85\x10\xff\xff\xff\xff\xd4\x1b\xad\x90\xff\xff\xff\xff\xd5^\xad\x10\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd7Gɐ\xff\xff\xff\xff\u05ff\xc2\x10\x00\x00\x00\x00\x13" + + "MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00" + + "\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!" + + "\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00" + + "\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K" + + "\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00" + + "\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y" + + "\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00" + + "\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g" + + "藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00" + + "\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v" + + "/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00" + + "\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" + + "\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" + + "\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x00\x00\v\xcc\x00\x00\x00\x00\v\xcc\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00" + + "\r\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x01\b\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00CMT\x00CEST\x00CET\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x01\x01\nC" + + "ET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPe\x8d\x0fgV\t\x00\x00V\t\x00\x00\x0f\x00\x1c\x00Euro" + + "pe/ChisinauUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x8d\x00\x00\x00\x10\x00\x00\x00&\x80\x00\x00\x00\x9ek\x9f\f\xb7\xb0\xd2\b\xb9>\xf3`\xb9\xef\x9c`\xbaߍ`\xbb\xcf~`\xbcȩླྀ\x9a\xe0\xbe" + + "\xa8\x8b࿘|\xe0\xc0\x88m\xe0\xc1x^\xe0\xc2hO\xe0\xc3X@\xe0\xc4H1\xe0\xc58\"\xe0\xc6(\x13\xe0\xc7\x18\x04\xe0ȼ\x93`\xcaw}P\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10\xcf" + + "\x924\x10\xd0N\x90`\x15'\xa7\xd0\x16\x18\xdc@\x17\b\xdbP\x17\xfa\x0f\xc0\x18\xea\x0e\xd0\x19\xdbC@\x1a̓\xd0\x1b\xbc\xa0\xf0\x1c\xac\x91\xf0\x1d\x9c\x82\xf0\x1e\x8cs\xf0\x1f|d\xf0 lU\xf0!" + + "\\F\xf0\"L7\xf0#<(\xf0$,\x19\xf0%\x1c\n\xf0&\v\xfb\xf0&CL\xe0'\x055\x80'\xf5&\x80(\xe5\x17\x80)\xd4\xec`*\xc4\xcfP+\xb4\xce`,\xa4\xb1P-\x94\xb0`." + + "\x84\x93P/t\x92`0duP1]\xae\xe02r{\xd03=\xad\x004R\x88\x005\x1d\x8f\x0062j\x006\xfdq\x008\x1b\x86\x808\xddS\x009\xfbh\x80:\xbd5\x00;\xdbJ\x80<" + + "\xa6Q\x80=\xbb,\x80>\x863\x80?\x9b\x0e\x80@f\x15\x80A\x84+\x00BE\xf7\x80Cd\r\x00D%ـEC\xef\x00F\x05\xbb\x80G#\xd1\x00G\xee\xd8\x00I\x03\xb3\x00Iκ\x00J" + + "\xe3\x95\x00K\xae\x9c\x00Ḻ\x80M\x8e~\x00N\xac\x93\x80On`\x00P\x8cu\x80QW|\x80RlW\x80S7^\x80TL9\x80U\x17@\x80V,\x1b\x80V\xf7\"\x80X\x158\x00X" + + "\xd7\x04\x80Y\xf5\x1a\x00Z\xb6\xe6\x80[\xd4\xfc\x00\\\xa0\x03\x00]\xb4\xde\x00^\u007f\xe5\x00_\x94\xc0\x00`_\xc7\x00a}܀b?\xa9\x00c]\xbe\x80d\x1f\x8b\x00e=\xa0\x80f\b\xa7\x80g" + + "\x1d\x82\x80g艀h\xfdd\x80i\xc8k\x80j\xddF\x80k\xa8M\x80l\xc6c\x00m\x88/\x80n\xa6E\x00oh\x11\x80p\x86'\x00qQ.\x00rf\t\x00s1\x10\x00tE\xeb\x00u" + + "\x10\xf2\x00v/\a\x80v\xf0\xd4\x00x\x0e\xe9\x80xж\x00y\xeeˀz\xb0\x98\x00{έ\x80|\x99\xb4\x80}\xae\x8f\x80~y\x96\x80\u007f\x8eq\x80\x01\x02\x05\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x06\t\a\b\a\b\v\n\v\n\v\n\v\n\f\r\f\r\f\r\f\r\f\r\f\r\x06\x04\x03\x04\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x00\x00\x1b\b\x00\x00\x00\x00\x1a\xf4\x00\x04\x00\x00\x18x\x00\b\x00\x00*0\x01\f\x00\x00\x1c \x00\x11\x00\x00\x1c \x00\x11\x00\x00*0\x01\f\x00\x00\x0e\x10\x00\x15\x00\x00\x1c " + + "\x01\x19\x00\x00\x1c \x01\x19\x00\x008@\x01\x1e\x00\x00*0\x00\"\x00\x00*0\x00\"\x00\x008@\x01\x1e\x00\x00*0\x01\f\x00\x00\x1c \x00\x11LMT\x00CMT\x00BMT\x00EEST" + + "\x00EET\x00CET\x00CEST\x00MSD\x00MSK\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x01\x01\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x8d\x00\x00\x00\x10\x00\x00\x00&\xff\xff\xff\xffV\xb6\xc8\xf8\xff\xff\xff\xff\x9ek\x9f\f\xff\xff\xff\xff\xb7\xb0\xd2\b\xff\xff\xff\xff\xb9>\xf3`\xff\xff\xff\xff\xb9\xef" + + "\x9c`\xff\xff\xff\xff\xbaߍ`\xff\xff\xff\xff\xbb\xcf~`\xff\xff\xff\xff\xbcȩ\xe0\xff\xff\xff\xff\xbd\xb8\x9a\xe0\xff\xff\xff\xff\xbe\xa8\x8b\xe0\xff\xff\xff\xff\xbf\x98|\xe0\xff\xff\xff\xff\xc0\x88m\xe0\xff\xff" + + "\xff\xff\xc1x^\xe0\xff\xff\xff\xff\xc2hO\xe0\xff\xff\xff\xff\xc3X@\xe0\xff\xff\xff\xff\xc4H1\xe0\xff\xff\xff\xff\xc58\"\xe0\xff\xff\xff\xff\xc6(\x13\xe0\xff\xff\xff\xff\xc7\x18\x04\xe0\xff\xff\xff\xffȼ" + + "\x93`\xff\xff\xff\xff\xcaw}P\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0N\x90`\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00" + + "\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac" + + "\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00" + + "\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00&CL\xe0\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd4" + + "\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00" + + "\x00\x001]\xae\xe0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x8f\x00\x00\x00\x00\x0062j\x00\x00\x00\x00\x006\xfdq\x00\x00\x00\x00\x008\x1b" + + "\x86\x80\x00\x00\x00\x008\xddS\x00\x00\x00\x00\x009\xfbh\x80\x00\x00\x00\x00:\xbd5\x00\x00\x00\x00\x00;\xdbJ\x80\x00\x00\x00\x00<\xa6Q\x80\x00\x00\x00\x00=\xbb,\x80\x00\x00\x00\x00>\x863\x80\x00\x00" + + "\x00\x00?\x9b\x0e\x80\x00\x00\x00\x00@f\x15\x80\x00\x00\x00\x00A\x84+\x00\x00\x00\x00\x00BE\xf7\x80\x00\x00\x00\x00Cd\r\x00\x00\x00\x00\x00D%ـ\x00\x00\x00\x00EC\xef\x00\x00\x00\x00\x00F\x05" + + "\xbb\x80\x00\x00\x00\x00G#\xd1\x00\x00\x00\x00\x00G\xee\xd8\x00\x00\x00\x00\x00I\x03\xb3\x00\x00\x00\x00\x00Iκ\x00\x00\x00\x00\x00J\xe3\x95\x00\x00\x00\x00\x00K\xae\x9c\x00\x00\x00\x00\x00Ḻ\x80\x00\x00" + + "\x00\x00M\x8e~\x00\x00\x00\x00\x00N\xac\x93\x80\x00\x00\x00\x00On`\x00\x00\x00\x00\x00P\x8cu\x80\x00\x00\x00\x00QW|\x80\x00\x00\x00\x00RlW\x80\x00\x00\x00\x00S7^\x80\x00\x00\x00\x00TL" + + "9\x80\x00\x00\x00\x00U\x17@\x80\x00\x00\x00\x00V,\x1b\x80\x00\x00\x00\x00V\xf7\"\x80\x00\x00\x00\x00X\x158\x00\x00\x00\x00\x00X\xd7\x04\x80\x00\x00\x00\x00Y\xf5\x1a\x00\x00\x00\x00\x00Z\xb6\xe6\x80\x00\x00" + + "\x00\x00[\xd4\xfc\x00\x00\x00\x00\x00\\\xa0\x03\x00\x00\x00\x00\x00]\xb4\xde\x00\x00\x00\x00\x00^\u007f\xe5\x00\x00\x00\x00\x00_\x94\xc0\x00\x00\x00\x00\x00`_\xc7\x00\x00\x00\x00\x00a}܀\x00\x00\x00\x00b?" + + "\xa9\x00\x00\x00\x00\x00c]\xbe\x80\x00\x00\x00\x00d\x1f\x8b\x00\x00\x00\x00\x00e=\xa0\x80\x00\x00\x00\x00f\b\xa7\x80\x00\x00\x00\x00g\x1d\x82\x80\x00\x00\x00\x00g艀\x00\x00\x00\x00h\xfdd\x80\x00\x00" + + "\x00\x00i\xc8k\x80\x00\x00\x00\x00j\xddF\x80\x00\x00\x00\x00k\xa8M\x80\x00\x00\x00\x00l\xc6c\x00\x00\x00\x00\x00m\x88/\x80\x00\x00\x00\x00n\xa6E\x00\x00\x00\x00\x00oh\x11\x80\x00\x00\x00\x00p\x86" + + "'\x00\x00\x00\x00\x00qQ.\x00\x00\x00\x00\x00rf\t\x00\x00\x00\x00\x00s1\x10\x00\x00\x00\x00\x00tE\xeb\x00\x00\x00\x00\x00u\x10\xf2\x00\x00\x00\x00\x00v/\a\x80\x00\x00\x00\x00v\xf0\xd4\x00\x00\x00" + + "\x00\x00x\x0e\xe9\x80\x00\x00\x00\x00xж\x00\x00\x00\x00\x00y\xeeˀ\x00\x00\x00\x00z\xb0\x98\x00\x00\x00\x00\x00{έ\x80\x00\x00\x00\x00|\x99\xb4\x80\x00\x00\x00\x00}\xae\x8f\x80\x00\x00\x00\x00~y" + + "\x96\x80\x00\x00\x00\x00\u007f\x8eq\x80\x01\x02\x05\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x06\t\a\b\a\b\v\n\v\n\v\n\v\n\f\r\f\r\f\r\f\r\f\r\f\r\x06\x04\x03\x04\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x00\x00\x1b\b\x00\x00\x00\x00\x1a\xf4\x00\x04\x00\x00\x18x\x00\b\x00\x00*0\x01\f\x00\x00\x1c \x00" + + "\x11\x00\x00\x1c \x00\x11\x00\x00*0\x01\f\x00\x00\x0e\x10\x00\x15\x00\x00\x1c \x01\x19\x00\x00\x1c \x01\x19\x00\x008@\x01\x1e\x00\x00*0\x00\"\x00\x00*0\x00\"\x00\x008@\x01\x1e\x00\x00*0\x01" + + "\f\x00\x00\x1c \x00\x11LMT\x00CMT\x00BMT\x00EEST\x00EET\x00CET\x00CEST\x00MSD\x00MSK\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x01\x01\x00" + + "\x00\nEET-2EEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf9\xe6\xa9\xc7l\a\x00\x00l\a\x00\x00\x10\x00\x1c\x00E" + + "urope/MariehamnUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00v\x00\x00\x00\x06\x00\x00\x00\x11\x80\x00\x00\x00\xa4so\x1b\xcb\xceQ`\xcc\xc0\xe5`\x15#݀\x16\x13\u0380\x17\x03\xbf\x80\x17\xf3\xb0\x80\x18" + + "㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90C" + + "d\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90Q" + + "W\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_" + + "\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m" + + "\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{" + + "λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x03\x02\x03\x02\x03\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x00\x00\x17e\x00\x00\x00\x00\x17e\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x01\b\x00\x00\x1c \x00\rLMT\x00HMT" + + "\x00EEST\x00EET\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00v\x00\x00" + + "\x00\x06\x00\x00\x00\x11\xff\xff\xff\xffS\xba&\x9b\xff\xff\xff\xff\xa4so\x1b\xff\xff\xff\xff\xcb\xceQ`\xff\xff\xff\xff\xcc\xc0\xe5`\x00\x00\x00\x00\x15#݀\x00\x00\x00\x00\x16\x13\u0380\x00\x00\x00\x00\x17\x03" + + "\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00" + + "\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x84" + + "9\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00" + + "\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00On" + + "n\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00" + + "\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4" + + "\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00" + + "\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8" + + "[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00" + + "\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xee" + + "ِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x03\x02\x03\x02\x03\x02\x03\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x00\x00\x17e\x00\x00\x00\x00\x17e\x00\x04" + + "\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x01\b\x00\x00\x1c \x00\rLMT\x00HMT\x00EEST\x00EET\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x01\x01\nEET-2E" + + "EST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPvȞN\x1d\b\x00\x00\x1d\b\x00\x00\f\x00\x1c\x00Europe/" + + "SofiaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00" + + "\t\x00\x00\x00\x00\x00\x00\x00}\x00\x00\x00\t\x00\x00\x00\x16\x80\x00\x00\x00\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10Ђ%\x10\xd1r$ \x11c\xefP\x12U?\xe0\x13M\v\xd0\x145!" + + "\xe0\x15,\xed\xd0\x16\x13\xc0p\x17\f\xcf\xd0\x17\xf3\xb0\x80\x18㡀\x19Ӓ\x80\x1aÃ\x80\x1b\xbc\xaf\x00\x1c\xac\xa0\x00\x1d\x9c\x91\x00\x1e\x8c\x82\x00\x1f|s\x00 ld\x00!\\U\x00\"LF" + + "\x00#<7\x00$,(\x00%\x1c\x19\x00&\f\n\x00'\x055\x80'\xf5\n`(\xe4\xedP)\xd4\xec`*\xc4\xcfP+\xb4\xce`,\xa4\xb1P-\x94\xb0`.\x84\x93P/t\x92`0du" + + "P1]\xae\xe02r{\xd03=\xbb\x104R\x96\x105\x1d\x9d\x1062x\x106\xfd\u007f\x108\x1b\x94\x908\xdda\x109\xfbv\x90:\xbdC\x10;\xdbX\x90<\xa6_\x90=\xbb:\x90>\x86A" + + "\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿" + + "\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4" + + "\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr" + + "\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2" + + "\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x02\x03\x02\x03\x02\x01\x04\x01\x04\x01\x04\x01\x04\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b" + + "\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\x00\x00\x15\xdc\x00\x00\x00\x00\x1c \x00\x04\x00\x00\x0e\x10\x00\b" + + "\x00\x00\x1c \x01\f\x00\x00*0\x01\x11\x00\x00\x1c \x00\x04\x00\x00*0\x01\x11\x00\x00*0\x01\x11\x00\x00\x1c \x00\x04LMT\x00EET\x00CET\x00CEST\x00EEST\x00\x00\x00" + + "\x01\x01\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00~\x00\x00\x00\n\x00\x00\x00\x1a" + + "\xff\xff\xff\xffV\xb6\xce$\xff\xff\xff\xffr\xc3\xe3\x18\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff" + + "\xd1r$ \x00\x00\x00\x00\x11c\xefP\x00\x00\x00\x00\x12U?\xe0\x00\x00\x00\x00\x13M\v\xd0\x00\x00\x00\x00\x145!\xe0\x00\x00\x00\x00\x15,\xed\xd0\x00\x00\x00\x00\x16\x13\xc0p\x00\x00\x00\x00\x17\f\xcf\xd0" + + "\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18㡀\x00\x00\x00\x00\x19Ӓ\x80\x00\x00\x00\x00\x1aÃ\x80\x00\x00\x00\x00\x1b\xbc\xaf\x00\x00\x00\x00\x00\x1c\xac\xa0\x00\x00\x00\x00\x00\x1d\x9c\x91\x00\x00\x00\x00\x00" + + "\x1e\x8c\x82\x00\x00\x00\x00\x00\x1f|s\x00\x00\x00\x00\x00 ld\x00\x00\x00\x00\x00!\\U\x00\x00\x00\x00\x00\"LF\x00\x00\x00\x00\x00#<7\x00\x00\x00\x00\x00$,(\x00\x00\x00\x00\x00%\x1c\x19\x00" + + "\x00\x00\x00\x00&\f\n\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00" + + ",\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\xbb\x10" + + "\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\u007f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00" + + ":\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10" + + "\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00" + + "I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10" + + "\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00" + + "V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10" + + "\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00" + + "e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90" + + "\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00" + + "s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ" + + "\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x02\x03\x04\x03\x04\x03\x02\x05\x02\x05\x02" + + "\x05\x02\x05\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t" + + "\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\x00\x00\x15\xdc\x00\x00" + + "\x00\x00\x1bh\x00\x04\x00\x00\x1c \x00\b\x00\x00\x0e\x10\x00\f\x00\x00\x1c \x01\x10\x00\x00*0\x01\x15\x00\x00\x1c \x00\b\x00\x00*0\x01\x15\x00\x00*0\x01\x15\x00\x00\x1c \x00\bLMT\x00IM" + + "T\x00EET\x00CET\x00CEST\x00EEST\x00\x00\x00\x00\x01\x01\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\nEET-2EEST,M3.5.0/3," + + "M10.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPRg\x93\xa8\xd6\b\x00\x00\xd6\b\x00\x00\r\x00\x1c\x00Europe/AthensUT\t\x00\x03n\xd3" + + "\xa7^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x8a\x00\x00\x00" + + "\n\x00\x00\x00\x1a\x80\x00\x00\x00\x9b\x80!\x80\xb9|\xe9\xe0\xb9Ư\xd0\xc9\xf2c\xe0\xca\x10\xa8P\xcc\xe7K\x10ͪL\xf0\u03a2\x18\xe0ϓip\xdf\x13\x9e`߷\nP\t\xec^`\v\x18\xf4" + + "`\vͮ\x00\f\xbd\x9f\x00\r\xa4U\x80\x0e\x8c]\x80\x0f\x847\x80\x10j\xfc\x10\x11d{\xf0\x12R\xaa\xf0\x13F\x82`\x143\xc2P\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18\xe3\xaf" + + "\x90\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b" + + "\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a" + + "\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce" + + "\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=" + + "\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ" + + "\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x03\x02\x03\x02\x05\x04\x05\x04\x03\x02\x03\x06\a\x06\a\x06\a\x06\x03\x02\x03\x02\x03\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b" + + "\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b" + + "\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\x00\x00\x16<\x00\x00\x00\x00\x16<\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00" + + "\x00\x0e\x10\x00\x11\x00\x00\x1c \x01\x15\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x01\b\x00\x00\x1c \x00\rLMT\x00AMT\x00EEST\x00EET\x00CET\x00CEST" + + "\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x8a\x00\x00\x00" + + "\n\x00\x00\x00\x1a\xff\xff\xff\xfft?\x98D\xff\xff\xff\xff\x9b\x80!\x80\xff\xff\xff\xff\xb9|\xe9\xe0\xff\xff\xff\xff\xb9Ư\xd0\xff\xff\xff\xff\xc9\xf2c\xe0\xff\xff\xff\xff\xca\x10\xa8P\xff\xff\xff\xff\xcc\xe7K" + + "\x10\xff\xff\xff\xffͪL\xf0\xff\xff\xff\xff\u03a2\x18\xe0\xff\xff\xff\xffϓip\xff\xff\xff\xff\xdf\x13\x9e`\xff\xff\xff\xff߷\nP\x00\x00\x00\x00\t\xec^`\x00\x00\x00\x00\v\x18\xf4`\x00\x00\x00" + + "\x00\vͮ\x00\x00\x00\x00\x00\f\xbd\x9f\x00\x00\x00\x00\x00\r\xa4U\x80\x00\x00\x00\x00\x0e\x8c]\x80\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10j\xfc\x10\x00\x00\x00\x00\x11d{\xf0\x00\x00\x00\x00\x12R\xaa" + + "\xf0\x00\x00\x00\x00\x13F\x82`\x00\x00\x00\x00\x143\xc2P\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00" + + "\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr" + + "\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00" + + "\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3" + + "\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00" + + "\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12" + + "\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00" + + "\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90" + + "\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00" + + "\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00" + + "\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00" + + "\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x03\x02\x03\x02\x05\x04\x05\x04\x03\x02\x03\x06\a\x06\a\x06\a\x06\x03\x02\x03\x02\x03\b\t\b\t\b\t\b" + + "\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b" + + "\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\x00\x00\x16<\x00\x00\x00\x00\x16<\x00\x04\x00" + + "\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00\x0e\x10\x00\x11\x00\x00\x1c \x01\x15\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x01\b\x00\x00\x1c \x00\rLMT\x00AMT\x00EEST\x00" + + "EET\x00CET\x00CEST\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\nEET-2EEST,M3.5.0/3,M10.5.0" + + "/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPr\xe7\x92\x17u\a\x00\x00u\a\x00\x00\x10\x00\x1c\x00Europe/StockholmUT\t\x00\x03nӧ^n\xd3" + + "\xa7^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00w\x00\x00\x00\x05\x00\x00\x00" + + "\r\x80\x00\x00\x00\x9b\x1e\x8c`\x9b\xd5\xda\xf0\x13MD\x10\x143\xfa\x90\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f" + + "\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6" + + "\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)" + + "\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99" + + "\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17" + + "\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x02\x01" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x10\xec" + + "\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\b\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\x04LMT\x00CET\x00CEST\x00\x00\x00\x00\x01\x01\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00x\x00\x00\x00\x06\x00\x00\x00\x11\xff\xff\xff\xffT՟\x94\xff\xff\xff\xff|Usb\xff\xff\xff\xff\x9b\x1e\x8c`\xff\xff\xff" + + "\xff\x9b\xd5\xda\xf0\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf" + + "\x90\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00" + + "\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b" + + "\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00" + + "\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a" + + "\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00" + + "\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce" + + "\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00" + + "\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=" + + "\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00" + + "\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ" + + "\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x00\x00\x10\xec\x00\x00\x00\x00\x0e\x1e\x00\x04\x00\x00\x0e\x10\x00\b\x00\x00\x1c \x01\f\x00\x00\x1c" + + " \x01\f\x00\x00\x0e\x10\x00\bLMT\x00SET\x00CET\x00CEST\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M10." + + "5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x98_{t\xbf\x04\x00\x00\xbf\x04\x00\x00\r\x00\x1c\x00Europe/SamaraUT\t\x00\x03nӧ^n\xd3" + + "\xa7^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x00\v\x00\x00\x00" + + "\x10\xa1\x009\x80\xb5\xa4\vP\x15'\x99\xc0\x16\x18\xce0\x17\b\xcd@\x17\xfa\x01\xb0\x18\xea\x00\xc0\x19\xdb50\x1a̅\xc0\x1b\xbc\x92\xe0\x1c\xac\x83\xe0\x1d\x9ct\xe0\x1e\x8ce\xe0\x1f|V\xe0 lG" + + "\xe0!\\8\xe0\"L)\xe0#<\x1a\xe0$,\v\xe0%\x1c\n\xf0&\v\xfb\xf0'\x05'p'\xf5\x18p(\xe5\x17\x80)\x00\xc7\x00)\xd4\xec`*\xc4\xdd`+\xb4\xce`,\xa4\xbf`-\x94\xb0" + + "`.\x84\xa1`/t\x92`0d\x83`1]\xae\xe02r\x89\xe03=\x90\xe04Rk\xe05\x1dr\xe062M\xe06\xfdT\xe08\x1bj`8\xdd6\xe09\xfbL`:\xbd\x18\xe0;\xdb." + + "`<\xa65`=\xbb\x10`>\x86\x17`?\x9a\xf2`@e\xf9`A\x84\x0e\xe0BE\xdb`Cc\xf0\xe0D%\xbd`EC\xd2\xe0F\x05\x9f`G#\xb4\xe0G\xee\xbb\xe0I\x03\x96\xe0IΝ" + + "\xe0J\xe3x\xe0K\xae\u007f\xe0ḶpM\x8eo\xf0\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x06\a\b\a\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x04\x00\x00.\xf4\x00\x00\x00\x00*0\x00\x04\x00\x008@\x00\b\x00\x00FP\x01\f\x00\x008@\x00\b\x00\x00FP" + + "\x01\f\x00\x008@\x01\b\x00\x00*0\x00\x04\x00\x00*0\x01\x04\x00\x008@\x01\b\x00\x008@\x00\bLMT\x00+03\x00+04\x00+05\x00\x00\x01\x00\x00\x01\x01\x01\x01\x01\x01\x01\x00" + + "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x00\v\x00\x00\x00\x10\xff\xff\xff\xff\xa1\x00" + + "9\x80\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00" + + "\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\" + + "8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00" + + "\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\x00\xc7\x00\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xdd`\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xbf`\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84" + + "\xa1`\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000d\x83`\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r\x89\xe0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004Rk\xe0\x00\x00\x00\x005\x1dr\xe0\x00\x00" + + "\x00\x0062M\xe0\x00\x00\x00\x006\xfdT\xe0\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`\x00\x00\x00\x00<\xa6" + + "5`\x00\x00\x00\x00=\xbb\x10`\x00\x00\x00\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0\x00\x00\x00\x00BE\xdb`\x00\x00\x00\x00Cc\xf0\xe0\x00\x00" + + "\x00\x00D%\xbd`\x00\x00\x00\x00EC\xd2\xe0\x00\x00\x00\x00F\x05\x9f`\x00\x00\x00\x00G#\xb4\xe0\x00\x00\x00\x00G\xee\xbb\xe0\x00\x00\x00\x00I\x03\x96\xe0\x00\x00\x00\x00IΝ\xe0\x00\x00\x00\x00J\xe3" + + "x\xe0\x00\x00\x00\x00K\xae\u007f\xe0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x06\a\b\a\x02\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\a\x04\x04\x00\x00.\xf4\x00\x00\x00\x00*0\x00\x04\x00\x008@\x00\b\x00\x00F" + + "P\x01\f\x00\x008@\x00\b\x00\x00FP\x01\f\x00\x008@\x01\b\x00\x00*0\x00\x04\x00\x00*0\x01\x04\x00\x008@\x01\b\x00\x008@\x00\bLMT\x00+03\x00+04\x00+05" + + "\x00\x00\x01\x00\x00\x01\x01\x01\x01\x01\x01\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\n<+04>-4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPaت\xdcu\v\x00\x00u\v\x00\x00\x0f\x00" + + "\x1c\x00Europe/BrusselsUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\xb8\x00\x00\x00\v\x00\x00\x00\x16\x80\x00\x00\x00\x98DI\x80\x9b\f%p\x9b\xd5\xda\xf0\x9cٮ\x90\x9d\xa4\xb5\x90\x9e\xb9\x90\x90\x9f\x84\x97" + + "\x90\x9f\xce\xf80\xa0`\xa5\xf0\xa1~\xbbp\xa2.\x12\xf0\xa3zL\xf0\xa45\x81\xf0\xa5^#p\xa6%5\xf0\xa7'\x9b\xf0\xa8*\x01\xf0\xa9\a}\xf0\xa9\xee4p\xaa\xe7_\xf0\xab\xd7P\xf0\xac\xc7A" + + "\xf0\xadɧ\xf0\xae\xa7#\xf0\xaf\xa0Op\xb0\x87\x05\xf0\xb1\x89k\xf0\xb2pL\xa0\xb3r\xb2\xa0\xb4P.\xa0\xb5IZ \xb60\x10\xa0\xb72v\xa0\xb8\x0f\xf2\xa0\xb8\xff㠹\xefԠ\xba\u058b" + + " \xbb\xd8\xf1 \xbc\xc8\xe2 \xbd\xb8\xd3 \xbe\x9f\x89\xa0\xbf\x98\xb5 \xc0\x9b\x1b \xc1x\x97 \xc2h\x88 \xc3Xy \xc4?/\xa0\xc58[ \xc6:\xc1 \xc7X֠\xc7\xda\t\xa0\xc8J\x19" + + " \xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10\xd0n^\x90\xd1r\x16\x10\xd2N@\x90ӑ@\x10\xd4K#\x90\r\xa4c\x90\x0e\x8b\x1a\x10\x0f\x84E\x90\x10t6\x90\x11d'\x90\x12T\x18" + + "\x90\x13MD\x10\x143\xfa\x90\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr" + + "\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3" + + "\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12" + + "\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90" + + "\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00" + + "\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x02\x05\x02\x03\x04\x03\x04\b\x06\a\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\t\n\t\n\t\n\t\n\t\n\t\n\t" + + "\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t" + + "\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\x00\x00\x04\x1a\x00\x00\x00\x00\x00\x00\x00" + + "\x04\x00\x00\x0e\x10\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x01\x11\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x04\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\bLMT\x00W" + + "ET\x00CET\x00CEST\x00WEST\x00\x00\x00\x00\x01\x01\x00\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\f\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\xb9\x00\x00\x00\f\x00\x00\x00\x1a\xff\xff\xff\xffV\xb6\xdf\xe6\xff\xff\xff\xffm\xe8\xc8\x00\xff\xff\xff\xff\x98DI\x80\xff\xff\xff\xff\x9b\f%p\xff\xff\xff\xff\x9b" + + "\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\x9f\xce\xf80\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xbbp\xff" + + "\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45\x81\xf0\xff\xff\xff\xff\xa5^#p\xff\xff\xff\xff\xa6%5\xf0\xff\xff\xff\xff\xa7'\x9b\xf0\xff\xff\xff\xff\xa8*\x01\xf0\xff\xff\xff\xff\xa9" + + "\a}\xf0\xff\xff\xff\xff\xa9\xee4p\xff\xff\xff\xff\xaa\xe7_\xf0\xff\xff\xff\xff\xab\xd7P\xf0\xff\xff\xff\xff\xac\xc7A\xf0\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff" + + "\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb7" + + "2v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb8\xff\xe3\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\u058b \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xc8\xe2 \xff\xff\xff\xff\xbd\xb8\xd3 \xff" + + "\xff\xff\xff\xbe\x9f\x89\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2h\x88 \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4?/\xa0\xff\xff\xff\xff\xc5" + + "8[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xc8J\x19 \xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff" + + "\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\xff\xff\xff\xffӑ@\x10\xff\xff\xff\xff\xd4K#\x90\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e" + + "\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00" + + "\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c" + + "\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00" + + "\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G" + + "#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00" + + "\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U" + + "\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00" + + "\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c" + + "]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00" + + "\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00q" + + "Q<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00" + + "\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f" + + "\x8e\u007f\x90\x01\x02\x03\x06\x03\x04\x05\x04\x05\t\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v" + + "\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v" + + "\n\v\n\v\n\v\n\v\x00\x00\x04\x1a\x00\x00\x00\x00\x04\x1a\x00\x04\x00\x00\x00\x00\x00\b\x00\x00\x0e\x10\x00\f\x00\x00\x1c \x01\x10\x00\x00\x0e\x10\x00\f\x00\x00\x1c \x01\x10\x00\x00\x0e\x10\x01\x15\x00\x00\x00\x00" + + "\x00\b\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\x10\x00\x00\x0e\x10\x00\fLMT\x00BMT\x00WET\x00CET\x00CEST\x00WEST\x00\x00\x00\x00\x00\x01\x01\x00\x01\x01\x01\x01\x01\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa5\xb8\xb6C^\n\x00\x00" + + "^\n\x00\x00\r\x00\x1c\x00Europe/WarsawUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\xa5\x00\x00\x00\v\x00\x00\x00\x1a\x80\x00\x00\x00\x99\xa8*Л\f\x17`\x9b\xd5\xda\xf0\x9cٮ\x90\x9d\xa4\xb5\x90\x9e\xb9\x90" + + "\x90\x9f\x84\x97\x90\xa0\x9a\xb6\x00\xa1e\xbd\x00\xa6}|`\xc8v\xde\x10\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10Є\xba\x00ѕ\x92pҊ\xbb`\xd3b\xffp\xd4K#\x90\xd5^\xad" + + "\x10\xd6)\xb4\x10\xd7,\x1a\x10\xd8\t\x96\x10\xd9\x02\xc1\x90\xd9\xe9x\x10\xe8T\xd2\x00\xe8\xf1\xb4\x80\xe9᥀\xeaі\x80\xec\x14\x96\x00캳\x00\xed\xaa\xa4\x00\ue695\x00\xef\xd4Z\x00\xf0zw" + + "\x00\xf1\xb4<\x00\xf2ZY\x00\xf3\x94\x1e\x00\xf4:;\x00\xf5}:\x80\xf6\x1a\x1d\x00\r\xa4U\x80\x0e\x8b\f\x00\x0f\x847\x80\x10t(\x80\x11d\x19\x80\x12T\n\x80\x13M6\x00\x143\xec\x80\x15#\xdd" + + "\x80\x16\x13\u0380\x17\x03\xbf\x80\x17\xf3\xb0\x80\x18㡀\x19Ӓ\x80\x1aÃ\x80\x1b\xbc\xaf\x00\x1c\xac\xa0\x00\x1d\x9c\x91\x00\x1e\x8c\x82\x00\x1f|s\x00 ld\x00!\\U\x00\"LT\x10#\x86A\x90?\x9b\x1c" + + "\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c" + + "\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n" + + "\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y" + + "\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7" + + "\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x03\x02\x03\x04\x05\x04\b\x06\a\x03\x02\x05\x04\x05\x04\x03\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n" + + "\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n" + + "\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\x00\x00\x13\xb0\x00\x00\x00\x00\x13\xb0\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00*0\x01\x11" + + "\x00\x00\x1c \x00\x16\x00\x00\x1c \x00\x16\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00WMT\x00CEST\x00CET\x00EEST\x00EET\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x01" + + "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\xa5\x00\x00\x00\v\x00\x00\x00\x1a\xff\xff\xff\xff" + + "V\xb6\xd0P\xff\xff\xff\xff\x99\xa8*\xd0\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90" + + "\xff\xff\xff\xff\xa0\x9a\xb6\x00\xff\xff\xff\xff\xa1e\xbd\x00\xff\xff\xff\xff\xa6}|`\xff\xff\xff\xff\xc8v\xde\x10\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xff" + + "ϒ4\x10\xff\xff\xff\xffЄ\xba\x00\xff\xff\xff\xffѕ\x92p\xff\xff\xff\xffҊ\xbb`\xff\xff\xff\xff\xd3b\xffp\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd5^\xad\x10\xff\xff\xff\xff\xd6)\xb4\x10" + + "\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\xff\xff\xff\xff\xe8T\xd2\x00\xff\xff\xff\xff\xe8\xf1\xb4\x80\xff\xff\xff\xff\xe9᥀\xff\xff\xff\xff" + + "\xeaі\x80\xff\xff\xff\xff\xec\x14\x96\x00\xff\xff\xff\xff캳\x00\xff\xff\xff\xff\xed\xaa\xa4\x00\xff\xff\xff\xff\ue695\x00\xff\xff\xff\xff\xef\xd4Z\x00\xff\xff\xff\xff\xf0zw\x00\xff\xff\xff\xff\xf1\xb4<\x00" + + "\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3\x94\x1e\x00\xff\xff\xff\xff\xf4:;\x00\xff\xff\xff\xff\xf5}:\x80\xff\xff\xff\xff\xf6\x1a\x1d\x00\x00\x00\x00\x00\r\xa4U\x80\x00\x00\x00\x00\x0e\x8b\f\x00\x00\x00\x00\x00" + + "\x0f\x847\x80\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11d\x19\x80\x00\x00\x00\x00\x12T\n\x80\x00\x00\x00\x00\x13M6\x00\x00\x00\x00\x00\x143\xec\x80\x00\x00\x00\x00\x15#݀\x00\x00\x00\x00\x16\x13\u0380" + + "\x00\x00\x00\x00\x17\x03\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18㡀\x00\x00\x00\x00\x19Ӓ\x80\x00\x00\x00\x00\x1aÃ\x80\x00\x00\x00\x00\x1b\xbc\xaf\x00\x00\x00\x00\x00\x1c\xac\xa0\x00\x00\x00\x00\x00" + + "\x1d\x9c\x91\x00\x00\x00\x00\x00\x1e\x8c\x82\x00\x00\x00\x00\x00\x1f|s\x00\x00\x00\x00\x00 ld\x00\x00\x00\x00\x00!\\U\x00\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90" + + "\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00" + + "G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90" + + "\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00" + + "V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10" + + "\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00" + + "d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90" + + "\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00" + + "rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10" + + "\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x03\x02\x03" + + "\x04\x05\x04\b\x06\a\x03\x02\x05\x04\x05\x04\x03\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t" + + "\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\x00\x00\x13\xb0\x00\x00\x00\x00\x13\xb0\x00\x04\x00\x00\x1c \x01\b\x00" + + "\x00\x0e\x10\x00\r\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00*0\x01\x11\x00\x00\x1c \x00\x16\x00\x00\x1c \x00\x16\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00WMT\x00CEST\x00" + + "CET\x00EEST\x00EET\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M10.5.0" + + "/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe9\x10\x19\xb7t\x00\x00\x00t\x00\x00\x00\a\x00\x1c\x00FactoryUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5" + + "\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00-0" + + "0\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00-00\x00\n<-0" + + "0>0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa5\xa2\x06\xaf@\x0e\x00\x00@\x0e\x00\x00\x02\x00\x1c\x00GBUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04" + + "\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xf2\x00\x00\x00\a\x00\x00\x00\x11\x80\x00\x00\x00\x9b&\xad\xa0\x9b\xd6\x05 " + + "\x9c\xcf0\xa0\x9d\xa4à\x9e\x9c\x9d\xa0\x9f\x97\x1a\xa0\xa0\x85\xba \xa1v\xfc\xa0\xa2e\x9c \xa3{Ƞ\xa4N\xb8\xa0\xa5?\xfb \xa6%` \xa7'\xc6 \xa8*, \xa8\xeb\xf8\xa0\xaa\x00Ӡ" + + "\xaa\xd5\x15 \xab\xe9\xf0 \xac\xc7l \xad\xc9\xd2 \xae\xa7N \xaf\xa0y\xa0\xb0\x870 \xb1\x92Р\xb2pL\xa0\xb3r\xb2\xa0\xb4P.\xa0\xb5IZ \xb60\x10\xa0\xb72v\xa0\xb8\x0f\xf2\xa0" + + "\xb9\x12X\xa0\xb9\xefԠ\xba\xe9\x00 \xbb\xd8\xf1 \xbc\xdbW \xbd\xb8\xd3 \xbe\xb1\xfe\xa0\xbf\x98\xb5 \xc0\x9b\x1b \xc1x\x97 \xc2z\xfd \xc3Xy \xc4Q\xa4\xa0\xc58[ \xc6:\xc1 " + + "\xc7X֠\xc7\xda\t\xa0\xca\x16&\x90ʗY\x90\xcb\xd1\x1e\x90\xccw;\x90ͱ\x00\x90\xce`X\x10ϐ\xe2\x90\xd0n^\x90\xd1r\x16\x10\xd1\xfb2\x10\xd2i\xfe \xd3c)\xa0\xd4I\xe0 " + + "\xd5\x1e!\xa0\xd5B\xfd\x90\xd5\xdf\xe0\x10\xd6N\xac \xd6\xfe\x03\xa0\xd8.\x8e \xd8\xf9\x95 \xda\x0ep \xda\xeb\xec \xdb\xe5\x17\xa0\xdc\xcb\xce \xdd\xc4\xf9\xa0\u07b4\xea\xa0߮\x16 \xe0\x94̠" + + "\xe1rH\xa0\xe2kt \xe3R*\xa0\xe4T\x90\xa0\xe52\f\xa0\xe6=\xad \xe7\x1b) \xe8\x14T\xa0\xe8\xfb\v \xe9\xfdq \xea\xda\xed \xeb\xddS \xec\xba\xcf \xed\xb3\xfa\xa0\ue6b1 " + + "\xef\x81g\xa0\xf0\x9f} \xf1aI\xa0\xf2\u007f_ \xf3Jf \xf4_A \xf5!\r\xa0\xf6?# \xf7\x00\xef\xa0\xf8\x1f\x05 \xf8\xe0Ѡ\xf9\xfe\xe7 \xfa\xc0\xb3\xa0\xfb\xe8\x03\xa0\xfc{\xab\xa0" + + "\xfdǻp\x03p\xc6 \x04)X \x05P\xa8 \x06\t: \a0\x8a \a\xe9\x1c \t\x10l \t\xc8\xfe \n\xf0N \v\xb2\x1a\xa0\f\xd00 \r\x91\xfc\xa0\x0e\xb0\x12 \x0fqޠ" + + "\x10\x99.\xa0\x11Q\xc0\xa0\x12y\x10\xa0\x131\xa2\xa0\x14X\xf2\xa0\x15#\xeb\x90\x168Ɛ\x17\x03͐\x18\x18\xa8\x90\x18㯐\x19\xf8\x8a\x90\x1aÑ\x90\x1b\xe1\xa7\x10\x1c\xac\xae\x10\x1d\xc1\x89\x10" + + "\x1e\x8c\x90\x10\x1f\xa1k\x10 lr\x10!\x81M\x10\"LT\x10#a/\x10$,6\x10%JK\x90&\f\x18\x10'*-\x90'\xf54\x90)\n\x0f\x90)\xd5\x16\x90*\xe9\xf1\x90+\xb4\xf8\x90" + + ",\xc9Ӑ-\x94ڐ.\xa9\xb5\x90/t\xbc\x900\x89\x97\x901]\xd9\x102r\xb4\x103=\xbb\x104R\x96\x105\x1d\x9d\x1062x\x106\xfd\u007f\x108\x1b\x94\x908\xdda\x109\xfbv\x90" + + ":\xbdC\x10;\xdbX\x90<\xa6_\x90=\xbb:\x90>\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10" + + "I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90" + + "V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10" + + "e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10" + + "s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01" + + "\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x06\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff" + + "\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\bLMT\x00BST\x00GMT\x00BDST\x00\x00\x01\x01" + + "\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xf2\x00\x00\x00\a\x00\x00\x00\x11\xff\xff\xff\xff\x1a" + + "]\t\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff" + + "\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8" + + "*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff" + + "\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb6" + + "0\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff" + + "\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4" + + "Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff" + + "\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2" + + "i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff" + + "\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\xde" + + "\xb4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff" + + "\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec" + + "\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\u007f_ \xff\xff\xff\xff\xf3Jf \xff" + + "\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa" + + "\xc0\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfdǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00" + + "\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r" + + "\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\x00\x00\x00\x00\x10\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00" + + "\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x168Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b" + + "\xe1\xa7\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00" + + "\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)" + + "\xd5\x16\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xc9Ӑ\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00" + + "\x00\x00\x001]\xd9\x10\x00\x00\x00\x002r\xb4\x10\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\u007f\x10\x00\x00\x00\x008" + + "\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00" + + "\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F" + + "\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00" + + "\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00T" + + "LG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00" + + "\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b" + + "?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00" + + "\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p" + + "\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00" + + "\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~" + + "y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04" + + "\x06\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\bLMT\x00B" + + "ST\x00GMT\x00BDST\x00\x00\x01\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01\nGMT0BST,M3.5.0/1,M10.5.0\nPK\x03\x04\n\x00\x00\x00" + + "\x00\x00\xf5F\x9cP\xa5\xa2\x06\xaf@\x0e\x00\x00@\x0e\x00\x00\a\x00\x1c\x00GB-EireUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZi" + + "f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xf2\x00\x00\x00\a\x00\x00\x00\x11\x80\x00\x00\x00\x9b&\xad\xa0\x9b\xd6\x05 \x9c\xcf0\xa0\x9d\xa4\xc3" + + "\xa0\x9e\x9c\x9d\xa0\x9f\x97\x1a\xa0\xa0\x85\xba \xa1v\xfc\xa0\xa2e\x9c \xa3{Ƞ\xa4N\xb8\xa0\xa5?\xfb \xa6%` \xa7'\xc6 \xa8*, \xa8\xeb\xf8\xa0\xaa\x00Ӡ\xaa\xd5\x15 \xab\xe9\xf0" + + " \xac\xc7l \xad\xc9\xd2 \xae\xa7N \xaf\xa0y\xa0\xb0\x870 \xb1\x92Р\xb2pL\xa0\xb3r\xb2\xa0\xb4P.\xa0\xb5IZ \xb60\x10\xa0\xb72v\xa0\xb8\x0f\xf2\xa0\xb9\x12X\xa0\xb9\xef\xd4" + + "\xa0\xba\xe9\x00 \xbb\xd8\xf1 \xbc\xdbW \xbd\xb8\xd3 \xbe\xb1\xfe\xa0\xbf\x98\xb5 \xc0\x9b\x1b \xc1x\x97 \xc2z\xfd \xc3Xy \xc4Q\xa4\xa0\xc58[ \xc6:\xc1 \xc7X֠\xc7\xda\t" + + "\xa0\xca\x16&\x90ʗY\x90\xcb\xd1\x1e\x90\xccw;\x90ͱ\x00\x90\xce`X\x10ϐ\xe2\x90\xd0n^\x90\xd1r\x16\x10\xd1\xfb2\x10\xd2i\xfe \xd3c)\xa0\xd4I\xe0 \xd5\x1e!\xa0\xd5B\xfd" + + "\x90\xd5\xdf\xe0\x10\xd6N\xac \xd6\xfe\x03\xa0\xd8.\x8e \xd8\xf9\x95 \xda\x0ep \xda\xeb\xec \xdb\xe5\x17\xa0\xdc\xcb\xce \xdd\xc4\xf9\xa0\u07b4\xea\xa0߮\x16 \xe0\x94̠\xe1rH\xa0\xe2kt" + + " \xe3R*\xa0\xe4T\x90\xa0\xe52\f\xa0\xe6=\xad \xe7\x1b) \xe8\x14T\xa0\xe8\xfb\v \xe9\xfdq \xea\xda\xed \xeb\xddS \xec\xba\xcf \xed\xb3\xfa\xa0\ue6b1 \xef\x81g\xa0\xf0\x9f}" + + " \xf1aI\xa0\xf2\u007f_ \xf3Jf \xf4_A \xf5!\r\xa0\xf6?# \xf7\x00\xef\xa0\xf8\x1f\x05 \xf8\xe0Ѡ\xf9\xfe\xe7 \xfa\xc0\xb3\xa0\xfb\xe8\x03\xa0\xfc{\xab\xa0\xfdǻp\x03p\xc6" + + " \x04)X \x05P\xa8 \x06\t: \a0\x8a \a\xe9\x1c \t\x10l \t\xc8\xfe \n\xf0N \v\xb2\x1a\xa0\f\xd00 \r\x91\xfc\xa0\x0e\xb0\x12 \x0fqޠ\x10\x99.\xa0\x11Q\xc0" + + "\xa0\x12y\x10\xa0\x131\xa2\xa0\x14X\xf2\xa0\x15#\xeb\x90\x168Ɛ\x17\x03͐\x18\x18\xa8\x90\x18㯐\x19\xf8\x8a\x90\x1aÑ\x90\x1b\xe1\xa7\x10\x1c\xac\xae\x10\x1d\xc1\x89\x10\x1e\x8c\x90\x10\x1f\xa1k" + + "\x10 lr\x10!\x81M\x10\"LT\x10#a/\x10$,6\x10%JK\x90&\f\x18\x10'*-\x90'\xf54\x90)\n\x0f\x90)\xd5\x16\x90*\xe9\xf1\x90+\xb4\xf8\x90,\xc9Ӑ-\x94\xda" + + "\x90.\xa9\xb5\x90/t\xbc\x900\x89\x97\x901]\xd9\x102r\xb4\x103=\xbb\x104R\x96\x105\x1d\x9d\x1062x\x106\xfd\u007f\x108\x1b\x94\x908\xdda\x109\xfbv\x90:\xbdC\x10;\xdbX" + + "\x90<\xa6_\x90=\xbb:\x90>\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8" + + "\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F" + + "\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5" + + "\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9" + + "\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x06\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xff\xb5\x00\x00\x00\x00\x0e" + + "\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\bLMT\x00BST\x00GMT\x00BDST\x00\x00\x01\x01\x01\x00\x01\x01\x00\x00\x00" + + "\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xf2\x00\x00\x00\a\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff" + + "\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0" + + "\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff" + + "\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0" + + "\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff" + + "\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 " + + "\xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff" + + "\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90" + + "\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff" + + "\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e " + + "\xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff" + + "߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad " + + "\xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff" + + "\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\u007f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A " + + "\xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff\xff\xff\xff" + + "\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfdǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a " + + "\x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00" + + "\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\x00\x00\x00\x00\x10\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15#\xeb\x90" + + "\x00\x00\x00\x00\x168Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00\x00\x00\x00" + + "\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10" + + "\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00" + + "*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xc9Ӑ\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00\x00\x001]\xd9\x10" + + "\x00\x00\x00\x002r\xb4\x10\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\u007f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x00" + + "8\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90" + + "\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00" + + "G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10" + + "\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00" + + "U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10" + + "\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00" + + "c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90" + + "\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00" + + "qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90" + + "\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00" + + "\u007f\x8e\u007f\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01" + + "\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x06\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\bLMT\x00BST\x00GMT\x00" + + "BDST\x00\x00\x01\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01\nGMT0BST,M3.5.0/1,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa6" + + "4^\xabr\x00\x00\x00r\x00\x00\x00\x03\x00\x1c\x00GMTUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa64^\xabr\x00" + + "\x00\x00r\x00\x00\x00\x05\x00\x1c\x00GMT+0UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa64^\xabr\x00\x00\x00r" + + "\x00\x00\x00\x05\x00\x1c\x00GMT-0UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa64^\xabr\x00\x00\x00r\x00\x00\x00" + + "\x04\x00\x1c\x00GMT0UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa64^\xabr\x00\x00\x00r\x00\x00\x00\t\x00\x1c\x00" + + "GreenwichUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x91\x12\x12Cs\x00\x00\x00s\x00\x00\x00\x03\x00\x1c" + + "\x00HSTUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xffs`\x00\x00HST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xffs`\x00\x00HST\x00\nHST10\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf5Dk\x8d\xb3\x04\x00\x00\xb3\x04\x00\x00\b\x00\x1c\x00Hon" + + "gkongUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\a\x00\x00\x00\x00\x00\x00\x00E\x00\x00\x00\a\x00\x00\x00\x16\x85ic\x90\xcaM10\xcaۓ0\xcbKqxҠސ\xd3k׀ԓX\xb8\xd5B\xb08\xd6s:\xb8\xd7>A\xb8\xd8.2" + + "\xb8\xd8\xf99\xb8\xda\x0e\x14\xb8\xda\xd9\x1b\xb8\xdb\xed\xf6\xb8ܸ\xfd\xb8\xdd\xcdظޢ\x1a8߶\xf58\xe0\x81\xfc8\xe1\x96\xc9(\xe2Oi8\xe3v\xab(\xe4/K8\xe5_Ǩ\xe6\x0f-" + + "8\xe7?\xa9\xa8\xe7\xf8I\xb8\xe9\x1f\x8b\xa8\xe9\xd8+\xb8\xea\xffm\xa8\xeb\xb8\r\xb8\xec\xdfO\xa8\xed\x97\xef\xb8\xee\xc8l(\xefwѸ\xf0\xa8N(\xf1W\xb3\xb8\xf2\x880(\xf3@\xd08\xf4h\x12" + + "(\xf5 \xb28\xf6G\xf4(\xf7%~8\xf8\x15a(\xf9\x05`8\xf9\xf5C(\xfa\xe5B8\xfb\xde_\xa8\xfc\xce^\xb8\xfd\xbeA\xa8\xfe\xae@\xb8\xff\x9e#\xa8\x00\x8e\"\xb8\x01~\x05\xa8\x02n\x04" + + "\xb8\x03]\xe7\xa8\x04M\xe6\xb8\x05G\x04(\x067\x038\a&\xe6(\a\x83=8\t\x06\xc8(\t\xf6\xc78\n\xe6\xaa(\v֩8\fƌ(\x11\x9b98\x12ol\xa8\x01\x02\x03\x04\x01\x02\x05" + + "\x06\x05\x06\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x00\x00k\n\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x01\b\x00\x00w\x88\x01\r\x00\x00~\x90\x00\x12\x00\x00p\x80\x00\x04\x00\x00~\x90\x01\bLMT\x00HKT\x00HKST\x00HKW" + + "T\x00JST\x00\x00\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00E\x00\x00\x00\a\x00\x00\x00\x16\xff\xff\xff" + + "\xff\x85ic\x90\xff\xff\xff\xff\xcaM10\xff\xff\xff\xff\xcaۓ0\xff\xff\xff\xff\xcbKqx\xff\xff\xff\xffҠސ\xff\xff\xff\xff\xd3k׀\xff\xff\xff\xffԓX\xb8\xff\xff\xff\xff\xd5B\xb0" + + "8\xff\xff\xff\xff\xd6s:\xb8\xff\xff\xff\xff\xd7>A\xb8\xff\xff\xff\xff\xd8.2\xb8\xff\xff\xff\xff\xd8\xf99\xb8\xff\xff\xff\xff\xda\x0e\x14\xb8\xff\xff\xff\xff\xda\xd9\x1b\xb8\xff\xff\xff\xff\xdb\xed\xf6\xb8\xff\xff\xff" + + "\xffܸ\xfd\xb8\xff\xff\xff\xff\xdd\xcdظ\xff\xff\xff\xffޢ\x1a8\xff\xff\xff\xff߶\xf58\xff\xff\xff\xff\xe0\x81\xfc8\xff\xff\xff\xff\xe1\x96\xc9(\xff\xff\xff\xff\xe2Oi8\xff\xff\xff\xff\xe3v\xab" + + "(\xff\xff\xff\xff\xe4/K8\xff\xff\xff\xff\xe5_Ǩ\xff\xff\xff\xff\xe6\x0f-8\xff\xff\xff\xff\xe7?\xa9\xa8\xff\xff\xff\xff\xe7\xf8I\xb8\xff\xff\xff\xff\xe9\x1f\x8b\xa8\xff\xff\xff\xff\xe9\xd8+\xb8\xff\xff\xff" + + "\xff\xea\xffm\xa8\xff\xff\xff\xff\xeb\xb8\r\xb8\xff\xff\xff\xff\xec\xdfO\xa8\xff\xff\xff\xff\xed\x97\xef\xb8\xff\xff\xff\xff\xee\xc8l(\xff\xff\xff\xff\xefwѸ\xff\xff\xff\xff\xf0\xa8N(\xff\xff\xff\xff\xf1W\xb3" + + "\xb8\xff\xff\xff\xff\xf2\x880(\xff\xff\xff\xff\xf3@\xd08\xff\xff\xff\xff\xf4h\x12(\xff\xff\xff\xff\xf5 \xb28\xff\xff\xff\xff\xf6G\xf4(\xff\xff\xff\xff\xf7%~8\xff\xff\xff\xff\xf8\x15a(\xff\xff\xff" + + "\xff\xf9\x05`8\xff\xff\xff\xff\xf9\xf5C(\xff\xff\xff\xff\xfa\xe5B8\xff\xff\xff\xff\xfb\xde_\xa8\xff\xff\xff\xff\xfc\xce^\xb8\xff\xff\xff\xff\xfd\xbeA\xa8\xff\xff\xff\xff\xfe\xae@\xb8\xff\xff\xff\xff\xff\x9e#" + + "\xa8\x00\x00\x00\x00\x00\x8e\"\xb8\x00\x00\x00\x00\x01~\x05\xa8\x00\x00\x00\x00\x02n\x04\xb8\x00\x00\x00\x00\x03]\xe7\xa8\x00\x00\x00\x00\x04M\xe6\xb8\x00\x00\x00\x00\x05G\x04(\x00\x00\x00\x00\x067\x038\x00\x00\x00" + + "\x00\a&\xe6(\x00\x00\x00\x00\a\x83=8\x00\x00\x00\x00\t\x06\xc8(\x00\x00\x00\x00\t\xf6\xc78\x00\x00\x00\x00\n\xe6\xaa(\x00\x00\x00\x00\v֩8\x00\x00\x00\x00\fƌ(\x00\x00\x00\x00\x11\x9b9" + + "8\x00\x00\x00\x00\x12ol\xa8\x01\x02\x03\x04\x01\x02\x05\x06\x05\x06\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00k\n\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x01\b\x00\x00w\x88\x01\r\x00\x00~\x90\x00\x12\x00\x00p\x80\x00\x04\x00\x00~\x90\x01\b" + + "LMT\x00HKT\x00HKST\x00HKWT\x00JST\x00\x00\x00\x00\x00\x00\x01\x01\nHKT-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP-\x84\xb1)\x8a\x04\x00\x00\x8a\x04" + + "\x00\x00\a\x00\x1c\x00IcelandUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00D\x00\x00\x00\x06\x00\x00\x00\x10\x8b`\x83\xa0\x9c\x91\x1e\x00\x9dш\x90\x9erQ\x80\x9f\xd5\x03\x10\xa0S\x85\x00\xa1\xb66\x90\xa4<'\x80\xa4\xb9t" + + "\x10\xc6M\x1a\x00\xc7=' \xc7\xda\x17\xb0\xc9&C\xa0\xc9\xc3& \xcb\x06%\xa0ˬB\xa0\xcc\xdc\xcd ͌$\xa0μ\xaf \xcfl\x06\xa0М\x91 \xd1K\xe8\xa0҅\xad\xa0\xd3+\xca" + + "\xa0\xd4e\x8f\xa0\xd59\xd1 \xd6Eq\xa0\xd7\x19\xb3 \xd8%S\xa0\xd8\xf9\x95 \xda\x0ep \xda\xd9w \xdb\xe5\x17\xa0ܹY \xdd\xce4 ޢu\xa0߮\x16 \xe0\x82W\xa0\xe1\x8d\xf8" + + " \xe2b9\xa0\xe3m\xda \xe4B\x1b\xa0\xe5M\xbc \xe6!\xfd\xa0\xe76ؠ\xe8\v\x1a \xe9\x16\xba\xa0\xe9\xea\xfc \xea\xf6\x9c\xa0\xeb\xca\xde \xec\xd6~\xa0\xed\xaa\xc0 \xee\xb6`\xa0\uf2a2" + + " \xf0\x96B\xa0\xf1j\x84 \xf2\u007f_ \xf3S\xa0\xa0\xf4_A \xf53\x82\xa0\xf6?# \xf7\x13d\xa0\xf8\x1f\x05 \xf8\xf3F\xa0\xf9\xfe\xe7 \xfa\xd3(\xa0\xfb\xe8\x03\xa0\xfc\xbcE \x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x05\xff\xff\xeb`\x00\x00\x00\x00\x00\x00\x01\x04\xff\xff\xf1\xf0\x00\b\xff\xff\xf1\xf0\x00\b\x00\x00\x00\x00\x01\x04\x00\x00\x00\x00\x00\fLMT\x00+00\x00-01\x00GMT\x00\x00\x00\x00" + + "\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00D\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\x8b`\x83\xa0\xff\xff\xff\xff\x9c" + + "\x91\x1e\x00\xff\xff\xff\xff\x9dш\x90\xff\xff\xff\xff\x9erQ\x80\xff\xff\xff\xff\x9f\xd5\x03\x10\xff\xff\xff\xff\xa0S\x85\x00\xff\xff\xff\xff\xa1\xb66\x90\xff\xff\xff\xff\xa4<'\x80\xff\xff\xff\xff\xa4\xb9t\x10\xff" + + "\xff\xff\xff\xc6M\x1a\x00\xff\xff\xff\xff\xc7=' \xff\xff\xff\xff\xc7\xda\x17\xb0\xff\xff\xff\xff\xc9&C\xa0\xff\xff\xff\xff\xc9\xc3& \xff\xff\xff\xff\xcb\x06%\xa0\xff\xff\xff\xffˬB\xa0\xff\xff\xff\xff\xcc" + + "\xdc\xcd \xff\xff\xff\xff͌$\xa0\xff\xff\xff\xffμ\xaf \xff\xff\xff\xff\xcfl\x06\xa0\xff\xff\xff\xffМ\x91 \xff\xff\xff\xff\xd1K\xe8\xa0\xff\xff\xff\xff҅\xad\xa0\xff\xff\xff\xff\xd3+ʠ\xff" + + "\xff\xff\xff\xd4e\x8f\xa0\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd6Eq\xa0\xff\xff\xff\xff\xd7\x19\xb3 \xff\xff\xff\xff\xd8%S\xa0\xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda" + + "\xd9w \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xce4 \xff\xff\xff\xffޢu\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x82W\xa0\xff\xff\xff\xff\xe1\x8d\xf8 \xff" + + "\xff\xff\xff\xe2b9\xa0\xff\xff\xff\xff\xe3m\xda \xff\xff\xff\xff\xe4B\x1b\xa0\xff\xff\xff\xff\xe5M\xbc \xff\xff\xff\xff\xe6!\xfd\xa0\xff\xff\xff\xff\xe76ؠ\xff\xff\xff\xff\xe8\v\x1a \xff\xff\xff\xff\xe9" + + "\x16\xba\xa0\xff\xff\xff\xff\xe9\xea\xfc \xff\xff\xff\xff\xea\xf6\x9c\xa0\xff\xff\xff\xff\xeb\xca\xde \xff\xff\xff\xff\xec\xd6~\xa0\xff\xff\xff\xff\xed\xaa\xc0 \xff\xff\xff\xff\xee\xb6`\xa0\xff\xff\xff\xff\uf2a2 \xff" + + "\xff\xff\xff\xf0\x96B\xa0\xff\xff\xff\xff\xf1j\x84 \xff\xff\xff\xff\xf2\u007f_ \xff\xff\xff\xff\xf3S\xa0\xa0\xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf53\x82\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7" + + "\x13d\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xf3F\xa0\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xd3(\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc\xbcE \x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\xff" + + "\xff\xeb`\x00\x00\x00\x00\x00\x00\x01\x04\xff\xff\xf1\xf0\x00\b\xff\xff\xf1\xf0\x00\b\x00\x00\x00\x00\x01\x04\x00\x00\x00\x00\x00\fLMT\x00+00\x00-01\x00GMT\x00\x00\x00\x00\x01\x01\x01\nGM" + + "T0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x1c\x00Indian/UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5" + + "\x01\x00\x00\x04\x14\x00\x00\x00PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPE\xa8\xf0\xf8\xf1\x00\x00\x00\xf1\x00\x00\x00\x10\x00\x1c\x00Indian/MauritiusUT\t\x00\x03n" + + "ӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00" + + "\x00\x03\x00\x00\x00\f\x89\u007f\x05\x98\x18\x05\xed@\x18\xdbr0I\x03\x96\xe0IΏ\xd0\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x02\x00\x005\xe8\x00\x00\x00\x00FP\x01\x04\x00\x008@\x00\bLMT\x00+0" + + "5\x00+04\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x89\u007f\x05\x98\x00\x00" + + "\x00\x00\x18\x05\xed@\x00\x00\x00\x00\x18\xdbr0\x00\x00\x00\x00I\x03\x96\xe0\x00\x00\x00\x00IΏ\xd0\x00\x00\x00\x00\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x02\x00\x005\xe8\x00\x00\x00\x00FP\x01\x04\x00\x008@" + + "\x00\bLMT\x00+05\x00+04\x00\n<+04>-4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPvQҸ\xc7\x00\x00\x00\xc7\x00\x00\x00\r\x00\x1c\x00Indian/" + + "ChagosUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\f\x89~\xf7\x9c0\xe6ݰ\u007f\xff\xff\xff\x01\x02\x02\x00\x00C\xe4\x00\x00\x00\x00FP\x00\x04\x00\x00T`\x00\bLMT\x00+05\x00+" + + "06\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x89~\xf7\x9c\x00\x00\x00\x000" + + "\xe6ݰ\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x02\x00\x00C\xe4\x00\x00\x00\x00FP\x00\x04\x00\x00T`\x00\bLMT\x00+05\x00+06\x00\n<+06>-6\nPK\x03\x04\n\x00\x00" + + "\x00\x00\x00\xf5F\x9cPx=\xfb\xae\xfb\x00\x00\x00\xfb\x00\x00\x00\x0e\x00\x1c\x00Indian/MayotteUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00" + + "\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x14\xb1\xee\xda\xfc\xb4\u009a\xd0ǑG" + + "\xd8\xed/\xe1\xd4\x01\x02\x03\x01\x00\x00\"\x84\x00\x00\x00\x00*0\x00\x04\x00\x00#(\x00\b\x00\x00&\xac\x00\x0e\x00\x00*0\x00\x04LMT\x00EAT\x00+0230\x00+0245\x00T" + + "Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xb1\xee\xda\xfc\xff\xff\xff\xff\xb4\u009a\xd0\xff" + + "\xff\xff\xffǑG\xd8\xff\xff\xff\xff\xed/\xe1\xd4\x01\x02\x03\x01\x00\x00\"\x84\x00\x00\x00\x00*0\x00\x04\x00\x00#(\x00\b\x00\x00&\xac\x00\x0e\x00\x00*0\x00\x04LMT\x00EAT\x00+02" + + "30\x00+0245\x00\nEAT-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP,\x14Ქ\x00\x00\x00\xa5\x00\x00\x00\x10\x00\x1c\x00Indian/Christm" + + "asUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\x80\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x00c\x1c\x00\x00\x00\x00bp\x00\x04LMT\x00+07\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xffs\x16\xa9\xe4\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x00c\x1c\x00\x00\x00\x00bp\x00\x04LM" + + "T\x00+07\x00\n<+07>-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x93&\xf6\xb6\xae\x00\x00\x00\xae\x00\x00\x00\f\x00\x1c\x00Indian/CocosUT\t" + + "\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x02\x00\x00\x00\x02\x00\x00\x00\n\x80\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x00Z\xdc\x00\x00\x00\x00[h\x00\x04LMT\x00+0630\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\n\xff\xff\xff\xff|U&\xa4\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x00Z\xdc\x00\x00\x00\x00[h\x00\x04LMT\x00+" + + "0630\x00\n<+0630>-6:30\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPi\xf9Q\xd5\xc7\x00\x00\x00\xc7\x00\x00\x00\x0f\x00\x1c\x00Indian/Mald" + + "ivesUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\f\x80\x00\x00\x00\xed/Ø\u007f\xff\xff\xff\x01\x02\x02\x00\x00D\xe8\x00\x00\x00\x00D\xe8\x00\x04\x00\x00FP\x00\bLMT\x00MMT\x00+05" + + "\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffV\xb6\x9f\x18\xff\xff\xff\xff\xed/\xc3" + + "\x98\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x02\x00\x00D\xe8\x00\x00\x00\x00D\xe8\x00\x04\x00\x00FP\x00\bLMT\x00MMT\x00+05\x00\n<+05>-5\nPK\x03\x04\n\x00\x00\x00\x00" + + "\x00\xf5F\x9cPx=\xfb\xae\xfb\x00\x00\x00\xfb\x00\x00\x00\r\x00\x1c\x00Indian/ComoroUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00" + + "\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x14\xb1\xee\xda\xfc\xb4\u009a\xd0ǑG\xd8\xed/" + + "\xe1\xd4\x01\x02\x03\x01\x00\x00\"\x84\x00\x00\x00\x00*0\x00\x04\x00\x00#(\x00\b\x00\x00&\xac\x00\x0e\x00\x00*0\x00\x04LMT\x00EAT\x00+0230\x00+0245\x00TZif" + + "2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xb1\xee\xda\xfc\xff\xff\xff\xff\xb4\u009a\xd0\xff\xff\xff\xff" + + "ǑG\xd8\xff\xff\xff\xff\xed/\xe1\xd4\x01\x02\x03\x01\x00\x00\"\x84\x00\x00\x00\x00*0\x00\x04\x00\x00#(\x00\b\x00\x00&\xac\x00\x0e\x00\x00*0\x00\x04LMT\x00EAT\x00+0230\x00" + + "+0245\x00\nEAT-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x1c\xb3\x02H\xa5\x00\x00\x00\xa5\x00\x00\x00\x0e\x00\x1c\x00Indian/ReunionUT\t" + + "\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x02\x00\x00\x00\x02\x00\x00\x00\b\x91\xcc9\x80\u007f\xff\xff\xff\x01\x01\x00\x004\x00\x00\x00\x00\x008@\x00\x04LMT\x00+04\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x91\xcc9\x80\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x004\x00\x00\x00\x00\x008@\x00\x04LMT\x00+04" + + "\x00\n<+04>-4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP4e\x10\x18\xa5\x00\x00\x00\xa5\x00\x00\x00\v\x00\x1c\x00Indian/MaheUT\t\x00\x03nӧ^" + + "nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00" + + "\x00\x00\b\x88d\xe6\x84\u007f\xff\xff\xff\x01\x01\x00\x003\xfc\x00\x00\x00\x008@\x00\x04LMT\x00+04\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x88d\xe6\x84\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x003\xfc\x00\x00\x00\x008@\x00\x04LMT\x00+04\x00\n<+04" + + ">-4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa7\xd1X\x9a\xa5\x00\x00\x00\xa5\x00\x00\x00\x10\x00\x1c\x00Indian/KerguelenUT\t\x00\x03nӧ^n" + + "ӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00" + + "\x00\b\xdaab\x80\u007f\xff\xff\xff\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00FP\x00\x04-00\x00+05\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xdaab\x80\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00FP\x00\x04-00\x00+05\x00\n<+05>" + + "-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPx=\xfb\xae\xfb\x00\x00\x00\xfb\x00\x00\x00\x13\x00\x1c\x00Indian/AntananarivoUT\t\x00\x03nӧ" + + "^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05" + + "\x00\x00\x00\x14\xb1\xee\xda\xfc\xb4\u009a\xd0ǑG\xd8\xed/\xe1\xd4\x01\x02\x03\x01\x00\x00\"\x84\x00\x00\x00\x00*0\x00\x04\x00\x00#(\x00\b\x00\x00&\xac\x00\x0e\x00\x00*0\x00\x04LMT\x00EA" + + "T\x00+0230\x00+0245\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff" + + "\xff\xff\xb1\xee\xda\xfc\xff\xff\xff\xff\xb4\u009a\xd0\xff\xff\xff\xffǑG\xd8\xff\xff\xff\xff\xed/\xe1\xd4\x01\x02\x03\x01\x00\x00\"\x84\x00\x00\x00\x00*0\x00\x04\x00\x00#(\x00\b\x00\x00&\xac\x00\x0e\x00\x00" + + "*0\x00\x04LMT\x00EAT\x00+0230\x00+0245\x00\nEAT-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x93G\xdd9\x16\n\x00\x00\x16\n\x00\x00\x04\x00\x1c" + + "\x00IranUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\a\x00\x00\x00\x1c\x9al}\xc8\xd2\xdb\x12\xc8\x0e\xbb\xa2H\x0ft-@\x10\x8e@0\x10\xed:@\x11Ug\xc8\x12EJ\xb8\x137\xec\xc8\x14-\x15\xb8( v" + + "\xc8(\u06dd\xb8)˜\xc8*\xbe\"\xb8+\xac\xd0H,\x9fV8-\x8e\x03\xc8.\x80\x89\xb8/o7H0a\xbd81Pj\xc82B\xf0\xb832\xef\xc84%u\xb85\x14#H6\x06\xa9" + + "86\xf5V\xc87\xe7ܸ8֊H9\xc9\x108:\xb9\x0fH;\xab\x958<\x9aB\xc8=\x8cȸ>{vH?m\xfc8@\\\xa9\xc8AO/\xb8B?.\xc8C1\xb4\xb8G\xe2\xc9" + + "HH\xd5O8I\xc5NHJ\xb7\xd48K\xa6\x81\xc8L\x99\a\xb8M\x87\xb5HNz;8Oh\xe8\xc8P[n\xb8QKm\xc8R=\xf3\xb8S,\xa1HT\x1f'8U\r\xd4\xc8V\x00Z" + + "\xb8V\xef\bHW\xe1\x8e8XэHY\xc4\x138Z\xb2\xc0\xc8[\xa5F\xb8\\\x93\xf4H]\x86z8^u'\xc8_g\xad\xb8`W\xac\xc8aJ2\xb8b8\xe0Hc+f8d\x1a\x13" + + "\xc8e\f\x99\xb8e\xfbGHf\xed\xcd8g\xdd\xccHh\xd0R8i\xbe\xff\xc8j\xb1\x85\xb8k\xa03Hl\x92\xb98m\x81f\xc8ns\xec\xb8ob\x9aHpU 8qE\x1fHr7\xa5" + + "8s&R\xc8t\x18ظu\a\x86Hu\xfa\f8v\xe8\xb9\xc8w\xdb?\xb8x\xcb>\xc8y\xbdĸz\xacrH{\x9e\xf88|\x8d\xa5\xc8}\x80+\xb8~n\xd9H\u007fa_8\x01\x02\x04" + + "\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05" + + "\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x00\x0008\x00\x00\x00\x0008\x00\x04\x00\x0018\x00\b\x00\x00FP\x01" + + "\x0e\x00\x008@\x00\x12\x00\x00?H\x01\x16\x00\x0018\x00\bLMT\x00TMT\x00+0330\x00+05\x00+04\x00+0430\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff\x9al}\xc8\xff\xff\xff\xff\xd2\xdb\x12\xc8\x00\x00\x00\x00\x0e\xbb\xa2H\x00\x00\x00\x00\x0f" + + "t-@\x00\x00\x00\x00\x10\x8e@0\x00\x00\x00\x00\x10\xed:@\x00\x00\x00\x00\x11Ug\xc8\x00\x00\x00\x00\x12EJ\xb8\x00\x00\x00\x00\x137\xec\xc8\x00\x00\x00\x00\x14-\x15\xb8\x00\x00\x00\x00( v\xc8\x00" + + "\x00\x00\x00(\u06dd\xb8\x00\x00\x00\x00)˜\xc8\x00\x00\x00\x00*\xbe\"\xb8\x00\x00\x00\x00+\xac\xd0H\x00\x00\x00\x00,\x9fV8\x00\x00\x00\x00-\x8e\x03\xc8\x00\x00\x00\x00.\x80\x89\xb8\x00\x00\x00\x00/" + + "o7H\x00\x00\x00\x000a\xbd8\x00\x00\x00\x001Pj\xc8\x00\x00\x00\x002B\xf0\xb8\x00\x00\x00\x0032\xef\xc8\x00\x00\x00\x004%u\xb8\x00\x00\x00\x005\x14#H\x00\x00\x00\x006\x06\xa98\x00" + + "\x00\x00\x006\xf5V\xc8\x00\x00\x00\x007\xe7ܸ\x00\x00\x00\x008֊H\x00\x00\x00\x009\xc9\x108\x00\x00\x00\x00:\xb9\x0fH\x00\x00\x00\x00;\xab\x958\x00\x00\x00\x00<\x9aB\xc8\x00\x00\x00\x00=" + + "\x8cȸ\x00\x00\x00\x00>{vH\x00\x00\x00\x00?m\xfc8\x00\x00\x00\x00@\\\xa9\xc8\x00\x00\x00\x00AO/\xb8\x00\x00\x00\x00B?.\xc8\x00\x00\x00\x00C1\xb4\xb8\x00\x00\x00\x00G\xe2\xc9H\x00" + + "\x00\x00\x00H\xd5O8\x00\x00\x00\x00I\xc5NH\x00\x00\x00\x00J\xb7\xd48\x00\x00\x00\x00K\xa6\x81\xc8\x00\x00\x00\x00L\x99\a\xb8\x00\x00\x00\x00M\x87\xb5H\x00\x00\x00\x00Nz;8\x00\x00\x00\x00O" + + "h\xe8\xc8\x00\x00\x00\x00P[n\xb8\x00\x00\x00\x00QKm\xc8\x00\x00\x00\x00R=\xf3\xb8\x00\x00\x00\x00S,\xa1H\x00\x00\x00\x00T\x1f'8\x00\x00\x00\x00U\r\xd4\xc8\x00\x00\x00\x00V\x00Z\xb8\x00" + + "\x00\x00\x00V\xef\bH\x00\x00\x00\x00W\xe1\x8e8\x00\x00\x00\x00XэH\x00\x00\x00\x00Y\xc4\x138\x00\x00\x00\x00Z\xb2\xc0\xc8\x00\x00\x00\x00[\xa5F\xb8\x00\x00\x00\x00\\\x93\xf4H\x00\x00\x00\x00]" + + "\x86z8\x00\x00\x00\x00^u'\xc8\x00\x00\x00\x00_g\xad\xb8\x00\x00\x00\x00`W\xac\xc8\x00\x00\x00\x00aJ2\xb8\x00\x00\x00\x00b8\xe0H\x00\x00\x00\x00c+f8\x00\x00\x00\x00d\x1a\x13\xc8\x00" + + "\x00\x00\x00e\f\x99\xb8\x00\x00\x00\x00e\xfbGH\x00\x00\x00\x00f\xed\xcd8\x00\x00\x00\x00g\xdd\xccH\x00\x00\x00\x00h\xd0R8\x00\x00\x00\x00i\xbe\xff\xc8\x00\x00\x00\x00j\xb1\x85\xb8\x00\x00\x00\x00k" + + "\xa03H\x00\x00\x00\x00l\x92\xb98\x00\x00\x00\x00m\x81f\xc8\x00\x00\x00\x00ns\xec\xb8\x00\x00\x00\x00ob\x9aH\x00\x00\x00\x00pU 8\x00\x00\x00\x00qE\x1fH\x00\x00\x00\x00r7\xa58\x00" + + "\x00\x00\x00s&R\xc8\x00\x00\x00\x00t\x18ظ\x00\x00\x00\x00u\a\x86H\x00\x00\x00\x00u\xfa\f8\x00\x00\x00\x00v\xe8\xb9\xc8\x00\x00\x00\x00w\xdb?\xb8\x00\x00\x00\x00x\xcb>\xc8\x00\x00\x00\x00y" + + "\xbdĸ\x00\x00\x00\x00z\xacrH\x00\x00\x00\x00{\x9e\xf88\x00\x00\x00\x00|\x8d\xa5\xc8\x00\x00\x00\x00}\x80+\xb8\x00\x00\x00\x00~n\xd9H\x00\x00\x00\x00\u007fa_8\x00\x00\x00\x00\x80Q^H\x00" + + "\x00\x00\x00\x81C\xe48\x00\x00\x00\x00\x822\x91\xc8\x00\x00\x00\x00\x83%\x17\xb8\x00\x00\x00\x00\x84\x13\xc5H\x00\x00\x00\x00\x85\x06K8\x00\x00\x00\x00\x85\xf4\xf8\xc8\x00\x00\x00\x00\x86\xe7~\xb8\x00\x00\x00\x00\x87" + + "\xd7}\xc8\x00\x00\x00\x00\x88\xca\x03\xb8\x00\x00\x00\x00\x89\xb8\xb1H\x00\x00\x00\x00\x8a\xab78\x00\x00\x00\x00\x8b\x99\xe4\xc8\x00\x00\x00\x00\x8c\x8cj\xb8\x00\x00\x00\x00\x8d{\x18H\x00\x00\x00\x00\x8em\x9e8\x00" + + "\x00\x00\x00\x8f]\x9dH\x00\x00\x00\x00\x90P#8\x00\x00\x00\x00\x91>\xd0\xc8\x00\x00\x00\x00\x921V\xb8\x00\x00\x00\x00\x93 \x04H\x00\x00\x00\x00\x94\x12\x8a8\x00\x00\x00\x00\x95\x017\xc8\x00\x00\x00\x00\x95" + + "\xf3\xbd\xb8\x00\x00\x00\x00\x96\xe3\xbc\xc8\x00\x00\x00\x00\x97\xd6B\xb8\x00\x00\x00\x00\x98\xc4\xf0H\x00\x00\x00\x00\x99\xb7v8\x00\x00\x00\x00\x9a\xa6#\xc8\x00\x00\x00\x00\x9b\x98\xa9\xb8\x00\x00\x00\x00\x9c\x87WH\x00" + + "\x00\x00\x00\x9dy\xdd8\x00\x00\x00\x00\x9ei\xdcH\x00\x00\x00\x00\x9f\\b8\x00\x00\x00\x00\xa0K\x0f\xc8\x00\x00\x00\x00\xa1=\x95\xb8\x00\x00\x00\x00\xa2,CH\x00\x00\x00\x00\xa3\x1e\xc98\x00\x00\x00\x00\xa4" + + "\rv\xc8\x00\x00\x00\x00\xa4\xff\xfc\xb8\x00\x00\x00\x00\xa5\xef\xfb\xc8\x00\x00\x00\x00\xa6⁸\x00\x00\x00\x00\xa7\xd1/H\x00\x00\x00\x00\xa8õ8\x00\x00\x00\x00\xa9\xb2b\xc8\x00\x00\x00\x00\xaa\xa4\xe8\xb8\x00" + + "\x00\x00\x00\xab\x93\x96H\x00\x00\x00\x00\xac\x86\x1c8\x00\x00\x00\x00\xadt\xc9\xc8\x00\x00\x00\x00\xaegO\xb8\x00\x00\x00\x00\xafWN\xc8\x00\x00\x00\x00\xb0IԸ\x00\x00\x00\x00\xb18\x82H\x00\x00\x00\x00\xb2" + + "+\b8\x00\x00\x00\x00\xb3\x19\xb5\xc8\x00\x00\x00\x00\xb4\f;\xb8\x00\x00\x00\x00\xb4\xfa\xe9H\x00\x00\x00\x00\xb5\xedo8\x00\x00\x00\x00\xb6\xddnH\x00\x00\x00\x00\xb7\xcf\xf48\x00\x00\x00\x00\xb8\xbe\xa1\xc8\x00" + + "\x00\x00\x00\xb9\xb1'\xb8\x00\x00\x00\x00\xba\x9f\xd5H\x00\x00\x00\x00\xbb\x92[8\x00\x00\x00\x00\xbc\x81\b\xc8\x00\x00\x00\x00\xbds\x8e\xb8\x00\x00\x00\x00\xbec\x8d\xc8\x00\x00\x00\x00\xbfV\x13\xb8\x00\x00\x00\x00\xc0" + + "D\xc1H\x00\x00\x00\x00\xc17G8\x00\x00\x00\x00\xc2%\xf4\xc8\x00\x00\x00\x00\xc3\x18z\xb8\x00\x00\x00\x00\xc4\a(H\x00\x00\x00\x00\xc4\xf9\xae8\x00\x00\x00\x00\xc5\xe9\xadH\x00\x00\x00\x00\xc6\xdc38\x00" + + "\x00\x00\x00\xc7\xca\xe0\xc8\x00\x00\x00\x00Ƚf\xb8\x00\x00\x00\x00ɬ\x14H\x00\x00\x00\x00ʞ\x9a8\x00\x00\x00\x00ˍG\xc8\x00\x00\x00\x00\xcc\u007f\u0378\x00\x00\x00\x00\xcdo\xcc\xc8\x00\x00\x00\x00\xce" + + "bR\xb8\x00\x00\x00\x00\xcfQ\x00H\x00\x00\x00\x00\xd0C\x868\x00\x00\x00\x00\xd123\xc8\x00\x00\x00\x00\xd2$\xb9\xb8\x00\x00\x00\x00\xd3\x13gH\x00\x00\x00\x00\xd4\x05\xed8\x00\x00\x00\x00\xd4\xf5\xecH\x00" + + "\x00\x00\x00\xd5\xe8r8\x00\x00\x00\x00\xd6\xd7\x1f\xc8\x00\x00\x00\x00\xd7ɥ\xb8\x00\x00\x00\x00ظSH\x00\x00\x00\x00٪\xd98\x00\x00\x00\x00ڙ\x86\xc8\x00\x00\x00\x00ی\f\xb8\x00\x00\x00\x00\xdc" + + "|\v\xc8\x00\x00\x00\x00\xddn\x91\xb8\x00\x00\x00\x00\xde]?H\x00\x00\x00\x00\xdfO\xc58\x01\x02\x04\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05" + + "\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05" + + "\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05" + + "\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x00\x0008\x00\x00\x00\x0008\x00" + + "\x04\x00\x0018\x00\b\x00\x00FP\x01\x0e\x00\x008@\x00\x12\x00\x00?H\x01\x16\x00\x0018\x00\bLMT\x00TMT\x00+0330\x00+05\x00+04\x00+0430\x00\n" + + "<+0330>-3:30<+0430>,J79/24,J263/24\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfe\x1c\xdd\x02\xf0\b\x00\x00\xf0\b\x00" + + "\x00\x06\x00\x1c\x00IsraelUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\x00\x00\x00\x06\x00\x00\x00\x15\x80\x00\x00\x00\x9e0E\x88\xc8Y\xb2\xe0\xcc\xe5\xc1Pͬ\xfe\x00\xce\xc6\xf4\xd0Ϗf\xe0Щy\xd0ф`\xe0\xd2" + + "\x8a\xc9p\xd3e\xb0\x80\xd4k\xe0\xd0\xd7Z\x14`\xd7\xdf\x1f\xc0\xd8/\xb5p\xd9\x1eF\xe0\xda\x10\xe8\xf0\xda\xeb\xb3\xe0۴4\x00ܹ \xe0\xdd\xe0\x8d\x00\u07b4\u0380ߤ\xbf\x80\xe0\x8bv\x00\xe1" + + "V}\x00\xe2\xbeJ`\xe364\xd0\xe4\x9c\xf7\x00\xe5\x16\x16\xd0\xe6t\xd3\xe0\xe7\x11Ҁ\xe8'\xff\x00\xe8\xe8O\xd0\b|\x8b\xe0\b\xfd\xb0\xd0\t\xf6\xea`\n\xa63\xd0\x13\xe8\xaa\xe0\x14 \t\xe0\x1a" + + "\xf9t\xe0\x1b\x8d\x1c\xe0\x1c\xbe\xf8\xe0\x1d\x89\xf1\xd0\x1e\xcc\xff`\x1f`\x99P \x82\xb1`!I\xb5\xd0\"^\x9e\xe0# ]P$Z0`%\x00?P&\v\xed\xe0&\xd6\xe6\xd0'\xeb\xcf\xe0(" + + "\xc0\x03P)\xd4\xec`*\xa9\x1f\xd0+\xbbe\xe0,\x89\x01\xd0-\x9bG\xe0._\xa9P/{)\xe00H\xc5\xd01H\x96\xe02\x83\x82p?|\x9f\xe0@s6pAP\xa4`BL\x8f\x00CHOpD,q\x00E" + + "\x1e\xf6\xf0F\fS\x00F\xecc\xf0G\xec5\x00H\xe7\xf5pI\xcc\x17\x00J\xbe\x9c\xf0K\xab\xf9\x00L\x8c\t\xf0M\x95\x15\x80N\x87\x9bpOt\xf7\x80P^B\xf0QTـRlIpS" + + "4\xbb\x80TL+pU\x14\x9d\x80V,\rpV\xf4\u007f\x80X\x15)\xf0X\xd4a\x80Y\xf5\v\xf0Z\xb4C\x80[\xd4\xed\xf0\\\x9d`\x00]\xb4\xcf\xf0^}B\x00_\x94\xb1\xf0`]$\x00a" + + "}\xcepb=\x06\x00c]\xb0pd\x1c\xe8\x00e=\x92pf\x06\x04\x80g\x1dtpg\xe5\xe6\x80h\xfdVpi\xc5Ȁj\xdd8pk\xa5\xaa\x80l\xc6T\xf0m\x85\x8c\x80n\xa66\xf0o" + + "en\x80p\x86\x18\xf0qN\x8b\x00re\xfa\xf0s.m\x00tE\xdc\xf0u\x0eO\x00v.\xf9pv\xee1\x00x\x0e\xdbpx\xce\x13\x00y\xee\xbdpz\xad\xf5\x00{Οp|\x97\x11\x80}" + + "\xae\x81p~v\xf3\x80\u007f\x8ecp\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00!\x06\x00\x00\x00\x00 \xf8\x00\x04\x00\x00*0\x01\b\x00\x00\x1c " + + "\x00\f\x00\x008@\x01\x10\x00\x00*0\x01\bLMT\x00JMT\x00IDT\x00IST\x00IDDT\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\x00\x00\x00\x06\x00\x00\x00\x15\xff\xff\xff\xffV\xb6\xc2\xfa\xff\xff\xff\xff\x9e0E\x88\xff\xff\xff\xff\xc8Y\xb2\xe0\xff\xff\xff\xff\xcc\xe5\xc1P\xff\xff\xff\xffͬ\xfe\x00\xff" + + "\xff\xff\xff\xce\xc6\xf4\xd0\xff\xff\xff\xffϏf\xe0\xff\xff\xff\xffЩy\xd0\xff\xff\xff\xffф`\xe0\xff\xff\xff\xffҊ\xc9p\xff\xff\xff\xff\xd3e\xb0\x80\xff\xff\xff\xff\xd4k\xe0\xd0\xff\xff\xff\xff\xd7" + + "Z\x14`\xff\xff\xff\xff\xd7\xdf\x1f\xc0\xff\xff\xff\xff\xd8/\xb5p\xff\xff\xff\xff\xd9\x1eF\xe0\xff\xff\xff\xff\xda\x10\xe8\xf0\xff\xff\xff\xff\xda\xeb\xb3\xe0\xff\xff\xff\xff۴4\x00\xff\xff\xff\xffܹ \xe0\xff" + + "\xff\xff\xff\xdd\xe0\x8d\x00\xff\xff\xff\xff\u07b4\u0380\xff\xff\xff\xffߤ\xbf\x80\xff\xff\xff\xff\xe0\x8bv\x00\xff\xff\xff\xff\xe1V}\x00\xff\xff\xff\xff\xe2\xbeJ`\xff\xff\xff\xff\xe364\xd0\xff\xff\xff\xff\xe4" + + "\x9c\xf7\x00\xff\xff\xff\xff\xe5\x16\x16\xd0\xff\xff\xff\xff\xe6t\xd3\xe0\xff\xff\xff\xff\xe7\x11Ҁ\xff\xff\xff\xff\xe8'\xff\x00\xff\xff\xff\xff\xe8\xe8O\xd0\x00\x00\x00\x00\b|\x8b\xe0\x00\x00\x00\x00\b\xfd\xb0\xd0\x00" + + "\x00\x00\x00\t\xf6\xea`\x00\x00\x00\x00\n\xa63\xd0\x00\x00\x00\x00\x13\xe8\xaa\xe0\x00\x00\x00\x00\x14 \t\xe0\x00\x00\x00\x00\x1a\xf9t\xe0\x00\x00\x00\x00\x1b\x8d\x1c\xe0\x00\x00\x00\x00\x1c\xbe\xf8\xe0\x00\x00\x00\x00\x1d" + + "\x89\xf1\xd0\x00\x00\x00\x00\x1e\xcc\xff`\x00\x00\x00\x00\x1f`\x99P\x00\x00\x00\x00 \x82\xb1`\x00\x00\x00\x00!I\xb5\xd0\x00\x00\x00\x00\"^\x9e\xe0\x00\x00\x00\x00# ]P\x00\x00\x00\x00$Z0`\x00" + + "\x00\x00\x00%\x00?P\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00&\xd6\xe6\xd0\x00\x00\x00\x00'\xeb\xcf\xe0\x00\x00\x00\x00(\xc0\x03P\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xa9\x1f\xd0\x00\x00\x00\x00+" + + "\xbbe\xe0\x00\x00\x00\x00,\x89\x01\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00._\xa9P\x00\x00\x00\x00/{)\xe0\x00\x00\x00\x000H\xc5\xd0\x00\x00\x00\x001H\x96\xe0\x00\x00\x00\x002\x83\x82p\x00\x00\x00\x00?|\x9f\xe0\x00\x00\x00\x00@s6p\x00" + + "\x00\x00\x00AP\xa4`\x00\x00\x00\x00BL\x8f\x00\x00\x00\x00\x00CHOp\x00\x00\x00\x00D,q\x00\x00\x00\x00\x00E\x1e\xf6\xf0\x00\x00\x00\x00F\fS\x00\x00\x00\x00\x00F\xecc\xf0\x00\x00\x00\x00G" + + "\xec5\x00\x00\x00\x00\x00H\xe7\xf5p\x00\x00\x00\x00I\xcc\x17\x00\x00\x00\x00\x00J\xbe\x9c\xf0\x00\x00\x00\x00K\xab\xf9\x00\x00\x00\x00\x00L\x8c\t\xf0\x00\x00\x00\x00M\x95\x15\x80\x00\x00\x00\x00N\x87\x9bp\x00" + + "\x00\x00\x00Ot\xf7\x80\x00\x00\x00\x00P^B\xf0\x00\x00\x00\x00QTـ\x00\x00\x00\x00RlIp\x00\x00\x00\x00S4\xbb\x80\x00\x00\x00\x00TL+p\x00\x00\x00\x00U\x14\x9d\x80\x00\x00\x00\x00V" + + ",\rp\x00\x00\x00\x00V\xf4\u007f\x80\x00\x00\x00\x00X\x15)\xf0\x00\x00\x00\x00X\xd4a\x80\x00\x00\x00\x00Y\xf5\v\xf0\x00\x00\x00\x00Z\xb4C\x80\x00\x00\x00\x00[\xd4\xed\xf0\x00\x00\x00\x00\\\x9d`\x00\x00" + + "\x00\x00\x00]\xb4\xcf\xf0\x00\x00\x00\x00^}B\x00\x00\x00\x00\x00_\x94\xb1\xf0\x00\x00\x00\x00`]$\x00\x00\x00\x00\x00a}\xcep\x00\x00\x00\x00b=\x06\x00\x00\x00\x00\x00c]\xb0p\x00\x00\x00\x00d" + + "\x1c\xe8\x00\x00\x00\x00\x00e=\x92p\x00\x00\x00\x00f\x06\x04\x80\x00\x00\x00\x00g\x1dtp\x00\x00\x00\x00g\xe5\xe6\x80\x00\x00\x00\x00h\xfdVp\x00\x00\x00\x00i\xc5Ȁ\x00\x00\x00\x00j\xdd8p\x00" + + "\x00\x00\x00k\xa5\xaa\x80\x00\x00\x00\x00l\xc6T\xf0\x00\x00\x00\x00m\x85\x8c\x80\x00\x00\x00\x00n\xa66\xf0\x00\x00\x00\x00oen\x80\x00\x00\x00\x00p\x86\x18\xf0\x00\x00\x00\x00qN\x8b\x00\x00\x00\x00\x00r" + + "e\xfa\xf0\x00\x00\x00\x00s.m\x00\x00\x00\x00\x00tE\xdc\xf0\x00\x00\x00\x00u\x0eO\x00\x00\x00\x00\x00v.\xf9p\x00\x00\x00\x00v\xee1\x00\x00\x00\x00\x00x\x0e\xdbp\x00\x00\x00\x00x\xce\x13\x00\x00" + + "\x00\x00\x00y\xee\xbdp\x00\x00\x00\x00z\xad\xf5\x00\x00\x00\x00\x00{Οp\x00\x00\x00\x00|\x97\x11\x80\x00\x00\x00\x00}\xae\x81p\x00\x00\x00\x00~v\xf3\x80\x00\x00\x00\x00\u007f\x8ecp\x01\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00!\x06\x00\x00\x00\x00 \xf8\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\f\x00\x008@\x01\x10\x00\x00*0\x01\bLM" + + "T\x00JMT\x00IDT\x00IST\x00IDDT\x00\nIST-2IDT,M3.4.4/26,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9c" + + "P\xf9,\x94G\xe2\x01\x00\x00\xe2\x01\x00\x00\a\x00\x1c\x00JamaicaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x04\x00\x00\x00\x10\x80\x00\x00\x00\x93\x0f\xb4\xfe\a\x8d\x19p\t\x10\xa4`\t\xad\x94\xf0\n\xf0\x86`" + + "\v\xe0\x85p\f٢\xe0\r\xc0gp\x0e\xb9\x84\xe0\x0f\xa9\x83\xf0\x10\x99f\xe0\x11\x89e\xf0\x12yH\xe0\x13iG\xf0\x14Y*\xe0\x15I)\xf0\x169\f\xe0\x17)\v\xf0\x18\")`\x19\b\xed\xf0" + + "\x1a\x02\v`\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\xff\xff\xb8\x02\x00\x00\xff\xff\xb8\x02\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\fLMT\x00KMT\x00ES" + + "T\x00EDT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87#~\xff\xff" + + "\xff\xff\x93\x0f\xb4\xfe\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\t\xad\x94\xf0\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0" + + "gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00" + + "\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\xff\xff\xb8\x02\x00\x00\xff\xff\xb8\x02\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\fLMT\x00KMT\x00EST\x00EDT\x00\nEST5\nPK\x03\x04\n\x00" + + "\x00\x00\x00\x00\xf5F\x9cP\fH\xe6\r5\x01\x00\x005\x01\x00\x00\x05\x00\x1c\x00JapanUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZi" + + "f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x04\x00\x00\x00\f\x80\x00\x00\x00\xd7>\x02p\xd7\xedY\xf0\xd8\xf8\xfap\xd9\xcd;" + + "\xf0\xdb\a\x00\xf0ۭ\x1d\xf0\xdc\xe6\xe2\xf0\u074c\xff\xf0\x03\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x83\x03\x00\x00\x00\x00\x8c\xa0\x01\x04\x00\x00~\x90\x00\b\x00\x00~\x90\x00\bLMT\x00JDT\x00JS" + + "T\x00\x00\x00\x00\x01\x00\x00\x00\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xffe\xc2" + + "\xa4p\xff\xff\xff\xff\xd7>\x02p\xff\xff\xff\xff\xd7\xedY\xf0\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xd9\xcd;\xf0\xff\xff\xff\xff\xdb\a\x00\xf0\xff\xff\xff\xffۭ\x1d\xf0\xff\xff\xff\xff\xdc\xe6\xe2\xf0\xff\xff" + + "\xff\xff\u074c\xff\xf0\x03\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x83\x03\x00\x00\x00\x00\x8c\xa0\x01\x04\x00\x00~\x90\x00\b\x00\x00~\x90\x00\bLMT\x00JDT\x00JST\x00\x00\x00\x00\x01\x00\x00\x00\x01\n" + + "JST-9\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x03|\x89\xf2<\x01\x00\x00<\x01\x00\x00\t\x00\x1c\x00KwajaleinUT\t\x00\x03nӧ^nӧ^ux" + + "\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x06\x00\x00\x00\x18\x80\x00\x00" + + "\x00\xc1\xed5\xd0\xc9\xea\n`\xcfF\x81\xf0\xff\x86\x1bP,v\x0e@\u007f\xff\xff\xff\x01\x02\x03\x01\x04\x05\x05\x00\x00\x9c\xe0\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00\x8c\xa0\x00\b\x00\x00~\x90\x00\f\xff\xffW@" + + "\x00\x10\x00\x00\xa8\xc0\x00\x14LMT\x00+11\x00+10\x00+09\x00-12\x00+12\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff~6\x18 \xff\xff\xff\xff\xc1\xed5\xd0\xff\xff\xff\xff\xc9\xea\n`\xff\xff\xff\xff\xcfF\x81\xf0\xff\xff\xff\xff\xff\x86\x1bP\x00\x00\x00\x00" + + ",v\x0e@\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x01\x04\x05\x05\x00\x00\x9c\xe0\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00\x8c\xa0\x00\b\x00\x00~\x90\x00\f\xff\xffW@\x00\x10\x00\x00\xa8\xc0\x00\x14LMT\x00+" + + "11\x00+10\x00+09\x00-12\x00+12\x00\n<+12>-12\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc2ɵ,q\x02\x00\x00q\x02\x00\x00\x05\x00\x1c\x00L" + + "ibyaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x04\x00\x00\x00\x11\xa1\xf2\xc1$ݻ\xb1\x10\xde#\xad`\xe1x\xd2\x10\xe1\xe7e\xe0\xe5/?p\xe5\xa9\xcc\xe0\xebN\xc6\xf0\x16\x92B`\x17\b\xf7p\x17\xfa+\xe0" + + "\x18\xea*\xf0\x19\xdb_`\x1a̯\xf0\x1b\xbd\xe4`\x1c\xb4z\xf0\x1d\x9f\x17\xe0\x1e\x93\vp\x1f\x82\xee` pJp!a~\xe0\"R\xcfp#D\x03\xe0$4\x02\xf0%%7`&@\xb7\xf0" + + "2N\xf1`3D6p45j\xe0P\x9d\x99\x00QTـRi\xb4\x80\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x03\x02\x01\x03\x00\x00\f\\" + + "\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x00\rLMT\x00CEST\x00CET\x00EET\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff\xa1\xf2\xc1$\xff\xff\xff\xffݻ\xb1\x10\xff\xff\xff\xff\xde#\xad`\xff\xff\xff\xff\xe1x\xd2\x10\xff\xff\xff\xff\xe1\xe7e" + + "\xe0\xff\xff\xff\xff\xe5/?p\xff\xff\xff\xff\xe5\xa9\xcc\xe0\xff\xff\xff\xff\xebN\xc6\xf0\x00\x00\x00\x00\x16\x92B`\x00\x00\x00\x00\x17\b\xf7p\x00\x00\x00\x00\x17\xfa+\xe0\x00\x00\x00\x00\x18\xea*\xf0\x00\x00\x00" + + "\x00\x19\xdb_`\x00\x00\x00\x00\x1a̯\xf0\x00\x00\x00\x00\x1b\xbd\xe4`\x00\x00\x00\x00\x1c\xb4z\xf0\x00\x00\x00\x00\x1d\x9f\x17\xe0\x00\x00\x00\x00\x1e\x93\vp\x00\x00\x00\x00\x1f\x82\xee`\x00\x00\x00\x00 pJ" + + "p\x00\x00\x00\x00!a~\xe0\x00\x00\x00\x00\"R\xcfp\x00\x00\x00\x00#D\x03\xe0\x00\x00\x00\x00$4\x02\xf0\x00\x00\x00\x00%%7`\x00\x00\x00\x00&@\xb7\xf0\x00\x00\x00\x002N\xf1`\x00\x00\x00" + + "\x003D6p\x00\x00\x00\x0045j\xe0\x00\x00\x00\x00P\x9d\x99\x00\x00\x00\x00\x00QTـ\x00\x00\x00\x00Ri\xb4\x80\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x03\x02\x01\x03\x02\x01\x03\x00\x00\f\\\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x00\rLMT\x00CEST\x00CET\x00EET\x00\nEET-2\nPK\x03" + + "\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf5\xd6:\xad.\b\x00\x00.\b\x00\x00\x03\x00\x1c\x00METUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZ" + + "if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x88\x00\x00\x00\x04\x00\x00\x00\t\x9b\f\x17`\x9b\xd5\xda\xf0\x9cٮ\x90\x9d\xa4\xb5\x90\x9e\xb9" + + "\x90\x90\x9f\x84\x97\x90\xc8\tq\x90\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10Ђ%\x10\xd1r\x16\x10\xd2N@\x90\r\xa4c\x90\x0e\x8b\x1a\x10\x0f\x84E\x90\x10t6\x90\x11d'\x90\x12T" + + "\x18\x90\x13MD\x10\x143\xfa\x90\x15#\xeb\x90\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 l" + + "r\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3" + + "\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7" + + "\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d" + + "\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11" + + "\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x00\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x00\x00\x0e\x10\x00\x05\x00\x00\x1c \x01\x00\x00\x00\x1c \x01\x00\x00\x00\x0e\x10\x00\x05MEST\x00MET\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x88\x00\x00\x00\x04\x00\x00\x00\t\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e" + + "\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff" + + "\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12" + + "T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00" + + "\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 " + + "lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00" + + "\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J" + + "\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00" + + "\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X" + + "\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00" + + "\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g" + + "\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00" + + "\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u" + + "\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00" + + "\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x00\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\x0e\x10\x00\x05\x00\x00\x1c \x01\x00\x00" + + "\x00\x1c \x01\x00\x00\x00\x0e\x10\x00\x05MEST\x00MET\x00\x00\x00\x01\x01\nMET-1MEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00" + + "\x00\x00\xf5F\x9cP~#;\xf4r\x00\x00\x00r\x00\x00\x00\x03\x00\x1c\x00MSTUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\x9d\x90\x00\x00MST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\x9d\x90\x00\x00MST\x00\nMST7\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9c" + + "Pw\x1c\x17t\x06\t\x00\x00\x06\t\x00\x00\a\x00\x1c\x00MST7MDTUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x95\x00\x00\x00\x05\x00\x00\x00\x10\x9e\xa6:\x90\x9f\xbb\a\x80\xa0\x86\x1c\x90\xa1\x9a\xe9\x80ˉ\f\x90\xd2#\xf4p" + + "\xd2a\x18\x00\xfa\xf8u\x10\xfb\xe8X\x00\xfc\xd8W\x10\xfd\xc8:\x00\xfe\xb89\x10\xff\xa8\x1c\x00\x00\x98\x1b\x10\x01\x87\xfe\x00\x02w\xfd\x10\x03q\x1a\x80\x04a\x19\x90\x05P\xfc\x80\x06@\xfb\x90\a0ހ" + + "\a\x8d5\x90\t\x10\xc0\x80\t\xad\xb1\x10\n\xf0\xa2\x80\vࡐ\fٿ\x00\r\xc0\x83\x90\x0e\xb9\xa1\x00\x0f\xa9\xa0\x10\x10\x99\x83\x00\x11\x89\x82\x10\x12ye\x00\x13id\x10\x14YG\x00\x15IF\x10" + + "\x169)\x00\x17)(\x10\x18\"E\x80\x19\t\n\x10\x1a\x02'\x80\x1a\xf2&\x90\x1b\xe2\t\x80\x1c\xd2\b\x90\x1d\xc1\xeb\x80\x1e\xb1\xea\x90\x1f\xa1̀ v\x1d\x10!\x81\xaf\x80\"U\xff\x10#j\xcc\x00" + + "$5\xe1\x10%J\xae\x00&\x15\xc3\x10'*\x90\x00'\xfeߐ)\nr\x00)\xde\xc1\x90*\xeaT\x00+\xbe\xa3\x90,\xd3p\x80-\x9e\x85\x90.\xb3R\x80/~g\x900\x934\x801g\x84\x10" + + "2s\x16\x803Gf\x104R\xf8\x805'H\x1062ڀ7\a*\x108\x1b\xf7\x008\xe7\f\x109\xfb\xd9\x00:\xc6\xee\x10;ۻ\x00<\xb0\n\x90=\xbb\x9d\x00>\x8f\xec\x90?\x9b\u007f\x00" + + "@oΐA\x84\x9b\x80BO\xb0\x90Cd}\x80D/\x92\x90ED_\x80E\xf3\xc5\x10G-|\x00Gӧ\x10I\r^\x00I\xb3\x89\x10J\xed@\x00K\x9c\xa5\x90L\xd6\\\x80M|\x87\x90" + + "N\xb6>\x80O\\i\x90P\x96 \x80Q\x8f\xec\x90\x00\x00\x00\x00?\x9b\u007f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}" + + "\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x00\x00\x00\x00G-|\x00\x00\x00\x00\x00Gӧ\x10\x00\x00\x00\x00I\r^\x00\x00\x00\x00\x00I\xb3\x89\x10\x00\x00\x00" + + "\x00J\xed@\x00\x00\x00\x00\x00K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\\\x80\x00\x00\x00\x00M|\x87\x90\x00\x00\x00\x00N\xb6>\x80\x00\x00\x00\x00O\\i\x90\x00\x00\x00\x00P\x96 \x80\x00\x00\x00\x00Q\x8f\xfa\xa0?\x9b\x8d\x10@oܠA\x84\xa9\x90BO\xbe" + + "\xa0Cd\x8b\x90D/\xa0\xa0EDm\x90F\x0f\x82\xa0G$O\x90G\xf8\x9f I\x041\x90I\u0601 J\xe4\x13\x90K\x9c\xb3\xa0L\xd6j\x90M|\x95\xa0N\xb6L\x90O\\w\xa0P\x96." + + "\x90Q\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00" + + "\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00F\x0f\x82\xa0\x00\x00\x00\x00G$O\x90\x00\x00\x00\x00G\xf8\x9f \x00\x00\x00\x00I\x041\x90\x00\x00\x00\x00I\xd8" + + "\x81 \x00\x00\x00\x00J\xe4\x13\x90\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00M|\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\\w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00" + + "\x00\x00Q\x8fހ?\x9bp\xf0@o\xc0\x80A\x84\x8dpBO\xa2\x80CdopD/\x84\x80E" + + "DQpF\x0ff\x80G$3pG\xf8\x83\x00I\x04\x15pI\xd8e\x00J\xe3\xf7pK\xb8G\x00L\xcd\x13\xf0M\x98)\x00N\xac\xf5\xf0Ox\v\x00P\x8c\xd7\xf0Qa'\x80Rl\xb9\xf0S" + + "A\t\x80TL\x9b\xf0U \xeb\x80V,}\xf0W\x00̀X\x15\x9apXீY\xf5|pZ\xc0\x91\x80[\xd5^p\\\xa9\xae\x00]\xb5@p^\x89\x90\x00_\x95\"p`ir\x00a" + + "~>\xf0bIT\x00c^ \xf0d)6\x00e>\x02\xf0f\x12R\x80g\x1d\xe4\xf0g\xf24\x80h\xfd\xc6\xf0i\xd2\x16\x80jݨ\xf0k\xb1\xf8\x80l\xc6\xc5pm\x91ڀn\xa6\xa7po" + + "q\xbc\x80p\x86\x89pqZ\xd9\x00rfkps:\xbb\x00tFMpu\x1a\x9d\x00v/i\xf0v\xfa\u007f\x00x\x0fK\xf0x\xdaa\x00y\xef-\xf0z\xbaC\x00{\xcf\x0f\xf0|\xa3_\x80}" + + "\xae\xf1\xf0~\x83A\x80\u007f\x8e\xd3\xf0\x01\x02\x01\x02\x01\x02\x03\x02\x03\x02\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\xff\xff\xa3\f\x00\x00\xff\xff\x9d\x90\x00" + + "\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10LMT\x00MST\x00CST\x00CDT\x00CWT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8" + + "\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xc5ް`\xff\xff\xff\xffƗ4P\xff\xff\xff\xff\xc9U\xf1\xe0\xff\xff\xff\xff\xc9\xea\xddP\xff\xff\xff\xff\xcf\x02\xc6\xe0\xff\xff\xff\xffϷVP\xff" + + "\xff\xff\xffڙ\x15\xe0\xff\xff\xff\xff\xdbv\x83\xd0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x006" + + "2\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00" + + "\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D" + + "/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00F\x0ff\x80\x00\x00\x00\x00G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00" + + "\x00\x00\x00K\xb8G\x00\x00\x00\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00M\x98)\x00\x00\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00Ox\v\x00\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00R" + + "l\xb9\xf0\x00\x00\x00\x00SA\t\x80\x00\x00\x00\x00TL\x9b\xf0\x00\x00\x00\x00U \xeb\x80\x00\x00\x00\x00V,}\xf0\x00\x00\x00\x00W\x00̀\x00\x00\x00\x00X\x15\x9ap\x00\x00\x00\x00Xீ\x00" + + "\x00\x00\x00Y\xf5|p\x00\x00\x00\x00Z\xc0\x91\x80\x00\x00\x00\x00[\xd5^p\x00\x00\x00\x00\\\xa9\xae\x00\x00\x00\x00\x00]\xb5@p\x00\x00\x00\x00^\x89\x90\x00\x00\x00\x00\x00_\x95\"p\x00\x00\x00\x00`" + + "ir\x00\x00\x00\x00\x00a~>\xf0\x00\x00\x00\x00bIT\x00\x00\x00\x00\x00c^ \xf0\x00\x00\x00\x00d)6\x00\x00\x00\x00\x00e>\x02\xf0\x00\x00\x00\x00f\x12R\x80\x00\x00\x00\x00g\x1d\xe4\xf0\x00" + + "\x00\x00\x00g\xf24\x80\x00\x00\x00\x00h\xfd\xc6\xf0\x00\x00\x00\x00i\xd2\x16\x80\x00\x00\x00\x00jݨ\xf0\x00\x00\x00\x00k\xb1\xf8\x80\x00\x00\x00\x00l\xc6\xc5p\x00\x00\x00\x00m\x91ڀ\x00\x00\x00\x00n" + + "\xa6\xa7p\x00\x00\x00\x00oq\xbc\x80\x00\x00\x00\x00p\x86\x89p\x00\x00\x00\x00qZ\xd9\x00\x00\x00\x00\x00rfkp\x00\x00\x00\x00s:\xbb\x00\x00\x00\x00\x00tFMp\x00\x00\x00\x00u\x1a\x9d\x00\x00" + + "\x00\x00\x00v/i\xf0\x00\x00\x00\x00v\xfa\u007f\x00\x00\x00\x00\x00x\x0fK\xf0\x00\x00\x00\x00x\xdaa\x00\x00\x00\x00\x00y\xef-\xf0\x00\x00\x00\x00z\xbaC\x00\x00\x00\x00\x00{\xcf\x0f\xf0\x00\x00\x00\x00|" + + "\xa3_\x80\x00\x00\x00\x00}\xae\xf1\xf0\x00\x00\x00\x00~\x83A\x80\x00\x00\x00\x00\u007f\x8e\xd3\xf0\x01\x02\x01\x02\x01\x02\x03\x02\x03\x02\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\xff\xff\xa3\f\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10LMT\x00MST\x00CST\x00CDT\x00CWT\x00\nCST6" + + "CDT,M4.1.0,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPv:D\x98\xf6\x05\x00\x00\xf6\x05\x00\x00\x0e\x00\x1c\x00Mexico/Baja" + + "SurUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00]\x00\x00\x00\x06\x00\x00\x00\x14\xa5\xb6\xe8p\xaf\xf2n\xe0\xb6fV`\xb7C\xd2`\xb8\f6`\xb8\xfd\x86\xf0\xcb\xeaq`ؑ\xb4\xf0\x00\x00p\x801g\x84\x102s\x16\x803" + + "Gf\x104R\xf8\x805'H\x1062ڀ7\a*\x108\x1b\xf7\x008\xe7\f\x109\xfb\xd9\x00:\xf5\x12\x90;\xb6\xd1\x00<\xb0\n\x90=\xbb\x9d\x00>\x8f\xec\x90?\x9b\u007f\x00@oΐA" + + "\x84\x9b\x80BO\xb0\x90Cd}\x80D/\x92\x90ED_\x80F\x0ft\x90G$A\x80G\xf8\x91\x10I\x04#\x80I\xd8s\x10J\xe4\x05\x80K\xb8U\x10L\xcd\"\x00M\x987\x10N\xad\x04\x00O" + + "x\x19\x10P\x8c\xe6\x00Qa5\x90Rl\xc8\x00SA\x17\x90TL\xaa\x00U \xf9\x90V,\x8c\x00W\x00ېX\x15\xa8\x80XཐY\xf5\x8a\x80Z\xc0\x9f\x90[\xd5l\x80\\\xa9\xbc\x10]" + + "\xb5N\x80^\x89\x9e\x10_\x950\x80`i\x80\x10a~M\x00bIb\x10c^/\x00d)D\x10e>\x11\x00f\x12`\x90g\x1d\xf3\x00g\xf2B\x90h\xfd\xd5\x00i\xd2$\x90jݷ\x00k" + + "\xb2\x06\x90l\xc6Ӏm\x91\xe8\x90n\xa6\xb5\x80oqʐp\x86\x97\x80qZ\xe7\x10rfy\x80s:\xc9\x10tF[\x80u\x1a\xab\x10v/x\x00v\xfa\x8d\x10x\x0fZ\x00x\xdao\x10y" + + "\xef<\x00z\xbaQ\x10{\xcf\x1e\x00|\xa3m\x90}\xaf\x00\x00~\x83O\x90\u007f\x8e\xe2\x00\x01\x02\x01\x02\x01\x02\x01\x03\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01" + + "\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01" + + "\xff\xff\x9c<\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\x8f\x80\x00\f\xff\xff\xab\xa0\x01\x10\xff\xff\x9d\x90\x00\x04LMT\x00MST\x00CST\x00PST\x00MDT\x00TZif" + + "2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff" + + "\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xcb\xeaq`\xff\xff\xff\xffؑ\xb4\xf0\x00\x00\x00\x00\x00\x00p\x80\x00\x00\x00\x001g\x84\x10" + + "\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x00" + + "8\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\u007f\x00" + + "\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00" + + "G$A\x80\x00\x00\x00\x00G\xf8\x91\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00\x00\x00\x00K\xb8U\x10\x00\x00\x00\x00L\xcd\"\x00\x00\x00\x00\x00M\x987\x10" + + "\x00\x00\x00\x00N\xad\x04\x00\x00\x00\x00\x00Ox\x19\x10\x00\x00\x00\x00P\x8c\xe6\x00\x00\x00\x00\x00Qa5\x90\x00\x00\x00\x00Rl\xc8\x00\x00\x00\x00\x00SA\x17\x90\x00\x00\x00\x00TL\xaa\x00\x00\x00\x00\x00" + + "U \xf9\x90\x00\x00\x00\x00V,\x8c\x00\x00\x00\x00\x00W\x00ې\x00\x00\x00\x00X\x15\xa8\x80\x00\x00\x00\x00Xཐ\x00\x00\x00\x00Y\xf5\x8a\x80\x00\x00\x00\x00Z\xc0\x9f\x90\x00\x00\x00\x00[\xd5l\x80" + + "\x00\x00\x00\x00\\\xa9\xbc\x10\x00\x00\x00\x00]\xb5N\x80\x00\x00\x00\x00^\x89\x9e\x10\x00\x00\x00\x00_\x950\x80\x00\x00\x00\x00`i\x80\x10\x00\x00\x00\x00a~M\x00\x00\x00\x00\x00bIb\x10\x00\x00\x00\x00" + + "c^/\x00\x00\x00\x00\x00d)D\x10\x00\x00\x00\x00e>\x11\x00\x00\x00\x00\x00f\x12`\x90\x00\x00\x00\x00g\x1d\xf3\x00\x00\x00\x00\x00g\xf2B\x90\x00\x00\x00\x00h\xfd\xd5\x00\x00\x00\x00\x00i\xd2$\x90" + + "\x00\x00\x00\x00jݷ\x00\x00\x00\x00\x00k\xb2\x06\x90\x00\x00\x00\x00l\xc6Ӏ\x00\x00\x00\x00m\x91\xe8\x90\x00\x00\x00\x00n\xa6\xb5\x80\x00\x00\x00\x00oqʐ\x00\x00\x00\x00p\x86\x97\x80\x00\x00\x00\x00" + + "qZ\xe7\x10\x00\x00\x00\x00rfy\x80\x00\x00\x00\x00s:\xc9\x10\x00\x00\x00\x00tF[\x80\x00\x00\x00\x00u\x1a\xab\x10\x00\x00\x00\x00v/x\x00\x00\x00\x00\x00v\xfa\x8d\x10\x00\x00\x00\x00x\x0fZ\x00" + + "\x00\x00\x00\x00x\xdao\x10\x00\x00\x00\x00y\xef<\x00\x00\x00\x00\x00z\xbaQ\x10\x00\x00\x00\x00{\xcf\x1e\x00\x00\x00\x00\x00|\xa3m\x90\x00\x00\x00\x00}\xaf\x00\x00\x00\x00\x00\x00~\x83O\x90\x00\x00\x00\x00" + + "\u007f\x8e\xe2\x00\x01\x02\x01\x02\x01\x02\x01\x03\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04" + + "\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\xff\xff\x9c<\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\x8f\x80\x00" + + "\f\xff\xff\xab\xa0\x01\x10\xff\xff\x9d\x90\x00\x04LMT\x00MST\x00CST\x00PST\x00MDT\x00\nMST7MDT,M4.1.0,M10.5.0\nPK\x03" + + "\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP0>8\xb8\x85\t\x00\x00\x85\t\x00\x00\x02\x00\x1c\x00NZUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZi" + + "f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x9c\x00\x00\x00\a\x00\x00\x00\x13\x80\x00\x00\x00\xb0\xb4\xb2\xe8\xb1Q\x87X\xb2x\xe5h\xb3C\xe5" + + "`\xb4X\xc7h\xb5#\xc7`\xb68\xa9h\xb7\x03\xa9`\xb8\x18\x8bh\xb8\xec\xc5\xe0\xb9\xf8mh\xba̧\xe0\xbb\xd8Oh\xbc\xe3\xe8\u0f6e\xf6\xe8\xbe\xc3\xca࿎\xd8\xe8\xc0\xa3\xac\xe0\xc1n\xba" + + "\xe8\u0083\x8e\xe0\xc3N\x9c\xe8\xc4cp\xe0\xc5.~\xe8\xc6L\x8d`\xc7\x0e`\xe8\xc8,o`\xc8\xf7}h\xd2ښ@\t\x18\xfd\xe0\t\xac\xa5\xe0\n\xef\xa5`\v\x9e\xfc\xe0\f\xd8\xc1\xe0\r~\xde" + + "\xe0\x0e\xb8\xa3\xe0\x0f^\xc0\xe0\x10\x98\x85\xe0\x11>\xa2\xe0\x12xg\xe0\x13\x1e\x84\xe0\x14XI\xe0\x14\xfef\xe0\x168+\xe0\x16\xe7\x83`\x18!H`\x18\xc7e`\x1a\x01*`\x1a\xa7G`\x1b\xe1\f" + + "`\x1c\x87)`\x1d\xc0\xee`\x1eg\v`\x1f\xa0\xd0` F\xed`!\x80\xb2`\"0\t\xe0#i\xce\xe0$\x0f\xeb\xe0%.\x01`&\x02B\xe0'\r\xe3`'\xe2$\xe0(\xed\xc5`)\xc2\x06" + + "\xe0*ͧ`+\xab#`,\xad\x89`-\x8b\x05`.\x8dk`/j\xe7`0mM`1J\xc9`2Vi\xe03*\xab`46K\xe05\n\x8d`6\x16-\xe06\xf3\xa9\xe07\xf6\x0f" + + "\xe08Ӌ\xe09\xd5\xf1\xe0:\xb3m\xe0;\xbf\x0e`<\x93O\xe0=\x9e\xf0`>s1\xe0?~\xd2`@\\N`A^\xb4`B<0`C>\x96`D\x1c\x12`E\x1ex`E\xfb\xf4" + + "`F\xfeZ`G\xf7\x85\xe0H\xde<`I\xd7g\xe0J\xbe\x1e`K\xb7I\xe0L\x9e\x00`M\x97+\xe0N}\xe2`Ow\r\xe0Pf\xfe\xe0Q`*`RF\xe0\xe0S@\f`T&\xc2" + + "\xe0U\x1f\xee`V\x06\xa4\xe0V\xff\xd0`W\xe6\x86\xe0X߲`Y\xc6h\xe0Z\xbf\x94`[\xaf\x85`\\\xa8\xb0\xe0]\x8fg`^\x88\x92\xe0_oI``ht\xe0aO+`bHV" + + "\xe0c/\r`d(8\xe0e\x0e\xef`f\x11U`f\xf8\v\xe0g\xf17`h\xd7\xed\xe0i\xd1\x19`j\xb7\xcf\xe0k\xb0\xfb`l\x97\xb1\xe0m\x90\xdd`nw\x93\xe0op\xbf`p`\xb0" + + "`qY\xdb\xe0r@\x92`s9\xbd\xe0t t`u\x19\x9f\xe0v\x00V`v\xf9\x81\xe0w\xe08`x\xd9c\xe0y\xc0\x1a`z\xb9E\xe0{\xa96\xe0|\xa2b`}\x89\x18\xe0~\x82D" + + "`\u007fh\xfa\xe0\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x06\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x00\x00\xa3\xd8\x00\x00\x00\x00\xaf\xc8\x01\x04\x00\x00\xa1\xb8\x00\t\x00" + + "\x00\xa8\xc0\x01\x04\x00\x00\xb6\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04\x00\x00\xa8\xc0\x00\x04LMT\x00NZST\x00NZMT\x00NZDT\x00\x00\x00\x00\x00\x01\x01\x00TZif2\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x9c\x00\x00\x00\a\x00\x00\x00\x13\xff\xff\xff\xffA\xb7L\xa8\xff\xff\xff\xff\xb0\xb4\xb2\xe8\xff\xff\xff\xff\xb1Q\x87X\xff\xff\xff" + + "\xff\xb2x\xe5h\xff\xff\xff\xff\xb3C\xe5`\xff\xff\xff\xff\xb4X\xc7h\xff\xff\xff\xff\xb5#\xc7`\xff\xff\xff\xff\xb68\xa9h\xff\xff\xff\xff\xb7\x03\xa9`\xff\xff\xff\xff\xb8\x18\x8bh\xff\xff\xff\xff\xb8\xec\xc5" + + "\xe0\xff\xff\xff\xff\xb9\xf8mh\xff\xff\xff\xff\xba̧\xe0\xff\xff\xff\xff\xbb\xd8Oh\xff\xff\xff\xff\xbc\xe3\xe8\xe0\xff\xff\xff\xff\xbd\xae\xf6\xe8\xff\xff\xff\xff\xbe\xc3\xca\xe0\xff\xff\xff\xff\xbf\x8e\xd8\xe8\xff\xff\xff" + + "\xff\xc0\xa3\xac\xe0\xff\xff\xff\xff\xc1n\xba\xe8\xff\xff\xff\xff\u0083\x8e\xe0\xff\xff\xff\xff\xc3N\x9c\xe8\xff\xff\xff\xff\xc4cp\xe0\xff\xff\xff\xff\xc5.~\xe8\xff\xff\xff\xff\xc6L\x8d`\xff\xff\xff\xff\xc7\x0e`" + + "\xe8\xff\xff\xff\xff\xc8,o`\xff\xff\xff\xff\xc8\xf7}h\xff\xff\xff\xff\xd2ښ@\x00\x00\x00\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v\x9e\xfc\xe0\x00\x00\x00" + + "\x00\f\xd8\xc1\xe0\x00\x00\x00\x00\r~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84" + + "\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00" + + "\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\f`\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2" + + "`\x00\x00\x00\x00\"0\t\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00" + + "\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*ͧ`\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7" + + "`\x00\x00\x00\x000mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00" + + "\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008Ӌ\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0" + + "`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\\N`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00" + + "\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x00\x00\x00\x00G\xf7\x85\xe0\x00\x00\x00\x00H\xde<`\x00\x00\x00\x00I\xd7g\xe0\x00\x00\x00\x00J\xbe\x1e`\x00\x00\x00\x00K\xb7I" + + "\xe0\x00\x00\x00\x00L\x9e\x00`\x00\x00\x00\x00M\x97+\xe0\x00\x00\x00\x00N}\xe2`\x00\x00\x00\x00Ow\r\xe0\x00\x00\x00\x00Pf\xfe\xe0\x00\x00\x00\x00Q`*`\x00\x00\x00\x00RF\xe0\xe0\x00\x00\x00" + + "\x00S@\f`\x00\x00\x00\x00T&\xc2\xe0\x00\x00\x00\x00U\x1f\xee`\x00\x00\x00\x00V\x06\xa4\xe0\x00\x00\x00\x00V\xff\xd0`\x00\x00\x00\x00W\xe6\x86\xe0\x00\x00\x00\x00X߲`\x00\x00\x00\x00Y\xc6h" + + "\xe0\x00\x00\x00\x00Z\xbf\x94`\x00\x00\x00\x00[\xaf\x85`\x00\x00\x00\x00\\\xa8\xb0\xe0\x00\x00\x00\x00]\x8fg`\x00\x00\x00\x00^\x88\x92\xe0\x00\x00\x00\x00_oI`\x00\x00\x00\x00`ht\xe0\x00\x00\x00" + + "\x00aO+`\x00\x00\x00\x00bHV\xe0\x00\x00\x00\x00c/\r`\x00\x00\x00\x00d(8\xe0\x00\x00\x00\x00e\x0e\xef`\x00\x00\x00\x00f\x11U`\x00\x00\x00\x00f\xf8\v\xe0\x00\x00\x00\x00g\xf17" + + "`\x00\x00\x00\x00h\xd7\xed\xe0\x00\x00\x00\x00i\xd1\x19`\x00\x00\x00\x00j\xb7\xcf\xe0\x00\x00\x00\x00k\xb0\xfb`\x00\x00\x00\x00l\x97\xb1\xe0\x00\x00\x00\x00m\x90\xdd`\x00\x00\x00\x00nw\x93\xe0\x00\x00\x00" + + "\x00op\xbf`\x00\x00\x00\x00p`\xb0`\x00\x00\x00\x00qY\xdb\xe0\x00\x00\x00\x00r@\x92`\x00\x00\x00\x00s9\xbd\xe0\x00\x00\x00\x00t t`\x00\x00\x00\x00u\x19\x9f\xe0\x00\x00\x00\x00v\x00V" + + "`\x00\x00\x00\x00v\xf9\x81\xe0\x00\x00\x00\x00w\xe08`\x00\x00\x00\x00x\xd9c\xe0\x00\x00\x00\x00y\xc0\x1a`\x00\x00\x00\x00z\xb9E\xe0\x00\x00\x00\x00{\xa96\xe0\x00\x00\x00\x00|\xa2b`\x00\x00\x00" + + "\x00}\x89\x18\xe0\x00\x00\x00\x00~\x82D`\x00\x00\x00\x00\u007fh\xfa\xe0\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x06\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x00\x00\xa3" + + "\xd8\x00\x00\x00\x00\xaf\xc8\x01\x04\x00\x00\xa1\xb8\x00\t\x00\x00\xa8\xc0\x01\x04\x00\x00\xb6\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04\x00\x00\xa8\xc0\x00\x04LMT\x00NZST\x00NZMT\x00NZDT\x00\x00\x00" + + "\x00\x00\x01\x01\x00\nNZST-12NZDT,M9.5.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP{\x9d0U\x14\b\x00\x00\x14\b\x00\x00" + + "\a\x00\x1c\x00NZ-CHATUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x82\x00\x00\x00\x05\x00\x00\x00\x16\x80\x00\x00\x00\xd2ږ\xbc\t\x18\xfd\xe0\t\xac\xa5\xe0\n\xef\xa5`\v\x9e\xfc\xe0\f\xd8\xc1\xe0\r~\xde\xe0\x0e\xb8\xa3\xe0\x0f" + + "^\xc0\xe0\x10\x98\x85\xe0\x11>\xa2\xe0\x12xg\xe0\x13\x1e\x84\xe0\x14XI\xe0\x14\xfef\xe0\x168+\xe0\x16\xe7\x83`\x18!H`\x18\xc7e`\x1a\x01*`\x1a\xa7G`\x1b\xe1\f`\x1c\x87)`\x1d" + + "\xc0\xee`\x1eg\v`\x1f\xa0\xd0` F\xed`!\x80\xb2`\"0\t\xe0#i\xce\xe0$\x0f\xeb\xe0%.\x01`&\x02B\xe0'\r\xe3`'\xe2$\xe0(\xed\xc5`)\xc2\x06\xe0*ͧ`+" + + "\xab#`,\xad\x89`-\x8b\x05`.\x8dk`/j\xe7`0mM`1J\xc9`2Vi\xe03*\xab`46K\xe05\n\x8d`6\x16-\xe06\xf3\xa9\xe07\xf6\x0f\xe08Ӌ\xe09" + + "\xd5\xf1\xe0:\xb3m\xe0;\xbf\x0e`<\x93O\xe0=\x9e\xf0`>s1\xe0?~\xd2`@\\N`A^\xb4`B<0`C>\x96`D\x1c\x12`E\x1ex`E\xfb\xf4`F\xfeZ`G" + + "\xf7\x85\xe0H\xde<`I\xd7g\xe0J\xbe\x1e`K\xb7I\xe0L\x9e\x00`M\x97+\xe0N}\xe2`Ow\r\xe0Pf\xfe\xe0Q`*`RF\xe0\xe0S@\f`T&\xc2\xe0U\x1f\xee`V" + + "\x06\xa4\xe0V\xff\xd0`W\xe6\x86\xe0X߲`Y\xc6h\xe0Z\xbf\x94`[\xaf\x85`\\\xa8\xb0\xe0]\x8fg`^\x88\x92\xe0_oI``ht\xe0aO+`bHV\xe0c/\r`d" + + "(8\xe0e\x0e\xef`f\x11U`f\xf8\v\xe0g\xf17`h\xd7\xed\xe0i\xd1\x19`j\xb7\xcf\xe0k\xb0\xfb`l\x97\xb1\xe0m\x90\xdd`nw\x93\xe0op\xbf`p`\xb0`qY\xdb\xe0r" + + "@\x92`s9\xbd\xe0t t`u\x19\x9f\xe0v\x00V`v\xf9\x81\xe0w\xe08`x\xd9c\xe0y\xc0\x1a`z\xb9E\xe0{\xa96\xe0|\xa2b`}\x89\x18\xe0~\x82D`\u007fh\xfa\xe0\u007f" + + "\xff\xff\xff\x01\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x00\x00\xab\xfc\x00\x00\x00\x00\xacD\x00\x04\x00\x00\xc1\\\x01\n\x00\x00\xb3L\x00\x10\x00\x00\xb3L\x00\x10LMT\x00+1215\x00+1345\x00+" + + "1245\x00\x00\x00\x01\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x82\x00\x00\x00\x05\x00\x00\x00\x16\xff\xff\xff\xffA\xb7" + + "D\x84\xff\xff\xff\xff\xd2ږ\xbc\x00\x00\x00\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v\x9e\xfc\xe0\x00\x00\x00\x00\f\xd8\xc1\xe0\x00\x00\x00\x00\r~\xde\xe0\x00\x00" + + "\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfe" + + "f\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\f`\x00\x00" + + "\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\"0\t\xe0\x00\x00\x00\x00#i" + + "\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00" + + "\x00\x00*ͧ`\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x001J" + + "\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00" + + "\x00\x008Ӌ\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~" + + "\xd2`\x00\x00\x00\x00@\\N`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00" + + "\x00\x00F\xfeZ`\x00\x00\x00\x00G\xf7\x85\xe0\x00\x00\x00\x00H\xde<`\x00\x00\x00\x00I\xd7g\xe0\x00\x00\x00\x00J\xbe\x1e`\x00\x00\x00\x00K\xb7I\xe0\x00\x00\x00\x00L\x9e\x00`\x00\x00\x00\x00M\x97" + + "+\xe0\x00\x00\x00\x00N}\xe2`\x00\x00\x00\x00Ow\r\xe0\x00\x00\x00\x00Pf\xfe\xe0\x00\x00\x00\x00Q`*`\x00\x00\x00\x00RF\xe0\xe0\x00\x00\x00\x00S@\f`\x00\x00\x00\x00T&\xc2\xe0\x00\x00" + + "\x00\x00U\x1f\xee`\x00\x00\x00\x00V\x06\xa4\xe0\x00\x00\x00\x00V\xff\xd0`\x00\x00\x00\x00W\xe6\x86\xe0\x00\x00\x00\x00X߲`\x00\x00\x00\x00Y\xc6h\xe0\x00\x00\x00\x00Z\xbf\x94`\x00\x00\x00\x00[\xaf" + + "\x85`\x00\x00\x00\x00\\\xa8\xb0\xe0\x00\x00\x00\x00]\x8fg`\x00\x00\x00\x00^\x88\x92\xe0\x00\x00\x00\x00_oI`\x00\x00\x00\x00`ht\xe0\x00\x00\x00\x00aO+`\x00\x00\x00\x00bHV\xe0\x00\x00" + + "\x00\x00c/\r`\x00\x00\x00\x00d(8\xe0\x00\x00\x00\x00e\x0e\xef`\x00\x00\x00\x00f\x11U`\x00\x00\x00\x00f\xf8\v\xe0\x00\x00\x00\x00g\xf17`\x00\x00\x00\x00h\xd7\xed\xe0\x00\x00\x00\x00i\xd1" + + "\x19`\x00\x00\x00\x00j\xb7\xcf\xe0\x00\x00\x00\x00k\xb0\xfb`\x00\x00\x00\x00l\x97\xb1\xe0\x00\x00\x00\x00m\x90\xdd`\x00\x00\x00\x00nw\x93\xe0\x00\x00\x00\x00op\xbf`\x00\x00\x00\x00p`\xb0`\x00\x00" + + "\x00\x00qY\xdb\xe0\x00\x00\x00\x00r@\x92`\x00\x00\x00\x00s9\xbd\xe0\x00\x00\x00\x00t t`\x00\x00\x00\x00u\x19\x9f\xe0\x00\x00\x00\x00v\x00V`\x00\x00\x00\x00v\xf9\x81\xe0\x00\x00\x00\x00w\xe0" + + "8`\x00\x00\x00\x00x\xd9c\xe0\x00\x00\x00\x00y\xc0\x1a`\x00\x00\x00\x00z\xb9E\xe0\x00\x00\x00\x00{\xa96\xe0\x00\x00\x00\x00|\xa2b`\x00\x00\x00\x00}\x89\x18\xe0\x00\x00\x00\x00~\x82D`\x00\x00" + + "\x00\x00\u007fh\xfa\xe0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x00\x00\xab\xfc\x00\x00\x00\x00\xacD\x00\x04\x00\x00\xc1\\\x01\n\x00\x00\xb3L\x00\x10\x00\x00\xb3L\x00\x10LMT\x00+1" + + "215\x00+1345\x00+1245\x00\x00\x00\x01\x01\x00\n<+1245>-12:45<+1345>,M9.5.0/2:45,M4.1." + + "0/3:45\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc41\xb4\x85\x8c\t\x00\x00\x8c\t\x00\x00\x06\x00\x1c\x00NavajoUT\t\x00\x03nӧ^nӧ^ux\v\x00" + + "\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x9e\x00\x00\x00\x05\x00\x00\x00\x14\x80\x00\x00\x00\x9e" + + "\xa6:\x90\x9f\xbb\a\x80\xa0\x86\x1c\x90\xa1\x9a逢e\xfe\x90\xa3\x84\x06\x00\xa4E\xe0\x90\xa4\x8f\xa6\x80ˉ\f\x90\xd2#\xf4p\xd2a\x18\x00\xf7/v\x90\xf8(\x94\x00\xf9\x0fX\x90\xfa\bv\x00\xfa" + + "\xf8u\x10\xfb\xe8X\x00\xfc\xd8W\x10\xfd\xc8:\x00\xfe\xb89\x10\xff\xa8\x1c\x00\x00\x98\x1b\x10\x01\x87\xfe\x00\x02w\xfd\x10\x03q\x1a\x80\x04a\x19\x90\x05P\xfc\x80\x06@\xfb\x90\a0ހ\a\x8d5\x90\t" + + "\x10\xc0\x80\t\xad\xb1\x10\n\xf0\xa2\x80\vࡐ\fٿ\x00\r\xc0\x83\x90\x0e\xb9\xa1\x00\x0f\xa9\xa0\x10\x10\x99\x83\x00\x11\x89\x82\x10\x12ye\x00\x13id\x10\x14YG\x00\x15IF\x10\x169)\x00\x17" + + ")(\x10\x18\"E\x80\x19\t\n\x10\x1a\x02'\x80\x1a\xf2&\x90\x1b\xe2\t\x80\x1c\xd2\b\x90\x1d\xc1\xeb\x80\x1e\xb1\xea\x90\x1f\xa1̀ v\x1d\x10!\x81\xaf\x80\"U\xff\x10#j\xcc\x00$5\xe1\x10%" + + "J\xae\x00&\x15\xc3\x10'*\x90\x00'\xfeߐ)\nr\x00)\xde\xc1\x90*\xeaT\x00+\xbe\xa3\x90,\xd3p\x80-\x9e\x85\x90.\xb3R\x80/~g\x900\x934\x801g\x84\x102s\x16\x803" + + "Gf\x104R\xf8\x805'H\x1062ڀ7\a*\x108\x1b\xf7\x008\xe7\f\x109\xfb\xd9\x00:\xc6\xee\x10;ۻ\x00<\xb0\n\x90=\xbb\x9d\x00>\x8f\xec\x90?\x9b\u007f\x00@oΐA" + + "\x84\x9b\x80BO\xb0\x90Cd}\x80D/\x92\x90ED_\x80E\xf3\xc5\x10G-|\x00Gӧ\x10I\r^\x00I\xb3\x89\x10J\xed@\x00K\x9c\xa5\x90L\xd6\\\x80M|\x87\x90N\xb6>\x80O" + + "\\i\x90P\x96 \x80Q\x8f\xec\x90\x00\x00\x00\x00?\x9b\u007f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00" + + "\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x00\x00\x00\x00G-|\x00\x00\x00\x00\x00Gӧ" + + "\x10\x00\x00\x00\x00I\r^\x00\x00\x00\x00\x00I\xb3\x89\x10\x00\x00\x00\x00J\xed@\x00\x00\x00\x00\x00K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\\\x80\x00\x00\x00\x00M|\x87\x90\x00\x00\x00\x00N\xb6>\x80\x00\x00\x00" + + "\x00O\\i\x90\x00\x00\x00\x00P\x96 \x80\x00\x00\x00\x00Q\xf0Ӌ{\x80\xd4B\xad\xf0\xd5E\"\x00\xd6L\xbf\xf0\xd7<\xbf\x00\xd8\x06fp\xd9\x1d\xf2\x80\xd9A|\xf0\x1e\xbaR \x1fi\x9b\x90 ~\x84\xa0" + + "!I}\x90\"g\xa1 #)_\x90$G\x83 %\x12|\x10&'e &\xf2^\x10(\aG (\xd2@\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\bLMT\x00CDT\x00CST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff~6C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff\xff\xa1y\x04\xf0\xff\xff\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9\t\xf9p\xff" + + "\xff\xff\xff\xc9ӽ\x00\xff\xff\xff\xff\xcb\x05\x8a\xf0\xff\xff\xff\xff\xcb|@\x00\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xffӋ{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6" + + "L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00\x00\x1e\xbaR \x00\x00\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 ~\x84\xa0\x00" + + "\x00\x00\x00!I}\x90\x00\x00\x00\x00\"g\xa1 \x00\x00\x00\x00#)_\x90\x00\x00\x00\x00$G\x83 \x00\x00\x00\x00%\x12|\x10\x00\x00\x00\x00&'e \x00\x00\x00\x00&\xf2^\x10\x00\x00\x00\x00(" + + "\aG \x00\x00\x00\x00(\xd2@\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\bLM" + + "T\x00CDT\x00CST\x00\nCST-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb0\xf39\xa3\x06\t\x00\x00\x06\t\x00\x00\a\x00\x1c\x00PST8PDTUT\t\x00\x03n" + + "ӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x95\x00\x00" + + "\x00\x05\x00\x00\x00\x10\x9e\xa6H\xa0\x9f\xbb\x15\x90\xa0\x86*\xa0\xa1\x9a\xf7\x90ˉ\x1a\xa0\xd2#\xf4p\xd2a&\x10\xfa\xf8\x83 \xfb\xe8f\x10\xfc\xd8e \xfd\xc8H\x10\xfe\xb8G \xff\xa8*\x10\x00\x98" + + ") \x01\x88\f\x10\x02x\v \x03q(\x90\x04a'\xa0\x05Q\n\x90\x06A\t\xa0\a0\xec\x90\a\x8dC\xa0\t\x10ΐ\t\xad\xbf \n\xf0\xb0\x90\v\u0be0\f\xd9\xcd\x10\r\xc0\x91\xa0\x0e\xb9" + + "\xaf\x10\x0f\xa9\xae \x10\x99\x91\x10\x11\x89\x90 \x12ys\x10\x13ir \x14YU\x10\x15IT \x1697\x10\x17)6 \x18\"S\x90\x19\t\x18 \x1a\x025\x90\x1a\xf24\xa0\x1b\xe2\x17\x90\x1c\xd2" + + "\x16\xa0\x1d\xc1\xf9\x90\x1e\xb1\xf8\xa0\x1f\xa1ې v+ !\x81\xbd\x90\"V\r #j\xda\x10$5\xef %J\xbc\x10&\x15\xd1 '*\x9e\x10'\xfe\xed\xa0)\n\x80\x10)\xdeϠ*\xea" + + "b\x10+\xbe\xb1\xa0,\xd3~\x90-\x9e\x93\xa0.\xb3`\x90/~u\xa00\x93B\x901g\x92 2s$\x903Gt 4S\x06\x905'V 62\xe8\x907\a8 8\x1c\x05\x108\xe7" + + "\x1a 9\xfb\xe7\x10:\xc6\xfc ;\xdb\xc9\x10<\xb0\x18\xa0=\xbb\xab\x10>\x8f\xfa\xa0?\x9b\x8d\x10@oܠA\x84\xa9\x90BO\xbe\xa0Cd\x8b\x90D/\xa0\xa0EDm\x90E\xf3\xd3 G-" + + "\x8a\x10Gӵ I\rl\x10I\xb3\x97 J\xedN\x10K\x9c\xb3\xa0L\xd6j\x90M|\x95\xa0N\xb6L\x90O\\w\xa0P\x96.\x90Q\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00" + + "\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x00\x00\x00\x00G" + + "-\x8a\x10\x00\x00\x00\x00Gӵ \x00\x00\x00\x00I\rl\x10\x00\x00\x00\x00I\xb3\x97 \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00M|\x95\xa0\x00" + + "\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\\w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q-10\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPN\xaexD\r\x01\x00\x00\r\x01\x00\x00\r\x00\x1c\x00Pacific/" + + "ChuukUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\f\x80\x00\x00\x00\x98\x11\xa3\xe0\xa09\xf9\xf0\xc9\xea\n`\xd2\x11\x0e\xf0\u007f\xff\xff\xff\x01\x02\x01\x02\x01\x01\xff\xff<\xcc\x00\x00\x00\x00\x8c\xa0\x00\x04\x00" + + "\x00~\x90\x00\b\x00\x00\x8c\xa0\x00\x04LMT\x00+10\x00+09\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00" + + "\x00\x00\x05\x00\x00\x00\f\xff\xff\xff\xff\x14\xe1\xbf4\xff\xff\xff\xff~6&\xb4\xff\xff\xff\xff\x98\x11\xa3\xe0\xff\xff\xff\xff\xa09\xf9\xf0\xff\xff\xff\xff\xc9\xea\n`\xff\xff\xff\xff\xd2\x11\x0e\xf0\x00\x00\x00\x00\u007f" + + "\xff\xff\xff\x01\x02\x03\x02\x03\x02\x02\xff\xff<\xcc\x00\x00\x00\x00\x8eL\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x00\x04LMT\x00+10\x00+09\x00\n<+10>-1" + + "0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x97+τ\xb9\b\x00\x00\xb9\b\x00\x00\x0e\x00\x1c\x00Pacific/EasterUT\t\x00\x03nӧ^nӧ^u" + + "x\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x8c\x00\x00\x00\a\x00\x00\x00\x14\x80\x00" + + "\x00\x00\xb9\xc7@\x88\xfd\xd1<@\xfe\x92\xfa\xb0\xff\xcc\xcd\xc0\x00rܰ\x01uP\xc0\x02@I\xb0\x03U2\xc0\x04 +\xb0\x05>O@\x06\x00\r\xb0\a\v\xbc@\a\xdf\xef\xb0\b\xfe\x13@\t\xbf" + + "Ѱ\n\xdd\xf5@\v\xa8\xee0\f\xbd\xd7@\r\x88\xd00\x0e\x9d\xb9@\x0fh\xb20\x10\x86\xd5\xc0\x11H\x940\x12f\xb7\xc0\x13(v0\x14F\x99\xc0\x15\x11\x92\xb0\x16&{\xc0\x16\xf1t\xb0\x18\x06" + + "]\xc0\x18\xd1V\xb0\x19\xe6?\xc0\x1a\xb18\xb0\x1b\xcf\\@\x1c\x91\x1a\xb0\x1d\xaf>@\x1ep\xfc\xb0\x1f\x8f @ \u007f\x030!o\x02@\"9\xfb0#N\xe4@$\x19\xdd0%8\x00\xc0%\xf9" + + "\xbf0&\xf2\xf8\xc0'١0(\xf7\xc4\xc0)½\xb0*צ\xc0+\xa2\x9f\xb0,\xb7\x88\xc0-\x82\x81\xb0.\x97j\xc0/bc\xb00\x80\x87@1BE\xb02`i@3=\xd704@" + + "K@5\vD06\r\xb8@7\x06հ8\x00\x0f@8\xcb\b09\xe9+\xc0:\xaa\xea0;\xc9\r\xc0<\x8a\xcc0=\xa8\xef\xc0>j\xae0?\x88\xd1\xc0@SʰAh\xb3\xc0B3" + + "\xac\xb0CH\x95\xc0D\x13\x8e\xb0E1\xb2@E\xf3p\xb0G\x11\x94@G\xef\x020H\xf1v@I\xbco0J\xd1X@K\xb8\x00\xb0L\xb1:@M\xc6\a0NP\x82\xc0O\x9c\xae\xb0PB" + + "\xd9\xc0Q|\x90\xb0R+\xf6@S\\r\xb0T\v\xd8@W7\xe60W\xaf\xec\xc0Y\x17\xc80Y\x8f\xce\xc0Z\xf7\xaa0[o\xb0\xc0\\\xa9g\xb0]t|\xc0^\x89I\xb0_T^\xc0`i" + + "+\xb0a4@\xc0bI\r\xb0c\x14\"\xc0d(\xef\xb0d\xf4\x04\xc0f\x12\f0f\xdd!@g\xf1\xee0h\xbd\x03@i\xd1\xd00j\x9c\xe5@k\xb1\xb20l|\xc7@m\x91\x940n\\" + + "\xa9@oz\xb0\xb0p<\x8b@qZ\x92\xb0r%\xa7\xc0s:t\xb0t\x05\x89\xc0u\x1aV\xb0u\xe5k\xc0v\xfa8\xb0w\xc5M\xc0x\xda\x1a\xb0y\xa5/\xc0z\xc370{\x85\x11\xc0|\xa3" + + "\x190}n.@~\x82\xfb0\u007fN\x10@\u007f\xff\xff\xff\x01\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x06\xff\xff\x99x\x00\x00\xff\xff\x99x\x00\x04\xff\xff\xab\xa0\x01\b\xff\xff\x9d\x90" + + "\x00\f\xff\xff\x9d\x90\x00\f\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\x10LMT\x00EMT\x00-06\x00-07\x00-05\x00\x00\x00\x01\x01\x00\x01\x01\x00\x00\x01\x01\x00\x01\x01TZif3\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x8c\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xffi\x87B\b\xff\xff\xff\xff\xb9\xc7@\x88\xff\xff\xff\xff\xfd\xd1" + + "<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00\x00\x00\x00rܰ\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00\x02@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +\xb0\x00\x00" + + "\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\r\xb0\x00\x00\x00\x00\a\v\xbc@\x00\x00\x00\x00\a\xdf\xef\xb0\x00\x00\x00\x00\b\xfe\x13@\x00\x00\x00\x00\t\xbfѰ\x00\x00\x00\x00\n\xdd\xf5@\x00\x00\x00\x00\v\xa8" + + "\xee0\x00\x00\x00\x00\f\xbd\xd7@\x00\x00\x00\x00\r\x88\xd00\x00\x00\x00\x00\x0e\x9d\xb9@\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00\x10\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00" + + "\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11\x92\xb0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6" + + "?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \u007f\x030\x00\x00" + + "\x00\x00!o\x02@\x00\x00\x00\x00\"9\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'\xd9" + + "\xa10\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)½\xb0\x00\x00\x00\x00*צ\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00" + + "\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\vD0\x00\x00\x00\x006\r" + + "\xb8@\x00\x00\x00\x007\x06հ\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\b0\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00" + + "\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@Sʰ\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13" + + "\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00" + + "\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\a0\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+" + + "\xf6@\x00\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T\v\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00Y\x17\xc80\x00\x00\x00\x00Y\x8f\xce\xc0\x00\x00\x00\x00Z\xf7\xaa0\x00\x00" + + "\x00\x00[o\xb0\xc0\x00\x00\x00\x00\\\xa9g\xb0\x00\x00\x00\x00]t|\xc0\x00\x00\x00\x00^\x89I\xb0\x00\x00\x00\x00_T^\xc0\x00\x00\x00\x00`i+\xb0\x00\x00\x00\x00a4@\xc0\x00\x00\x00\x00bI" + + "\r\xb0\x00\x00\x00\x00c\x14\"\xc0\x00\x00\x00\x00d(\xef\xb0\x00\x00\x00\x00d\xf4\x04\xc0\x00\x00\x00\x00f\x12\f0\x00\x00\x00\x00f\xdd!@\x00\x00\x00\x00g\xf1\xee0\x00\x00\x00\x00h\xbd\x03@\x00\x00" + + "\x00\x00i\xd1\xd00\x00\x00\x00\x00j\x9c\xe5@\x00\x00\x00\x00k\xb1\xb20\x00\x00\x00\x00l|\xc7@\x00\x00\x00\x00m\x91\x940\x00\x00\x00\x00n\\\xa9@\x00\x00\x00\x00oz\xb0\xb0\x00\x00\x00\x00p<" + + "\x8b@\x00\x00\x00\x00qZ\x92\xb0\x00\x00\x00\x00r%\xa7\xc0\x00\x00\x00\x00s:t\xb0\x00\x00\x00\x00t\x05\x89\xc0\x00\x00\x00\x00u\x1aV\xb0\x00\x00\x00\x00u\xe5k\xc0\x00\x00\x00\x00v\xfa8\xb0\x00\x00" + + "\x00\x00w\xc5M\xc0\x00\x00\x00\x00x\xda\x1a\xb0\x00\x00\x00\x00y\xa5/\xc0\x00\x00\x00\x00z\xc370\x00\x00\x00\x00{\x85\x11\xc0\x00\x00\x00\x00|\xa3\x190\x00\x00\x00\x00}n.@\x00\x00\x00\x00~\x82" + + "\xfb0\x00\x00\x00\x00\u007fN\x10@\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x06\xff\xff\x99x\x00\x00\xff\xff\x99x\x00\x04\xff\xff\xab\xa0\x01\b\xff\xff\x9d\x90" + + "\x00\f\xff\xff\x9d\x90\x00\f\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\x10LMT\x00EMT\x00-06\x00-07\x00-05\x00\x00\x00\x01\x01\x00\x01\x01\x00\x00\x01\x01\x00\x01\x01\n<-06>" + + "6<-05>,M9.1.6/22,M4.1.6/22\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x03|\x89\xf2<\x01\x00\x00<\x01\x00\x00\x11\x00\x1c\x00Pac" + + "ific/KwajaleinUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x06\x00\x00\x00\x18\x80\x00\x00\x00\xc1\xed5\xd0\xc9\xea\n`\xcfF\x81\xf0\xff\x86\x1bP,v\x0e@\u007f\xff\xff\xff\x01\x02\x03\x01\x04\x05" + + "\x05\x00\x00\x9c\xe0\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00\x8c\xa0\x00\b\x00\x00~\x90\x00\f\xff\xffW@\x00\x10\x00\x00\xa8\xc0\x00\x14LMT\x00+11\x00+10\x00+09\x00-12\x00+12" + + "\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff~6\x18 \xff\xff\xff\xff\xc1\xed5" + + "\xd0\xff\xff\xff\xff\xc9\xea\n`\xff\xff\xff\xff\xcfF\x81\xf0\xff\xff\xff\xff\xff\x86\x1bP\x00\x00\x00\x00,v\x0e@\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x01\x04\x05\x05\x00\x00\x9c\xe0\x00\x00\x00\x00\x9a\xb0\x00\x04" + + "\x00\x00\x8c\xa0\x00\b\x00\x00~\x90\x00\f\xff\xffW@\x00\x10\x00\x00\xa8\xc0\x00\x14LMT\x00+11\x00+10\x00+09\x00-12\x00+12\x00\n<+12>-12\nPK" + + "\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa2\xee;+t\x01\x00\x00t\x01\x00\x00\x11\x00\x1c\x00Pacific/TongatapuUT\t\x00\x03nӧ^nӧ^ux" + + "\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x06\x00\x00\x00\x12\x80\x00\x00" + + "\x00\xc9sB\x907\xfbG\xd08\xd3}\xd0:\x04\bP:r\xb8@;\xe3\xeaP-13\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPN\xaexD\r\x01\x00\x00\r\x01\x00\x00\v\x00\x1c\x00Pacif" + + "ic/YapUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\f\x80\x00\x00\x00\x98\x11\xa3\xe0\xa09\xf9\xf0\xc9\xea\n`\xd2\x11\x0e\xf0\u007f\xff\xff\xff\x01\x02\x01\x02\x01\x01\xff\xff<\xcc\x00\x00\x00\x00\x8c\xa0\x00\x04" + + "\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x00\x04LMT\x00+10\x00+09\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a" + + "\x00\x00\x00\x05\x00\x00\x00\f\xff\xff\xff\xff\x14\xe1\xbf4\xff\xff\xff\xff~6&\xb4\xff\xff\xff\xff\x98\x11\xa3\xe0\xff\xff\xff\xff\xa09\xf9\xf0\xff\xff\xff\xff\xc9\xea\n`\xff\xff\xff\xff\xd2\x11\x0e\xf0\x00\x00\x00\x00" + + "\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x02\xff\xff<\xcc\x00\x00\x00\x00\x8eL\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x00\x04LMT\x00+10\x00+09\x00\n<+10>-" + + "10\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP~\x9eԨ\xa6\x00\x00\x00\xa6\x00\x00\x00\x0e\x00\x1c\x00Pacific/WallisUT\t\x00\x03nӧ^nӧ^" + + "ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\x80" + + "\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x00\xacX\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff~6\b\xa8\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x00\xacX\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00\n<+12>-12" + + "\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP:\f\xd7WI\x04\x00\x00I\x04\x00\x00\f\x00\x1c\x00Pacific/ApiaUT\t\x00\x03nӧ^nӧ^ux\v\x00" + + "\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\a\x00\x00\x00\x1a\x80\x00\x00\x00\x91" + + "\x05\xfc\x00\xdab\x048L\x9f'\xb0M\x97+\xe0N}\xe2`N\xfd\x8b\xa0Ow\r\xe0Pf\xfe\xe0Q`*`RF\xe0\xe0S@\f`T&\xc2\xe0U\x1f\xee`V\x06\xa4\xe0V\xff\xd0`W" + + "\xe6\x86\xe0X߲`Y\xc6h\xe0Z\xbf\x94`[\xaf\x85`\\\xa8\xb0\xe0]\x8fg`^\x88\x92\xe0_oI``ht\xe0aO+`bHV\xe0c/\r`d(8\xe0e\x0e\xef`f" + + "\x11U`f\xf8\v\xe0g\xf17`h\xd7\xed\xe0i\xd1\x19`j\xb7\xcf\xe0k\xb0\xfb`l\x97\xb1\xe0m\x90\xdd`nw\x93\xe0op\xbf`p`\xb0`qY\xdb\xe0r@\x92`s9\xbd\xe0t" + + " t`u\x19\x9f\xe0v\x00V`v\xf9\x81\xe0w\xe08`x\xd9c\xe0y\xc0\x1a`z\xb9E\xe0{\xa96\xe0|\xa2b`}\x89\x18\xe0~\x82D`\u007fh\xfa\xe0\u007f\xff\xff\xff\x01\x02\x04\x03\x04" + + "\x03\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x06\x00\x00\xb0\x80\x00" + + "\x00\xff\xff_\x00\x00\x00\xff\xff^H\x00\x04\xff\xffs`\x01\n\xff\xffeP\x00\x0e\x00\x00\xb6\xd0\x00\x12\x00\x00\xc4\xe0\x01\x16LMT\x00-1130\x00-10\x00-11\x00+13\x00+" + + "14\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\a\x00\x00\x00\x1a\xff\xff\xff\xffn=\xc9\x00\xff\xff\xff\xff\x91" + + "\x05\xfc\x00\xff\xff\xff\xff\xdab\x048\x00\x00\x00\x00L\x9f'\xb0\x00\x00\x00\x00M\x97+\xe0\x00\x00\x00\x00N}\xe2`\x00\x00\x00\x00N\xfd\x8b\xa0\x00\x00\x00\x00Ow\r\xe0\x00\x00\x00\x00Pf\xfe\xe0\x00" + + "\x00\x00\x00Q`*`\x00\x00\x00\x00RF\xe0\xe0\x00\x00\x00\x00S@\f`\x00\x00\x00\x00T&\xc2\xe0\x00\x00\x00\x00U\x1f\xee`\x00\x00\x00\x00V\x06\xa4\xe0\x00\x00\x00\x00V\xff\xd0`\x00\x00\x00\x00W" + + "\xe6\x86\xe0\x00\x00\x00\x00X߲`\x00\x00\x00\x00Y\xc6h\xe0\x00\x00\x00\x00Z\xbf\x94`\x00\x00\x00\x00[\xaf\x85`\x00\x00\x00\x00\\\xa8\xb0\xe0\x00\x00\x00\x00]\x8fg`\x00\x00\x00\x00^\x88\x92\xe0\x00" + + "\x00\x00\x00_oI`\x00\x00\x00\x00`ht\xe0\x00\x00\x00\x00aO+`\x00\x00\x00\x00bHV\xe0\x00\x00\x00\x00c/\r`\x00\x00\x00\x00d(8\xe0\x00\x00\x00\x00e\x0e\xef`\x00\x00\x00\x00f" + + "\x11U`\x00\x00\x00\x00f\xf8\v\xe0\x00\x00\x00\x00g\xf17`\x00\x00\x00\x00h\xd7\xed\xe0\x00\x00\x00\x00i\xd1\x19`\x00\x00\x00\x00j\xb7\xcf\xe0\x00\x00\x00\x00k\xb0\xfb`\x00\x00\x00\x00l\x97\xb1\xe0\x00" + + "\x00\x00\x00m\x90\xdd`\x00\x00\x00\x00nw\x93\xe0\x00\x00\x00\x00op\xbf`\x00\x00\x00\x00p`\xb0`\x00\x00\x00\x00qY\xdb\xe0\x00\x00\x00\x00r@\x92`\x00\x00\x00\x00s9\xbd\xe0\x00\x00\x00\x00t" + + " t`\x00\x00\x00\x00u\x19\x9f\xe0\x00\x00\x00\x00v\x00V`\x00\x00\x00\x00v\xf9\x81\xe0\x00\x00\x00\x00w\xe08`\x00\x00\x00\x00x\xd9c\xe0\x00\x00\x00\x00y\xc0\x1a`\x00\x00\x00\x00z\xb9E\xe0\x00" + + "\x00\x00\x00{\xa96\xe0\x00\x00\x00\x00|\xa2b`\x00\x00\x00\x00}\x89\x18\xe0\x00\x00\x00\x00~\x82D`\x00\x00\x00\x00\u007fh\xfa\xe0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x04\x03\x04\x03\x06\x05\x06\x05\x06\x05\x06" + + "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x06\x00\x00\xb0\x80\x00\x00\xff\xff_\x00\x00\x00\xff" + + "\xff^H\x00\x04\xff\xffs`\x01\n\xff\xffeP\x00\x0e\x00\x00\xb6\xd0\x00\x12\x00\x00\xc4\xe0\x01\x16LMT\x00-1130\x00-10\x00-11\x00+13\x00+14\x00\n<+13" + + ">-13<+14>,M9.5.0/3,M4.1.0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xddnO\np\x03\x00\x00p\x03\x00\x00\x0f\x00\x1c\x00Pa" + + "cific/NorfolkUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00\a\x00\x00\x00\x1e\x80\x00\x00\x00\xdcA\xf8\x80\t\x0f\xcah\t\xb5\xe7hV\x0f\xe6h]\x98\xaf\xf0^\x88\xa0\xf0_x\x91\xf0`h\x82" + + "\xf0aXs\xf0bHd\xf0c8U\xf0d(F\xf0e\x187\xf0f\x11cpg\x01Tpg\xf1Eph\xe16pi\xd1'pj\xc1\x18pk\xb1\tpl\xa0\xfapm\x90\xebpn\x80\xdc" + + "pop\xcdppi\xf8\xf0qY\xe9\xf0rI\xda\xf0s9\xcb\xf0t)\xbc\xf0u\x19\xad\xf0v\t\x9e\xf0v\xf9\x8f\xf0w\xe9\x80\xf0x\xd9q\xf0y\xc9b\xf0z\xb9S\xf0{\xb2\u007fp|\xa2p" + + "p}\x92ap~\x82Rp\u007frCp\u007f\xff\xff\xff\x01\x02\x03\x04\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x06" + + "\x00\x00\x9dx\x00\x00\x00\x00\x9d\x80\x00\x04\x00\x00\xa1\xb8\x00\n\x00\x00\xaf\xc8\x01\x10\x00\x00\xa1\xb8\x00\n\x00\x00\x9a\xb0\x00\x16\x00\x00\xa8\xc0\x01\x1aLMT\x00+1112\x00+1130\x00+1" + + "230\x00+11\x00+12\x00\x00\x00\x00\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00\a\x00" + + "\x00\x00\x1e\xff\xff\xff\xff~6\x17\x88\xff\xff\xff\xff\xdcA\xf8\x80\x00\x00\x00\x00\t\x0f\xcah\x00\x00\x00\x00\t\xb5\xe7h\x00\x00\x00\x00V\x0f\xe6h\x00\x00\x00\x00]\x98\xaf\xf0\x00\x00\x00\x00^\x88\xa0\xf0\x00" + + "\x00\x00\x00_x\x91\xf0\x00\x00\x00\x00`h\x82\xf0\x00\x00\x00\x00aXs\xf0\x00\x00\x00\x00bHd\xf0\x00\x00\x00\x00c8U\xf0\x00\x00\x00\x00d(F\xf0\x00\x00\x00\x00e\x187\xf0\x00\x00\x00\x00f" + + "\x11cp\x00\x00\x00\x00g\x01Tp\x00\x00\x00\x00g\xf1Ep\x00\x00\x00\x00h\xe16p\x00\x00\x00\x00i\xd1'p\x00\x00\x00\x00j\xc1\x18p\x00\x00\x00\x00k\xb1\tp\x00\x00\x00\x00l\xa0\xfap\x00" + + "\x00\x00\x00m\x90\xebp\x00\x00\x00\x00n\x80\xdcp\x00\x00\x00\x00op\xcdp\x00\x00\x00\x00pi\xf8\xf0\x00\x00\x00\x00qY\xe9\xf0\x00\x00\x00\x00rI\xda\xf0\x00\x00\x00\x00s9\xcb\xf0\x00\x00\x00\x00t" + + ")\xbc\xf0\x00\x00\x00\x00u\x19\xad\xf0\x00\x00\x00\x00v\t\x9e\xf0\x00\x00\x00\x00v\xf9\x8f\xf0\x00\x00\x00\x00w\xe9\x80\xf0\x00\x00\x00\x00x\xd9q\xf0\x00\x00\x00\x00y\xc9b\xf0\x00\x00\x00\x00z\xb9S\xf0\x00" + + "\x00\x00\x00{\xb2\u007fp\x00\x00\x00\x00|\xa2pp\x00\x00\x00\x00}\x92ap\x00\x00\x00\x00~\x82Rp\x00\x00\x00\x00\u007frCp\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x04\x05\x06\x05\x06\x05\x06\x05\x06\x05" + + "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x06\x00\x00\x9dx\x00\x00\x00\x00\x9d\x80\x00\x04\x00\x00\xa1\xb8\x00\n\x00\x00\xaf\xc8\x01\x10\x00\x00\xa1\xb8\x00\n" + + "\x00\x00\x9a\xb0\x00\x16\x00\x00\xa8\xc0\x01\x1aLMT\x00+1112\x00+1130\x00+1230\x00+11\x00+12\x00\x00\x00\x00\x01\x01\x01\x01\n<+11>-11<+" + + "12>,M10.1.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x8b}\x1f-\xd2\x01\x00\x00\xd2\x01\x00\x00\r\x00\x1c\x00Pacific/E" + + "fateUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x03\x00\x00\x00\f\x92\xf5´\x19\xd2\xf7\xd0\x1a\xc2\xda\xc0\x1b\xdaf\xd0\x1c\xa2\xbc\xc0\x1d\x9b\xf6P\x1e\x82\x9e\xc0\x1f{\xd8P k\xbb@![\xbaP\"K\x9d@" + + "#;\x9cP$+\u007f@%\x1b~P&\va@&\xfb`P'\xebC@(\xe4|\xd0)\x81Q@*\xe9H\xd0+a3@\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x02\x00\x00\x9d\xcc\x00\x00\x00\x00\xa8\xc0\x01\x04\x00\x00\x9a\xb0\x00\bLMT\x00+12\x00+11\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x92\xf5´\x00\x00\x00\x00\x19\xd2\xf7\xd0\x00\x00\x00\x00\x1a\xc2\xda\xc0\x00\x00\x00\x00\x1b\xdaf\xd0\x00\x00\x00\x00\x1c\xa2\xbc\xc0" + + "\x00\x00\x00\x00\x1d\x9b\xf6P\x00\x00\x00\x00\x1e\x82\x9e\xc0\x00\x00\x00\x00\x1f{\xd8P\x00\x00\x00\x00 k\xbb@\x00\x00\x00\x00![\xbaP\x00\x00\x00\x00\"K\x9d@\x00\x00\x00\x00#;\x9cP\x00\x00\x00\x00" + + "$+\u007f@\x00\x00\x00\x00%\x1b~P\x00\x00\x00\x00&\va@\x00\x00\x00\x00&\xfb`P\x00\x00\x00\x00'\xebC@\x00\x00\x00\x00(\xe4|\xd0\x00\x00\x00\x00)\x81Q@\x00\x00\x00\x00*\xe9H\xd0" + + "\x00\x00\x00\x00+a3@\x00\x00\x00\x00\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x00\x00\x9d\xcc\x00\x00\x00\x00\xa8\xc0\x01\x04\x00\x00\x9a\xb0\x00\bLMT\x00" + + "+12\x00+11\x00\n<+11>-11\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPg\xf5\x05\xa35\x04\x00\x005\x04\x00\x00\f\x00\x1c\x00Pacific/Fiji" + + "UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00@\x00\x00\x00\x03\x00\x00\x00\f\x9a\x13\xb1\xc06;\x17\xe06\xd7\xfa`8$4`8\xb7\xdc`K\x11,\xe0K\xae\x0f`L\xc2\xea`MrA\xe0N\xa2\xcc`O\x1a\xc4\xe0P\x82\xae`" + + "P\xfa\xa6\xe0Rk\xca\xe0R\xdaz\xd0TT\xe7`T\xbaj\xe0V4\xc9`V\x9aL\xe0X\x1d\xe5\xe0Xz.\xe0Y\xfd\xc7\xe0ZZ\x10\xe0[ݩ\xe0\\9\xf2\xe0]\xc6\xc6`^\x19\xd4\xe0" + + "_\xa6\xa8``\x02\xf1`a\x8f\xc4\xe0a\xe2\xd3`co\xa6\xe0cµ`eO\x88\xe0e\xa2\x97`g/j\xe0g\x82y`i\x0fL\xe0ik\x95\xe0j\xef.\xe0kKw\xe0l\xd8K`" + + "m+Y\xe0n\xb8-`o\v;\xe0p\x98\x0f`p\xeb\x1d\xe0rw\xf1`r\xca\xff\xe0tW\xd3`t\xb4\x1c`v@\xef\xe0v\x93\xfe`x \xd1\xe0xs\xe0`z\x00\xb3\xe0zS\xc2`" + + "{\xe0\x95\xe0|3\xa4`}\xc0w\xe0~\x1c\xc0\xe0\u007f\xa0Y\xe0\u007f\xfc\xa2\xe0\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x00\x00\xa7\xc0\x00\x00\x00\x00\xb6\xd0\x01\x04\x00\x00\xa8\xc0\x00\bLMT\x00+13\x00+1" + + "2\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x9a\x13\xb1\xc0\x00\x00\x00\x006;" + + "\x17\xe0\x00\x00\x00\x006\xd7\xfa`\x00\x00\x00\x008$4`\x00\x00\x00\x008\xb7\xdc`\x00\x00\x00\x00K\x11,\xe0\x00\x00\x00\x00K\xae\x0f`\x00\x00\x00\x00L\xc2\xea`\x00\x00\x00\x00MrA\xe0\x00\x00" + + "\x00\x00N\xa2\xcc`\x00\x00\x00\x00O\x1a\xc4\xe0\x00\x00\x00\x00P\x82\xae`\x00\x00\x00\x00P\xfa\xa6\xe0\x00\x00\x00\x00Rk\xca\xe0\x00\x00\x00\x00R\xdaz\xd0\x00\x00\x00\x00TT\xe7`\x00\x00\x00\x00T\xba" + + "j\xe0\x00\x00\x00\x00V4\xc9`\x00\x00\x00\x00V\x9aL\xe0\x00\x00\x00\x00X\x1d\xe5\xe0\x00\x00\x00\x00Xz.\xe0\x00\x00\x00\x00Y\xfd\xc7\xe0\x00\x00\x00\x00ZZ\x10\xe0\x00\x00\x00\x00[ݩ\xe0\x00\x00" + + "\x00\x00\\9\xf2\xe0\x00\x00\x00\x00]\xc6\xc6`\x00\x00\x00\x00^\x19\xd4\xe0\x00\x00\x00\x00_\xa6\xa8`\x00\x00\x00\x00`\x02\xf1`\x00\x00\x00\x00a\x8f\xc4\xe0\x00\x00\x00\x00a\xe2\xd3`\x00\x00\x00\x00co" + + "\xa6\xe0\x00\x00\x00\x00cµ`\x00\x00\x00\x00eO\x88\xe0\x00\x00\x00\x00e\xa2\x97`\x00\x00\x00\x00g/j\xe0\x00\x00\x00\x00g\x82y`\x00\x00\x00\x00i\x0fL\xe0\x00\x00\x00\x00ik\x95\xe0\x00\x00" + + "\x00\x00j\xef.\xe0\x00\x00\x00\x00kKw\xe0\x00\x00\x00\x00l\xd8K`\x00\x00\x00\x00m+Y\xe0\x00\x00\x00\x00n\xb8-`\x00\x00\x00\x00o\v;\xe0\x00\x00\x00\x00p\x98\x0f`\x00\x00\x00\x00p\xeb" + + "\x1d\xe0\x00\x00\x00\x00rw\xf1`\x00\x00\x00\x00r\xca\xff\xe0\x00\x00\x00\x00tW\xd3`\x00\x00\x00\x00t\xb4\x1c`\x00\x00\x00\x00v@\xef\xe0\x00\x00\x00\x00v\x93\xfe`\x00\x00\x00\x00x \xd1\xe0\x00\x00" + + "\x00\x00xs\xe0`\x00\x00\x00\x00z\x00\xb3\xe0\x00\x00\x00\x00zS\xc2`\x00\x00\x00\x00{\xe0\x95\xe0\x00\x00\x00\x00|3\xa4`\x00\x00\x00\x00}\xc0w\xe0\x00\x00\x00\x00~\x1c\xc0\xe0\x00\x00\x00\x00\u007f\xa0" + + "Y\xe0\x00\x00\x00\x00\u007f\xfc\xa2\xe0\x00\x00\x00\x00\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x02\x00\x00\xa7\xc0\x00\x00\x00\x00\xb6\xd0\x01\x04\x00\x00\xa8\xc0\x00\bLMT\x00+13\x00+12\x00\n<+12>-1" + + "2<+13>,M11.2.0,M1.2.3/99\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe0\x17⺦\x00\x00\x00\xa6\x00\x00\x00\x10\x00\x1c\x00Pacif" + + "ic/FunafutiUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\x80\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x00\xa8\x04\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00TZif2\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff~6\f\xfc\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x00\xa8\x04\x00" + + "\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00\n<+12>-12\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP(\xa1_\xa3\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x1c\x00Pacif" + + "ic/PalauUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\x80\x00\x00\x00\u007f\xff\xff\xff\x01\x01\xff\xff,\x94\x00\x00\x00\x00~\x90\x00\x04LMT\x00+09\x00TZif2\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\b\xff\xff\xff\xff\x14\xe1\xcfl\xff\xff\xff\xff~66\xec\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02" + + "\x02\xff\xff,\x94\x00\x00\x00\x00~\x14\x00\x00\x00\x00~\x90\x00\x04LMT\x00+09\x00\n<+09>-9\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x98\xd4\xe8V\xee\x01\x00\x00\xee\x01" + + "\x00\x00\f\x00\x1c\x00Pacific/GuamUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x05\x00\x00\x00\x15\x80\x00\x00\x00\xcb7\x95\xe0\xd0.\x89\xf0\xec7\xbe\x00\xef6\xf8\xf0\xfb\x9b\x00\x00\xfe?'\x8c\xff\x01" + + "\x1e\x00\xff]X\xf0\x00\x97,\x00\x01Fup\x02w\x0e\x00\x03&Wp\ap\x97\x00\a\xcc\xd1\xf0\f\b\x91\x00\f|\x87,\r\xbf\x94\x80\x0ee\xa3p:C^`\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03" + + "\x01\x03\x01\x03\x01\x03\x01\x03\x01\x04\xff\xff64\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x9a\xb0\x01\f\x00\x00\x8c\xa0\x00\x10LMT\x00GST\x00+09\x00GDT\x00ChST" + + "\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x06\x00\x00\x00\x15\xff\xff\xff\xff\x14\xe1\xc5\xcc\xff\xff\xff\xff~6-" + + "L\xff\xff\xff\xff\xcb7\x95\xe0\xff\xff\xff\xff\xd0.\x89\xf0\xff\xff\xff\xff\xec7\xbe\x00\xff\xff\xff\xff\xef6\xf8\xf0\xff\xff\xff\xff\xfb\x9b\x00\x00\xff\xff\xff\xff\xfe?'\x8c\xff\xff\xff\xff\xff\x01\x1e\x00\xff\xff\xff" + + "\xff\xff]X\xf0\x00\x00\x00\x00\x00\x97,\x00\x00\x00\x00\x00\x01Fup\x00\x00\x00\x00\x02w\x0e\x00\x00\x00\x00\x00\x03&Wp\x00\x00\x00\x00\ap\x97\x00\x00\x00\x00\x00\a\xcc\xd1\xf0\x00\x00\x00\x00\f\b\x91" + + "\x00\x00\x00\x00\x00\f|\x87,\x00\x00\x00\x00\r\xbf\x94\x80\x00\x00\x00\x00\x0ee\xa3p\x00\x00\x00\x00:C^`\x01\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x05\xff\xff64\x00\x00" + + "\x00\x00\x87\xb4\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x9a\xb0\x01\f\x00\x00\x8c\xa0\x00\x10LMT\x00GST\x00+09\x00GDT\x00ChST\x00\nChST-10\n" + + "PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x98\xd4\xe8V\xee\x01\x00\x00\xee\x01\x00\x00\x0e\x00\x1c\x00Pacific/SaipanUT\t\x00\x03nӧ^nӧ^ux\v" + + "\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x05\x00\x00\x00\x15\x80\x00\x00\x00" + + "\xcb7\x95\xe0\xd0.\x89\xf0\xec7\xbe\x00\xef6\xf8\xf0\xfb\x9b\x00\x00\xfe?'\x8c\xff\x01\x1e\x00\xff]X\xf0\x00\x97,\x00\x01Fup\x02w\x0e\x00\x03&Wp\ap\x97\x00\a\xcc\xd1\xf0\f\b\x91\x00" + + "\f|\x87,\r\xbf\x94\x80\x0ee\xa3p:C^`\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x04\xff\xff64\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x9a\xb0\x01\f" + + "\x00\x00\x8c\xa0\x00\x10LMT\x00GST\x00+09\x00GDT\x00ChST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x15\x00\x00\x00\x06\x00\x00\x00\x15\xff\xff\xff\xff\x14\xe1\xc5\xcc\xff\xff\xff\xff~6-L\xff\xff\xff\xff\xcb7\x95\xe0\xff\xff\xff\xff\xd0.\x89\xf0\xff\xff\xff\xff\xec7\xbe\x00\xff\xff\xff\xff\xef6\xf8\xf0\xff" + + "\xff\xff\xff\xfb\x9b\x00\x00\xff\xff\xff\xff\xfe?'\x8c\xff\xff\xff\xff\xff\x01\x1e\x00\xff\xff\xff\xff\xff]X\xf0\x00\x00\x00\x00\x00\x97,\x00\x00\x00\x00\x00\x01Fup\x00\x00\x00\x00\x02w\x0e\x00\x00\x00\x00\x00\x03" + + "&Wp\x00\x00\x00\x00\ap\x97\x00\x00\x00\x00\x00\a\xcc\xd1\xf0\x00\x00\x00\x00\f\b\x91\x00\x00\x00\x00\x00\f|\x87,\x00\x00\x00\x00\r\xbf\x94\x80\x00\x00\x00\x00\x0ee\xa3p\x00\x00\x00\x00:C^`\x01" + + "\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x05\xff\xff64\x00\x00\x00\x00\x87\xb4\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x9a\xb0\x01\f\x00\x00\x8c\xa0\x00\x10LMT\x00" + + "GST\x00+09\x00GDT\x00ChST\x00\nChST-10\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x93dt\x0e_\x01\x00\x00_\x01\x00\x00\x0e\x00\x1c\x00Paci" + + "fic/KosraeUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x06\x00\x00\x00\x14\x80\x00\x00\x00\x98\x11\x95Р9\xf9\xf0\xc1\xed5\xd0\xc9\xea\n`\xd2\x11\x0e\xf0\xff\x86\x1bP6\x8bg@\u007f\xff\xff\xff\x01\x02" + + "\x01\x03\x02\x01\x04\x01\x01\xff\xffGL\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x00\f\x00\x00\xa8\xc0\x00\x10\x00\x00\x9a\xb0\x00\x04LMT\x00+11\x00+09\x00+10\x00+" + + "12\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xff\x14ᴴ\xff\xff\xff\xff~" + + "6\x1c4\xff\xff\xff\xff\x98\x11\x95\xd0\xff\xff\xff\xff\xa09\xf9\xf0\xff\xff\xff\xff\xc1\xed5\xd0\xff\xff\xff\xff\xc9\xea\n`\xff\xff\xff\xff\xd2\x11\x0e\xf0\xff\xff\xff\xff\xff\x86\x1bP\x00\x00\x00\x006\x8bg@\x00" + + "\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x04\x03\x02\x05\x02\x02\xff\xffGL\x00\x00\x00\x00\x98\xcc\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x00\f\x00\x00\xa8\xc0\x00\x10\x00\x00\x9a\xb0\x00\x04L" + + "MT\x00+11\x00+09\x00+10\x00+12\x00\n<+11>-11\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP&QJ\xb4\xf1\x00\x00\x00\xf1\x00\x00\x00\f\x00\x1c\x00P" + + "acific/NiueUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x14\x80\x00\x00\x00\xdcC5`\x10t\xca8\u007f\xff\xff\xff\x01\x02\x03\x03\xff\xff`\xb4\x00\x00\xff\xff`\xa0\x00\x04\xff\xff^H\x00" + + "\n\xff\xffeP\x00\x10LMT\x00-1120\x00-1130\x00-11\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff~7TL\xff\xff\xff\xff\xdcC5`\x00\x00\x00\x00\x10t\xca8\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x03\xff\xff`\xb4\x00\x00\xff\xff`\xa0\x00\x04\xff" + + "\xff^H\x00\n\xff\xffeP\x00\x10LMT\x00-1120\x00-1130\x00-11\x00\n<-11>11\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPV\xa7\x1f\xd4/\x01" + + "\x00\x00/\x01\x00\x00\x0e\x00\x1c\x00Pacific/PonapeUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x05\x00\x00\x00\x10\x80\x00\x00\x00\x98\x11\x95Р9\xf9\xf0\xc1\xed5\xd0\xc9\xea\n`\xd2\x11\x0e\xf0" + + "\u007f\xff\xff\xff\x01\x02\x01\x03\x02\x01\x01\xff\xffB\xd4\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x00\f\x00\x00\x9a\xb0\x00\x04LMT\x00+11\x00+09\x00+10\x00TZi" + + "f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\x14\xe1\xb9,\xff\xff\xff\xff~6 \xac\xff\xff\xff" + + "\xff\x98\x11\x95\xd0\xff\xff\xff\xff\xa09\xf9\xf0\xff\xff\xff\xff\xc1\xed5\xd0\xff\xff\xff\xff\xc9\xea\n`\xff\xff\xff\xff\xd2\x11\x0e\xf0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x04\x03\x02\x02\xff\xffB\xd4\x00\x00\x00" + + "\x00\x94T\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x00\f\x00\x00\x9a\xb0\x00\x04LMT\x00+11\x00+09\x00+10\x00\n<+11>-11\nPK\x03\x04\n" + + "\x00\x00\x00\x00\x00\xf5F\x9cP\x01\xc1\xe8\x00\xa6\x00\x00\x00\xa6\x00\x00\x00\f\x00\x1c\x00Pacific/WakeUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00" + + "\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\x80\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00" + + "\x00\x9c4\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00" + + "\x00\x00\b\xff\xff\xff\xff~6\x18\xcc\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x00\x9c4\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00\n<+12>-12\nPK\x03\x04\n\x00\x00\x00\x00" + + "\x00\xf5F\x9cP\xc7s\xd0 \xee\x00\x00\x00\xee\x00\x00\x00\x11\x00\x1c\x00Pacific/GalapagosUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00" + + "\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\f\xb6\xa4L\x80\x1e\x18\xc4P+\x17" + + "\n\xe0+q\xf4P\u007f\xff\xff\xff\x01\x03\x02\x03\x03\xff\xff\xac\x00\x00\x00\xff\xff\xb9\xb0\x00\x04\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\bLMT\x00-05\x00-06\x00TZif2\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\xb6\xa4L\x80\x00\x00\x00\x00\x1e\x18\xc4P\x00\x00\x00\x00+\x17\n\xe0\x00" + + "\x00\x00\x00+q\xf4P\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x03\xff\xff\xac\x00\x00\x00\xff\xff\xb9\xb0\x00\x04\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\bLMT\x00-05\x00-06\x00\n<-0" + + "6>6\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPָ|\xb0I\x01\x00\x00I\x01\x00\x00\x10\x00\x1c\x00Pacific/JohnstonUT\t\x00\x03nӧ^n" + + "ӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x06\x00\x00" + + "\x00\x14\x80\x00\x00\x00\xbb\x05CH\xbb!qXˉ=\xc8\xd2#\xf4p\xd2aI8ՍsH\x01\x02\x01\x03\x04\x01\x05\xff\xffl\x02\x00\x00\xff\xfflX\x00\x04\xff\xffzh\x01\b\xff\xffzh\x01" + + "\f\xff\xffzh\x01\x10\xff\xffs`\x00\x04LMT\x00HST\x00HDT\x00HWT\x00HPT\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xfft\xe0p\xbe\xff\xff\xff\xff\xbb\x05CH\xff\xff\xff\xff\xbb!qX\xff\xff\xff\xffˉ=" + + "\xc8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aI8\xff\xff\xff\xffՍsH\x01\x02\x01\x03\x04\x01\x05\xff\xffl\x02\x00\x00\xff\xfflX\x00\x04\xff\xffzh\x01\b\xff\xffzh\x01\f\xff\xffzh" + + "\x01\x10\xff\xffs`\x00\x04LMT\x00HST\x00HDT\x00HWT\x00HPT\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00\nHST10\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9c" + + "Py|\x8dܯ\x00\x00\x00\xaf\x00\x00\x00\x0e\x00\x1c\x00Pacific/MidwayUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00T" + + "Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\b\x80\x00\x00\x00\x91\x05\xfb\b\x01\x02\x00\x00\xb1x\x00\x00\xff" + + "\xff_\xf8\x00\x00\xff\xffeP\x00\x04LMT\x00SST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00" + + "\x00\x00\b\xff\xff\xff\xffn=\xc8\b\xff\xff\xff\xff\x91\x05\xfb\b\x01\x02\x00\x00\xb1x\x00\x00\xff\xff_\xf8\x00\x00\xff\xffeP\x00\x04LMT\x00SST\x00\nSST11\nPK\x03\x04\n\x00" + + "\x00\x00\x00\x00\xf5F\x9cPZV\x1d\xe0\xfc\x00\x00\x00\xfc\x00\x00\x00\r\x00\x1c\x00Pacific/NauruUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00" + + "\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x12\xa3\xe7+\x04̐\xe9\xc8\xd2C'" + + "\xf0\x11!\xa8\xe8\u007f\xff\xff\xff\x01\x02\x01\x03\x03\x00\x00\x9c|\x00\x00\x00\x00\xa1\xb8\x00\x04\x00\x00~\x90\x00\n\x00\x00\xa8\xc0\x00\x0eLMT\x00+1130\x00+09\x00+12\x00TZif" + + "2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\xa3\xe7+\x04\xff\xff\xff\xff̐\xe9\xc8\xff\xff\xff\xff" + + "\xd2C'\xf0\x00\x00\x00\x00\x11!\xa8\xe8\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x01\x03\x03\x00\x00\x9c|\x00\x00\x00\x00\xa1\xb8\x00\x04\x00\x00~\x90\x00\n\x00\x00\xa8\xc0\x00\x0eLMT\x00+1130\x00+" + + "09\x00+12\x00\n<+12>-12\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP-11\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP{\x9d0U\x14\b\x00\x00\x14\b\x00\x00\x0f\x00\x1c\x00Pacific/Ch" + + "athamUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x05\x00\x00\x00\x00\x00\x00\x00\x82\x00\x00\x00\x05\x00\x00\x00\x16\x80\x00\x00\x00\xd2ږ\xbc\t\x18\xfd\xe0\t\xac\xa5\xe0\n\xef\xa5`\v\x9e\xfc\xe0\f\xd8\xc1\xe0\r~\xde\xe0\x0e\xb8\xa3\xe0\x0f^\xc0\xe0\x10\x98\x85" + + "\xe0\x11>\xa2\xe0\x12xg\xe0\x13\x1e\x84\xe0\x14XI\xe0\x14\xfef\xe0\x168+\xe0\x16\xe7\x83`\x18!H`\x18\xc7e`\x1a\x01*`\x1a\xa7G`\x1b\xe1\f`\x1c\x87)`\x1d\xc0\xee`\x1eg\v" + + "`\x1f\xa0\xd0` F\xed`!\x80\xb2`\"0\t\xe0#i\xce\xe0$\x0f\xeb\xe0%.\x01`&\x02B\xe0'\r\xe3`'\xe2$\xe0(\xed\xc5`)\xc2\x06\xe0*ͧ`+\xab#`,\xad\x89" + + "`-\x8b\x05`.\x8dk`/j\xe7`0mM`1J\xc9`2Vi\xe03*\xab`46K\xe05\n\x8d`6\x16-\xe06\xf3\xa9\xe07\xf6\x0f\xe08Ӌ\xe09\xd5\xf1\xe0:\xb3m" + + "\xe0;\xbf\x0e`<\x93O\xe0=\x9e\xf0`>s1\xe0?~\xd2`@\\N`A^\xb4`B<0`C>\x96`D\x1c\x12`E\x1ex`E\xfb\xf4`F\xfeZ`G\xf7\x85\xe0H\xde<" + + "`I\xd7g\xe0J\xbe\x1e`K\xb7I\xe0L\x9e\x00`M\x97+\xe0N}\xe2`Ow\r\xe0Pf\xfe\xe0Q`*`RF\xe0\xe0S@\f`T&\xc2\xe0U\x1f\xee`V\x06\xa4\xe0V\xff\xd0" + + "`W\xe6\x86\xe0X߲`Y\xc6h\xe0Z\xbf\x94`[\xaf\x85`\\\xa8\xb0\xe0]\x8fg`^\x88\x92\xe0_oI``ht\xe0aO+`bHV\xe0c/\r`d(8\xe0e\x0e\xef" + + "`f\x11U`f\xf8\v\xe0g\xf17`h\xd7\xed\xe0i\xd1\x19`j\xb7\xcf\xe0k\xb0\xfb`l\x97\xb1\xe0m\x90\xdd`nw\x93\xe0op\xbf`p`\xb0`qY\xdb\xe0r@\x92`s9\xbd" + + "\xe0t t`u\x19\x9f\xe0v\x00V`v\xf9\x81\xe0w\xe08`x\xd9c\xe0y\xc0\x1a`z\xb9E\xe0{\xa96\xe0|\xa2b`}\x89\x18\xe0~\x82D`\u007fh\xfa\xe0\u007f\xff\xff\xff\x01\x04\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x02\x00\x00\xab\xfc\x00\x00\x00\x00\xacD\x00\x04\x00\x00\xc1\\\x01\n\x00\x00\xb3L\x00\x10\x00\x00\xb3L\x00\x10LMT\x00+1215\x00+1345\x00+1245\x00\x00" + + "\x00\x01\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x82\x00\x00\x00\x05\x00\x00\x00\x16\xff\xff\xff\xffA\xb7D\x84\xff\xff\xff\xff" + + "\xd2ږ\xbc\x00\x00\x00\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v\x9e\xfc\xe0\x00\x00\x00\x00\f\xd8\xc1\xe0\x00\x00\x00\x00\r~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0" + + "\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00" + + "\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\f`\x00\x00\x00\x00\x1c\x87)`" + + "\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\"0\t\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00" + + "$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*ͧ`" + + "\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x00" + + "2Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008Ӌ\xe0" + + "\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00" + + "@\\N`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`" + + "\x00\x00\x00\x00G\xf7\x85\xe0\x00\x00\x00\x00H\xde<`\x00\x00\x00\x00I\xd7g\xe0\x00\x00\x00\x00J\xbe\x1e`\x00\x00\x00\x00K\xb7I\xe0\x00\x00\x00\x00L\x9e\x00`\x00\x00\x00\x00M\x97+\xe0\x00\x00\x00\x00" + + "N}\xe2`\x00\x00\x00\x00Ow\r\xe0\x00\x00\x00\x00Pf\xfe\xe0\x00\x00\x00\x00Q`*`\x00\x00\x00\x00RF\xe0\xe0\x00\x00\x00\x00S@\f`\x00\x00\x00\x00T&\xc2\xe0\x00\x00\x00\x00U\x1f\xee`" + + "\x00\x00\x00\x00V\x06\xa4\xe0\x00\x00\x00\x00V\xff\xd0`\x00\x00\x00\x00W\xe6\x86\xe0\x00\x00\x00\x00X߲`\x00\x00\x00\x00Y\xc6h\xe0\x00\x00\x00\x00Z\xbf\x94`\x00\x00\x00\x00[\xaf\x85`\x00\x00\x00\x00" + + "\\\xa8\xb0\xe0\x00\x00\x00\x00]\x8fg`\x00\x00\x00\x00^\x88\x92\xe0\x00\x00\x00\x00_oI`\x00\x00\x00\x00`ht\xe0\x00\x00\x00\x00aO+`\x00\x00\x00\x00bHV\xe0\x00\x00\x00\x00c/\r`" + + "\x00\x00\x00\x00d(8\xe0\x00\x00\x00\x00e\x0e\xef`\x00\x00\x00\x00f\x11U`\x00\x00\x00\x00f\xf8\v\xe0\x00\x00\x00\x00g\xf17`\x00\x00\x00\x00h\xd7\xed\xe0\x00\x00\x00\x00i\xd1\x19`\x00\x00\x00\x00" + + "j\xb7\xcf\xe0\x00\x00\x00\x00k\xb0\xfb`\x00\x00\x00\x00l\x97\xb1\xe0\x00\x00\x00\x00m\x90\xdd`\x00\x00\x00\x00nw\x93\xe0\x00\x00\x00\x00op\xbf`\x00\x00\x00\x00p`\xb0`\x00\x00\x00\x00qY\xdb\xe0" + + "\x00\x00\x00\x00r@\x92`\x00\x00\x00\x00s9\xbd\xe0\x00\x00\x00\x00t t`\x00\x00\x00\x00u\x19\x9f\xe0\x00\x00\x00\x00v\x00V`\x00\x00\x00\x00v\xf9\x81\xe0\x00\x00\x00\x00w\xe08`\x00\x00\x00\x00" + + "x\xd9c\xe0\x00\x00\x00\x00y\xc0\x1a`\x00\x00\x00\x00z\xb9E\xe0\x00\x00\x00\x00{\xa96\xe0\x00\x00\x00\x00|\xa2b`\x00\x00\x00\x00}\x89\x18\xe0\x00\x00\x00\x00~\x82D`\x00\x00\x00\x00\u007fh\xfa\xe0" + + "\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\x00\x00\xab\xfc\x00\x00\x00\x00\xacD\x00\x04\x00\x00\xc1\\\x01\n\x00\x00\xb3L\x00\x10\x00\x00\xb3L\x00\x10LMT\x00+1215\x00+1" + + "345\x00+1245\x00\x00\x00\x01\x01\x00\n<+1245>-12:45<+1345>,M9.5.0/2:45,M4.1.0/3:45" + + "\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP0>8\xb8\x85\t\x00\x00\x85\t\x00\x00\x10\x00\x1c\x00Pacific/AucklandUT\t\x00\x03nӧ^nӧ^" + + "ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x9c\x00\x00\x00\a\x00\x00\x00\x13\x80" + + "\x00\x00\x00\xb0\xb4\xb2\xe8\xb1Q\x87X\xb2x\xe5h\xb3C\xe5`\xb4X\xc7h\xb5#\xc7`\xb68\xa9h\xb7\x03\xa9`\xb8\x18\x8bh\xb8\xec\xc5\xe0\xb9\xf8mh\xba̧\xe0\xbb\xd8Oh\xbc\xe3\xe8\xe0\xbd" + + "\xae\xf6\xe8\xbe\xc3\xca࿎\xd8\xe8\xc0\xa3\xac\xe0\xc1n\xba\xe8\u0083\x8e\xe0\xc3N\x9c\xe8\xc4cp\xe0\xc5.~\xe8\xc6L\x8d`\xc7\x0e`\xe8\xc8,o`\xc8\xf7}h\xd2ښ@\t\x18\xfd\xe0\t" + + "\xac\xa5\xe0\n\xef\xa5`\v\x9e\xfc\xe0\f\xd8\xc1\xe0\r~\xde\xe0\x0e\xb8\xa3\xe0\x0f^\xc0\xe0\x10\x98\x85\xe0\x11>\xa2\xe0\x12xg\xe0\x13\x1e\x84\xe0\x14XI\xe0\x14\xfef\xe0\x168+\xe0\x16\xe7\x83`\x18" + + "!H`\x18\xc7e`\x1a\x01*`\x1a\xa7G`\x1b\xe1\f`\x1c\x87)`\x1d\xc0\xee`\x1eg\v`\x1f\xa0\xd0` F\xed`!\x80\xb2`\"0\t\xe0#i\xce\xe0$\x0f\xeb\xe0%.\x01`&" + + "\x02B\xe0'\r\xe3`'\xe2$\xe0(\xed\xc5`)\xc2\x06\xe0*ͧ`+\xab#`,\xad\x89`-\x8b\x05`.\x8dk`/j\xe7`0mM`1J\xc9`2Vi\xe03*\xab`4" + + "6K\xe05\n\x8d`6\x16-\xe06\xf3\xa9\xe07\xf6\x0f\xe08Ӌ\xe09\xd5\xf1\xe0:\xb3m\xe0;\xbf\x0e`<\x93O\xe0=\x9e\xf0`>s1\xe0?~\xd2`@\\N`A^\xb4`B" + + "<0`C>\x96`D\x1c\x12`E\x1ex`E\xfb\xf4`F\xfeZ`G\xf7\x85\xe0H\xde<`I\xd7g\xe0J\xbe\x1e`K\xb7I\xe0L\x9e\x00`M\x97+\xe0N}\xe2`Ow\r\xe0P" + + "f\xfe\xe0Q`*`RF\xe0\xe0S@\f`T&\xc2\xe0U\x1f\xee`V\x06\xa4\xe0V\xff\xd0`W\xe6\x86\xe0X߲`Y\xc6h\xe0Z\xbf\x94`[\xaf\x85`\\\xa8\xb0\xe0]\x8fg`^" + + "\x88\x92\xe0_oI``ht\xe0aO+`bHV\xe0c/\r`d(8\xe0e\x0e\xef`f\x11U`f\xf8\v\xe0g\xf17`h\xd7\xed\xe0i\xd1\x19`j\xb7\xcf\xe0k\xb0\xfb`l" + + "\x97\xb1\xe0m\x90\xdd`nw\x93\xe0op\xbf`p`\xb0`qY\xdb\xe0r@\x92`s9\xbd\xe0t t`u\x19\x9f\xe0v\x00V`v\xf9\x81\xe0w\xe08`x\xd9c\xe0y\xc0\x1a`z" + + "\xb9E\xe0{\xa96\xe0|\xa2b`}\x89\x18\xe0~\x82D`\u007fh\xfa\xe0\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x06\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x00" + + "\x00\xa3\xd8\x00\x00\x00\x00\xaf\xc8\x01\x04\x00\x00\xa1\xb8\x00\t\x00\x00\xa8\xc0\x01\x04\x00\x00\xb6\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04\x00\x00\xa8\xc0\x00\x04LMT\x00NZST\x00NZMT\x00NZDT\x00" + + "\x00\x00\x00\x00\x01\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x9c\x00\x00\x00\a\x00\x00\x00\x13\xff\xff\xff\xffA\xb7L\xa8\xff" + + "\xff\xff\xff\xb0\xb4\xb2\xe8\xff\xff\xff\xff\xb1Q\x87X\xff\xff\xff\xff\xb2x\xe5h\xff\xff\xff\xff\xb3C\xe5`\xff\xff\xff\xff\xb4X\xc7h\xff\xff\xff\xff\xb5#\xc7`\xff\xff\xff\xff\xb68\xa9h\xff\xff\xff\xff\xb7" + + "\x03\xa9`\xff\xff\xff\xff\xb8\x18\x8bh\xff\xff\xff\xff\xb8\xec\xc5\xe0\xff\xff\xff\xff\xb9\xf8mh\xff\xff\xff\xff\xba̧\xe0\xff\xff\xff\xff\xbb\xd8Oh\xff\xff\xff\xff\xbc\xe3\xe8\xe0\xff\xff\xff\xff\xbd\xae\xf6\xe8\xff" + + "\xff\xff\xff\xbe\xc3\xca\xe0\xff\xff\xff\xff\xbf\x8e\xd8\xe8\xff\xff\xff\xff\xc0\xa3\xac\xe0\xff\xff\xff\xff\xc1n\xba\xe8\xff\xff\xff\xff\u0083\x8e\xe0\xff\xff\xff\xff\xc3N\x9c\xe8\xff\xff\xff\xff\xc4cp\xe0\xff\xff\xff\xff\xc5" + + ".~\xe8\xff\xff\xff\xff\xc6L\x8d`\xff\xff\xff\xff\xc7\x0e`\xe8\xff\xff\xff\xff\xc8,o`\xff\xff\xff\xff\xc8\xf7}h\xff\xff\xff\xff\xd2ښ@\x00\x00\x00\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00" + + "\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v\x9e\xfc\xe0\x00\x00\x00\x00\f\xd8\xc1\xe0\x00\x00\x00\x00\r~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11" + + ">\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00" + + "\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\f`\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f" + + "\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\"0\t\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00" + + "\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*ͧ`\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-" + + "\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00" + + "\x00\x00\x005\n\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008Ӌ\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;" + + "\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\\N`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00" + + "\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x00\x00\x00\x00G\xf7\x85\xe0\x00\x00\x00\x00H\xde<`\x00\x00\x00\x00I" + + "\xd7g\xe0\x00\x00\x00\x00J\xbe\x1e`\x00\x00\x00\x00K\xb7I\xe0\x00\x00\x00\x00L\x9e\x00`\x00\x00\x00\x00M\x97+\xe0\x00\x00\x00\x00N}\xe2`\x00\x00\x00\x00Ow\r\xe0\x00\x00\x00\x00Pf\xfe\xe0\x00" + + "\x00\x00\x00Q`*`\x00\x00\x00\x00RF\xe0\xe0\x00\x00\x00\x00S@\f`\x00\x00\x00\x00T&\xc2\xe0\x00\x00\x00\x00U\x1f\xee`\x00\x00\x00\x00V\x06\xa4\xe0\x00\x00\x00\x00V\xff\xd0`\x00\x00\x00\x00W" + + "\xe6\x86\xe0\x00\x00\x00\x00X߲`\x00\x00\x00\x00Y\xc6h\xe0\x00\x00\x00\x00Z\xbf\x94`\x00\x00\x00\x00[\xaf\x85`\x00\x00\x00\x00\\\xa8\xb0\xe0\x00\x00\x00\x00]\x8fg`\x00\x00\x00\x00^\x88\x92\xe0\x00" + + "\x00\x00\x00_oI`\x00\x00\x00\x00`ht\xe0\x00\x00\x00\x00aO+`\x00\x00\x00\x00bHV\xe0\x00\x00\x00\x00c/\r`\x00\x00\x00\x00d(8\xe0\x00\x00\x00\x00e\x0e\xef`\x00\x00\x00\x00f" + + "\x11U`\x00\x00\x00\x00f\xf8\v\xe0\x00\x00\x00\x00g\xf17`\x00\x00\x00\x00h\xd7\xed\xe0\x00\x00\x00\x00i\xd1\x19`\x00\x00\x00\x00j\xb7\xcf\xe0\x00\x00\x00\x00k\xb0\xfb`\x00\x00\x00\x00l\x97\xb1\xe0\x00" + + "\x00\x00\x00m\x90\xdd`\x00\x00\x00\x00nw\x93\xe0\x00\x00\x00\x00op\xbf`\x00\x00\x00\x00p`\xb0`\x00\x00\x00\x00qY\xdb\xe0\x00\x00\x00\x00r@\x92`\x00\x00\x00\x00s9\xbd\xe0\x00\x00\x00\x00t" + + " t`\x00\x00\x00\x00u\x19\x9f\xe0\x00\x00\x00\x00v\x00V`\x00\x00\x00\x00v\xf9\x81\xe0\x00\x00\x00\x00w\xe08`\x00\x00\x00\x00x\xd9c\xe0\x00\x00\x00\x00y\xc0\x1a`\x00\x00\x00\x00z\xb9E\xe0\x00" + + "\x00\x00\x00{\xa96\xe0\x00\x00\x00\x00|\xa2b`\x00\x00\x00\x00}\x89\x18\xe0\x00\x00\x00\x00~\x82D`\x00\x00\x00\x00\u007fh\xfa\xe0\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x06\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" + + "\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x00\x00\xa3\xd8\x00\x00\x00\x00\xaf\xc8\x01\x04\x00\x00\xa1\xb8\x00\t\x00\x00\xa8\xc0\x01\x04\x00\x00\xb6\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04\x00\x00\xa8\xc0\x00\x04LMT" + + "\x00NZST\x00NZMT\x00NZDT\x00\x00\x00\x00\x00\x01\x01\x00\nNZST-12NZDT,M9.5.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00" + + "\x00\x00\xf5F\x9cPS\x91O\xa50\x01\x00\x000\x01\x00\x00\x0e\x00\x1c\x00Pacific/NoumeaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04" + + "\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x05\x00\x00\x00\f\x92\xf5\xc4t\x0e\xe6\xbaP\x0fV\xbb\xc0" + + "\x10ƜP\x117\xef@2\xa0K\xf03\x18Dp\u007f\xff\xff\xff\x02\x01\x02\x01\x02\x03\x04\x04\x00\x00\x9c\f\x00\x00\x00\x00\xa8\xc0\x01\x04\x00\x00\x9a\xb0\x00\b\x00\x00\xa8\xc0\x01\x04\x00\x00\x9a\xb0\x00\bLM" + + "T\x00+12\x00+11\x00\x00\x00\x00\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x05\x00\x00\x00\f\xff" + + "\xff\xff\xff\x92\xf5\xc4t\x00\x00\x00\x00\x0e\xe6\xbaP\x00\x00\x00\x00\x0fV\xbb\xc0\x00\x00\x00\x00\x10ƜP\x00\x00\x00\x00\x117\xef@\x00\x00\x00\x002\xa0K\xf0\x00\x00\x00\x003\x18Dp\x00\x00\x00\x00\u007f" + + "\xff\xff\xff\x02\x01\x02\x01\x02\x03\x04\x04\x00\x00\x9c\f\x00\x00\x00\x00\xa8\xc0\x01\x04\x00\x00\x9a\xb0\x00\b\x00\x00\xa8\xc0\x01\x04\x00\x00\x9a\xb0\x00\bLMT\x00+12\x00+11\x00\x00\x00\x00\x01\x01\n<" + + "+11>-11\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc8\x1ar\x86\xc8\x00\x00\x00\xc8\x00\x00\x00\x0f\x00\x1c\x00Pacific/FakaofoUT\t\x00\x03n\xd3" + + "\xa7^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00" + + "\x03\x00\x00\x00\f\x80\x00\x00\x00N\xfd\x99\xb0\u007f\xff\xff\xff\x01\x02\x02\xff\xff_x\x00\x00\xff\xffeP\x00\x04\x00\x00\xb6\xd0\x00\bLMT\x00-11\x00+13\x00TZif2\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff~7U\x88\x00\x00\x00\x00N\xfd\x99\xb0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02" + + "\x02\xff\xff_x\x00\x00\xff\xffeP\x00\x04\x00\x00\xb6\xd0\x00\bLMT\x00-11\x00+13\x00\n<+13>-13\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\t\xd07\"\xa5" + + "\x00\x00\x00\xa5\x00\x00\x00\x0e\x00\x1c\x00Pacific/TahitiUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\x94PU\xb8\u007f\xff\xff\xff\x01\x01\xff\xffs\xc8\x00\x00\xff\xffs`\x00\x04L" + + "MT\x00-10\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x94PU\xb8\x00" + + "\x00\x00\x00\u007f\xff\xff\xff\x01\x01\xff\xffs\xc8\x00\x00\xff\xffs`\x00\x04LMT\x00-10\x00\n<-10>10\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb6\x1c\xb3\x9e\xa4\x00\x00\x00" + + "\xa4\x00\x00\x00\x0f\x00\x1c\x00Pacific/GambierUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\x94PH\x04\u007f\xff\xff\xff\x01\x01\xff\xff\x81|\x00\x00\xff\xff\x81p\x00\x04LMT" + + "\x00-09\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x94PH\x04\x00\x00\x00" + + "\x00\u007f\xff\xff\xff\x01\x01\xff\xff\x81|\x00\x00\xff\xff\x81p\x00\x04LMT\x00-09\x00\n<-09>9\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc0YK\x026\x01\x00\x006\x01\x00" + + "\x00\x0e\x00\x1c\x00Pacific/MajuroUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x05\x00\x00\x00\x14\x80\x00\x00\x00\x98\x11\x95Р9\xf9\xf0\xc1\xed5\xd0\xc9\xea\n`\xcf=Gp\xff\x86\x1bP\u007f" + + "\xff\xff\xff\x01\x02\x01\x03\x02\x01\x04\x04\x00\x00\xa0\x80\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x00\f\x00\x00\xa8\xc0\x00\x10LMT\x00+11\x00+09\x00+10\x00+12" + + "\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff~6\x14\x80\xff\xff\xff\xff\x98\x11\x95" + + "\xd0\xff\xff\xff\xff\xa09\xf9\xf0\xff\xff\xff\xff\xc1\xed5\xd0\xff\xff\xff\xff\xc9\xea\n`\xff\xff\xff\xff\xcf=Gp\xff\xff\xff\xff\xff\x86\x1bP\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x01\x03\x02\x01\x04\x04\x00\x00\xa0" + + "\x80\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x00\f\x00\x00\xa8\xc0\x00\x10LMT\x00+11\x00+09\x00+10\x00+12\x00\n<+12>-12\nPK\x03" + + "\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPָ|\xb0I\x01\x00\x00I\x01\x00\x00\x10\x00\x1c\x00Pacific/HonoluluUT\t\x00\x03nӧ^nӧ^ux\v\x00" + + "\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x06\x00\x00\x00\x14\x80\x00\x00\x00\xbb" + + "\x05CH\xbb!qXˉ=\xc8\xd2#\xf4p\xd2aI8ՍsH\x01\x02\x01\x03\x04\x01\x05\xff\xffl\x02\x00\x00\xff\xfflX\x00\x04\xff\xffzh\x01\b\xff\xffzh\x01\f\xff\xffzh\x01\x10" + + "\xff\xffs`\x00\x04LMT\x00HST\x00HDT\x00HWT\x00HPT\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x06\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xfft\xe0p\xbe\xff\xff\xff\xff\xbb\x05CH\xff\xff\xff\xff\xbb!qX\xff\xff\xff\xffˉ=\xc8\xff\xff\xff\xff\xd2#" + + "\xf4p\xff\xff\xff\xff\xd2aI8\xff\xff\xff\xffՍsH\x01\x02\x01\x03\x04\x01\x05\xff\xffl\x02\x00\x00\xff\xfflX\x00\x04\xff\xffzh\x01\b\xff\xffzh\x01\f\xff\xffzh\x01\x10\xff\xffs`\x00" + + "\x04LMT\x00HST\x00HDT\x00HWT\x00HPT\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00\nHST10\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPV\xa7\x1f\xd4/\x01" + + "\x00\x00/\x01\x00\x00\x0f\x00\x1c\x00Pacific/PohnpeiUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x05\x00\x00\x00\x10\x80\x00\x00\x00\x98\x11\x95Р9\xf9\xf0\xc1\xed5\xd0\xc9\xea\n`\xd2\x11\x0e" + + "\xf0\u007f\xff\xff\xff\x01\x02\x01\x03\x02\x01\x01\xff\xffB\xd4\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x00\f\x00\x00\x9a\xb0\x00\x04LMT\x00+11\x00+09\x00+10\x00TZ" + + "if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\x14\xe1\xb9,\xff\xff\xff\xff~6 \xac\xff\xff" + + "\xff\xff\x98\x11\x95\xd0\xff\xff\xff\xff\xa09\xf9\xf0\xff\xff\xff\xff\xc1\xed5\xd0\xff\xff\xff\xff\xc9\xea\n`\xff\xff\xff\xff\xd2\x11\x0e\xf0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x04\x03\x02\x02\xff\xffB\xd4\x00\x00" + + "\x00\x00\x94T\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x00\f\x00\x00\x9a\xb0\x00\x04LMT\x00+11\x00+09\x00+10\x00\n<+11>-11\nPK\x03\x04" + + "\n\x00\x00\x00\x00\x00\xf5F\x9cPy|\x8dܯ\x00\x00\x00\xaf\x00\x00\x00\x11\x00\x1c\x00Pacific/Pago_PagoUT\t\x00\x03nӧ^nӧ^ux\v\x00" + + "\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\b\x80\x00\x00\x00\x91" + + "\x05\xfb\b\x01\x02\x00\x00\xb1x\x00\x00\xff\xff_\xf8\x00\x00\xff\xffeP\x00\x04LMT\x00SST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\b\xff\xff\xff\xffn=\xc8\b\xff\xff\xff\xff\x91\x05\xfb\b\x01\x02\x00\x00\xb1x\x00\x00\xff\xff_\xf8\x00\x00\xff\xffeP\x00\x04LMT\x00SST\x00\n" + + "SST11\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPN\xaexD\r\x01\x00\x00\r\x01\x00\x00\f\x00\x1c\x00Pacific/TrukUT\t\x00\x03nӧ^nӧ" + + "^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\f" + + "\x80\x00\x00\x00\x98\x11\xa3\xe0\xa09\xf9\xf0\xc9\xea\n`\xd2\x11\x0e\xf0\u007f\xff\xff\xff\x01\x02\x01\x02\x01\x01\xff\xff<\xcc\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x00\x04LMT\x00+1" + + "0\x00+09\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x05\x00\x00\x00\f\xff\xff\xff\xff\x14\xe1\xbf4\xff\xff" + + "\xff\xff~6&\xb4\xff\xff\xff\xff\x98\x11\xa3\xe0\xff\xff\xff\xff\xa09\xf9\xf0\xff\xff\xff\xff\xc9\xea\n`\xff\xff\xff\xff\xd2\x11\x0e\xf0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x03\x02\x02\xff\xff<\xcc\x00\x00\x00" + + "\x00\x8eL\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x00\x04LMT\x00+10\x00+09\x00\n<+10>-10\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb9" + + "\xfc\xba\xcd\xca\x00\x00\x00\xca\x00\x00\x00\x10\x00\x1c\x00Pacific/PitcairnUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00T" + + "Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x0e\x80\x00\x00\x005DB\b\u007f\xff\xff\xff\x01\x02\x02\xff\xff" + + "\x86\f\x00\x00\xff\xff\x88x\x00\x04\xff\xff\x8f\x80\x00\nLMT\x00-0830\x00-08\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xff~7.\xf4\x00\x00\x00\x005DB\b\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x02\xff\xff\x86\f\x00\x00\xff\xff\x88x\x00\x04\xff\xff\x8f\x80\x00\nL" + + "MT\x00-0830\x00-08\x00\n<-08>8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPʣ\xc1\x9d\xad\x00\x00\x00\xad\x00\x00\x00\x11\x00\x1c\x00Pacific/M" + + "arquesasUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\n\x94PLH\u007f\xff\xff\xff\x01\x01\xff\xff}8\x00\x00\xff\xffzh\x00\x04LMT\x00-0930\x00TZif2\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\n\xff\xff\xff\xff\x94PLH\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x01\xff\xff}8\x00\x00" + + "\xff\xffzh\x00\x04LMT\x00-0930\x00\n<-0930>9:30\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP!\xce\xc3\xf8\f\x01\x00\x00\f\x01\x00\x00\x14\x00\x1c\x00P" + + "acific/BougainvilleUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x10\x80\x00\x00\x00\xccC6`\xd2+l\xf0T\x9e׀\u007f\xff\xff\xff\x01\x02\x01\x03\x03\x00\x00\x91\xd8" + + "\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x9a\xb0\x00\fLMT\x00+10\x00+09\x00+11\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xffV\xb6R(\xff\xff\xff\xffr\xed\xa4\x90\xff\xff\xff\xff\xccC6`\xff\xff\xff\xff\xd2+l\xf0\x00\x00\x00\x00T\x9e׀" + + "\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x02\x04\x04\x00\x00\x91\xd8\x00\x00\x00\x00\x89\xf0\x00\x04\x00\x00\x8c\xa0\x00\t\x00\x00~\x90\x00\r\x00\x00\x9a\xb0\x00\x11LMT\x00PMMT\x00+10\x00+09" + + "\x00+11\x00\n<+11>-11\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa4\xdbp$\xa6\x00\x00\x00\xa6\x00\x00\x00\x0e\x00\x1c\x00Pacific/TarawaU" + + "T\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\x80\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x00\xa24\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff~6\x12\xcc\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x01\x00\x00\xa24\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+" + + "12\x00\n<+12>-12\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x04>\xe0gA\x02\x00\x00A\x02\x00\x00\x11\x00\x1c\x00Pacific/Rarotonga" + + "UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x1c\x00\x00\x00\x04\x00\x00\x00\x14\x80\x00\x00\x00\x10\xac\x1b(\x11?\xb5\x18\x12y\x81 \x13\x1f\x97\x18\x14Yc \x14\xffy\x18\x169E \x16蕘\x18\"a\xa0\x18\xc8w\x98\x1a\x02C\xa0" + + "\x1a\xa8Y\x98\x1b\xe2%\xa0\x1c\x88;\x98\x1d\xc2\a\xa0\x1eh\x1d\x98\x1f\xa1\xe9\xa0 G\xff\x98!\x81ˠ\"1\x1c\x18#j\xe8 $\x10\xfe\x18%J\xca %\xf0\xe0\x18'*\xac '\xd0\xc2\x18" + + "\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\xff\xffj8\x00\x00\xff\xfflX\x00\x04\xff\xffs`\x00\n\xff\xffzh\x01\x0eLMT\x00" + + "-1030\x00-10\x00-0930\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x00\x00\x04\x00\x00\x00\x14" + + "\xff\xff\xff\xff~7J\xc8\x00\x00\x00\x00\x10\xac\x1b(\x00\x00\x00\x00\x11?\xb5\x18\x00\x00\x00\x00\x12y\x81 \x00\x00\x00\x00\x13\x1f\x97\x18\x00\x00\x00\x00\x14Yc \x00\x00\x00\x00\x14\xffy\x18\x00\x00\x00\x00" + + "\x169E \x00\x00\x00\x00\x16蕘\x00\x00\x00\x00\x18\"a\xa0\x00\x00\x00\x00\x18\xc8w\x98\x00\x00\x00\x00\x1a\x02C\xa0\x00\x00\x00\x00\x1a\xa8Y\x98\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\x88;\x98" + + "\x00\x00\x00\x00\x1d\xc2\a\xa0\x00\x00\x00\x00\x1eh\x1d\x98\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 G\xff\x98\x00\x00\x00\x00!\x81ˠ\x00\x00\x00\x00\"1\x1c\x18\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00" + + "$\x10\xfe\x18\x00\x00\x00\x00%J\xca \x00\x00\x00\x00%\xf0\xe0\x18\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xd0\xc2\x18\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x02\xff\xffj8\x00\x00\xff\xfflX\x00\x04\xff\xffs`\x00\n\xff\xffzh\x01\x0eLMT\x00-1030\x00-10\x00-0930\x00\n<-1" + + "0>10\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cPy|\x8dܯ\x00\x00\x00\xaf\x00\x00\x00\r\x00\x1c\x00Pacific/SamoaUT\t\x00\x03nӧ^nӧ" + + "^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\b" + + "\x80\x00\x00\x00\x91\x05\xfb\b\x01\x02\x00\x00\xb1x\x00\x00\xff\xff_\xf8\x00\x00\xff\xffeP\x00\x04LMT\x00SST\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\b\xff\xff\xff\xffn=\xc8\b\xff\xff\xff\xff\x91\x05\xfb\b\x01\x02\x00\x00\xb1x\x00\x00\xff\xff_\xf8\x00\x00\xff\xffeP\x00\x04LMT\x00" + + "SST\x00\nSST11\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x83kȗ\xee\x00\x00\x00\xee\x00\x00\x00\x12\x00\x1c\x00Pacific/KiritimatiU" + + "T\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\x80\x00\x00\x00\x12U\xf2\x00/\x05+\xa0\u007f\xff\xff\xff\x01\x02\x03\x03\xff\xffl\x80\x00\x00\xff\xffj\x00\x00\x04\xff\xffs`\x00\n\x00\x00\xc4\xe0\x00\x0eLMT\x00-" + + "1040\x00-10\x00+14\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff" + + "\xff~7H\x80\x00\x00\x00\x00\x12U\xf2\x00\x00\x00\x00\x00/\x05+\xa0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x03\xff\xffl\x80\x00\x00\xff\xffj\x00\x00\x04\xff\xffs`\x00\n\x00\x00\xc4\xe0\x00\x0eLMT" + + "\x00-1040\x00-10\x00+14\x00\n<+14>-14\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x0f\xbb\x9eK\xea\x00\x00\x00\xea\x00\x00\x00\x11\x00\x1c\x00Pacif" + + "ic/EnderburyUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\x80\x00\x00\x00\x12V\x04\xc0/\x059\xb0\u007f\xff\xff\xff\x01\x02\x03\x03\xff\xff_\x9c\x00\x00\xff\xffW@\x00\x04\xff\xffeP" + + "\x00\b\x00\x00\xb6\xd0\x00\fLMT\x00-12\x00-11\x00+13\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04" + + "\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff~7Ud\x00\x00\x00\x00\x12V\x04\xc0\x00\x00\x00\x00/\x059\xb0\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x03\xff\xff_\x9c\x00\x00\xff\xffW@\x00\x04\xff\xffeP" + + "\x00\b\x00\x00\xb6\xd0\x00\fLMT\x00-12\x00-11\x00+13\x00\n<+13>-13\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa5\xb8\xb6C^\n\x00\x00^\n\x00\x00" + + "\x06\x00\x1c\x00PolandUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\v\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\xa5\x00\x00\x00\v\x00\x00\x00\x1a\x80\x00\x00\x00\x99\xa8*Л\f\x17`\x9b\xd5\xda\xf0\x9cٮ\x90\x9d\xa4\xb5\x90\x9e\xb9\x90\x90\x9f\x84\x97\x90\xa0\x9a\xb6\x00\xa1e" + + "\xbd\x00\xa6}|`\xc8v\xde\x10\xcc\xe7K\x10ͩ\x17\x90\u03a2C\x10ϒ4\x10Є\xba\x00ѕ\x92pҊ\xbb`\xd3b\xffp\xd4K#\x90\xd5^\xad\x10\xd6)\xb4\x10\xd7,\x1a\x10\xd8\t" + + "\x96\x10\xd9\x02\xc1\x90\xd9\xe9x\x10\xe8T\xd2\x00\xe8\xf1\xb4\x80\xe9᥀\xeaі\x80\xec\x14\x96\x00캳\x00\xed\xaa\xa4\x00\ue695\x00\xef\xd4Z\x00\xf0zw\x00\xf1\xb4<\x00\xf2ZY\x00\xf3\x94" + + "\x1e\x00\xf4:;\x00\xf5}:\x80\xf6\x1a\x1d\x00\r\xa4U\x80\x0e\x8b\f\x00\x0f\x847\x80\x10t(\x80\x11d\x19\x80\x12T\n\x80\x13M6\x00\x143\xec\x80\x15#݀\x16\x13\u0380\x17\x03\xbf\x80\x17\xf3" + + "\xb0\x80\x18㡀\x19Ӓ\x80\x1aÃ\x80\x1b\xbc\xaf\x00\x1c\xac\xa0\x00\x1d\x9c\x91\x00\x1e\x8c\x82\x00\x1f|s\x00 ld\x00!\\U\x00\"LT\x10#\x86A\x90?\x9b\x1c\x90@f#\x90A\x849\x10BF" + + "\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac\xa1\x90Onn\x10P\x8c" + + "\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0\x11\x10]\xb4\xec\x10^\u007f" + + "\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xddT\x90k\xa8[\x90l\xc6" + + "q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0\xc4\x10y\xeeِz\xb0" + + "\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x03\x02\x03\x04\x05\x04\b\x06\a\x03\x02\x05\x04\x05\x04\x03\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" + + "\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t" + + "\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t" + + "\n\t\n\t\n\t\n\x00\x00\x13\xb0\x00\x00\x00\x00\x13\xb0\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00*0\x01\x11\x00\x00\x1c \x00\x16\x00\x00\x1c \x00" + + "\x16\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00WMT\x00CEST\x00CET\x00EEST\x00EET\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" + + "\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\xa5\x00\x00\x00\v\x00\x00\x00\x1a\xff\xff\xff\xffV\xb6\xd0P\xff\xff\xff\xff\x99\xa8*" + + "\xd0\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xa0\x9a\xb6\x00\xff\xff\xff" + + "\xff\xa1e\xbd\x00\xff\xff\xff\xff\xa6}|`\xff\xff\xff\xff\xc8v\xde\x10\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЄ\xba" + + "\x00\xff\xff\xff\xffѕ\x92p\xff\xff\xff\xffҊ\xbb`\xff\xff\xff\xff\xd3b\xffp\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd5^\xad\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff" + + "\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\xff\xff\xff\xff\xe8T\xd2\x00\xff\xff\xff\xff\xe8\xf1\xb4\x80\xff\xff\xff\xff\xe9᥀\xff\xff\xff\xff\xeaі\x80\xff\xff\xff\xff\xec\x14\x96" + + "\x00\xff\xff\xff\xff캳\x00\xff\xff\xff\xff\xed\xaa\xa4\x00\xff\xff\xff\xff\ue695\x00\xff\xff\xff\xff\xef\xd4Z\x00\xff\xff\xff\xff\xf0zw\x00\xff\xff\xff\xff\xf1\xb4<\x00\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff" + + "\xff\xf3\x94\x1e\x00\xff\xff\xff\xff\xf4:;\x00\xff\xff\xff\xff\xf5}:\x80\xff\xff\xff\xff\xf6\x1a\x1d\x00\x00\x00\x00\x00\r\xa4U\x80\x00\x00\x00\x00\x0e\x8b\f\x00\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10t(" + + "\x80\x00\x00\x00\x00\x11d\x19\x80\x00\x00\x00\x00\x12T\n\x80\x00\x00\x00\x00\x13M6\x00\x00\x00\x00\x00\x143\xec\x80\x00\x00\x00\x00\x15#݀\x00\x00\x00\x00\x16\x13\u0380\x00\x00\x00\x00\x17\x03\xbf\x80\x00\x00\x00" + + "\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18㡀\x00\x00\x00\x00\x19Ӓ\x80\x00\x00\x00\x00\x1aÃ\x80\x00\x00\x00\x00\x1b\xbc\xaf\x00\x00\x00\x00\x00\x1c\xac\xa0\x00\x00\x00\x00\x00\x1d\x9c\x91\x00\x00\x00\x00\x00\x1e\x8c\x82" + + "\x00\x00\x00\x00\x00\x1f|s\x00\x00\x00\x00\x00 ld\x00\x00\x00\x00\x00!\\U\x00\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00" + + "\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1" + + "\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00" + + "\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70" + + "\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00" + + "\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae" + + "\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00" + + "\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e" + + "\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00" + + "\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x03\x02\x03\x04\x05\x04\b\x06\a\x03\x02\x05\x04\x05" + + "\x04\x03\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\t\n\t\n\t\n\t\n\t\n" + + "\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n" + + "\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\x00\x00\x13\xb0\x00\x00\x00\x00\x13\xb0\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x01\b" + + "\x00\x00\x0e\x10\x00\r\x00\x00*0\x01\x11\x00\x00\x1c \x00\x16\x00\x00\x1c \x00\x16\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00WMT\x00CEST\x00CET\x00EEST\x00EE" + + "T\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00" + + "\x00\x00\xf5F\x9cP\xf2J꿍\r\x00\x00\x8d\r\x00\x00\b\x00\x1c\x00PortugalUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZ" + + "if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\xde\x00\x00\x00\f\x00\x00\x00\x1b\x80\x00\x00\x00\x92掀\x9bKmp\x9b\xfeǀ\x9c\x9c" + + "\xedp\x9dɃp\x9e\u007frp\x9f\xaa\xb6\xf0\xa0_Tp\xa1\x8b\xeap\xa2A\xd9p\xa3nop\xa4#\f\xf0\xa5O\xa2\xf0\xaa\x05\xefp\xaa\xf4\x8e\xf0\xadɧ\xf0\xae\xa7#\xf0\xaf\xa0Op\xb0\x87" + + "\x05\xf0\xb1\x89k\xf0\xb2p\"p\xb3r\x88p\xb4P\x04p\xb72Lp\xb8\x0f\xc8p\xb8\xff\xb9p\xb9\xef\xaap\xbcȷ\U0003de28\xf0\xbe\x9f_p\xbf\x98\x8a\xf0\xc0\x9a\xf0\xf0\xc1xl\xf0\xc2h" + + "]\xf0\xc3XN\xf0\xc4?\x05p\xc580\xf0\xc6:\x96\xf0\xc7X\xacp\xc7\xd9\xdfp\xc9\x01/p\xc9\xf1 p\xca\xe2b\xf0˵R\xf0\xcb\xec\xa3\xe0̀K\xe0\xccܢ\xf0͕4\xf0\xcd\xc3" + + "K`\xcer\xa2\xe0\xceſp\xcfu\x16\xf0Ϭg\xe0\xd0R\x84\xe0Х\xa1p\xd1T\xf8\xf0ьI\xe0\xd22f\xe0҅\x83p\xd3Y\xc4\xf0\xd4I\xb5\xf0\xd59\xd1 \xd6)\xc2 \xd7\x19" + + "\xb3 \xd8\t\xa4 \xd8\xf9\x95 \xd9\xe9\x86 ܹY ݲ\x84\xa0ޢu\xa0ߒf\xa0\xe0\x82W\xa0\xe1rH\xa0\xe2b9\xa0\xe3R*\xa0\xe4B\x1b\xa0\xe52\f\xa0\xe6!\xfd\xa0\xe7\x1b" + + ") \xe8\v\x1a \xe8\xfb\v \xe9\xea\xfc \xea\xda\xed \xeb\xca\xde \xec\xba\xcf \xed\xaa\xc0 \ue6b1 \uf2a2 \xf0z\x93 \xf1j\x84 \xf2c\xaf\xa0\xf3S\xa0\xa0\xf4C\x91\xa0\xf53" + + "\x82\xa0\xf6#s\xa0\xf7\x13d\xa0\xf8\x03U\xa0\xf8\xf3F\xa0\f\xab*\x00\r\x9b\x1b\x00\x0e\x8b\f\x00\x0f\x847\x80\x10t(\x80\x11d\x19\x80\x12T\x18\x90\x13C\xfb\x80\x143\xfa\x90\x15#\xeb\x90\x16\x13" + + "ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㽠\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90@f" + + "#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10N\xac" + + "\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10\\\xa0" + + "\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90j\xdd" + + "T\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90x\xd0" + + "\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x00\x06\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x03\x04\x03\x05\x03\x04\x03\x05\x03\x04\x03\x05\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" + + "\x03\x04\x03\x04\x03\x04\x03\x04\a\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\b\t\b\t\b\t\b\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06" + + "\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06" + + "\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\xff\xff\xf7c\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\t\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\t\x00\x00\x1c \x01\r\x00\x00\x00\x00\x00\t\x00\x00\x0e\x10\x00\x12" + + "\x00\x00\x0e\x10\x00\x12\x00\x00\x1c \x01\x16\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\tLMT\x00WEST\x00WET\x00WEMT\x00CET\x00CEST\x00\x00\x00\x00\x01\x01\x01\x01\x00\x01" + + "\x01\x01\x01\x00\x00\x00\x00\x00\x00\x01\x00\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\xde\x00\x00\x00\f\x00\x00\x00\x1b\xff" + + "\xff\xff\xff^=\f\x1d\xff\xff\xff\xff\x92掀\xff\xff\xff\xff\x9bKmp\xff\xff\xff\xff\x9b\xfeǀ\xff\xff\xff\xff\x9c\x9c\xedp\xff\xff\xff\xff\x9dɃp\xff\xff\xff\xff\x9e\u007frp\xff\xff\xff\xff\x9f" + + "\xaa\xb6\xf0\xff\xff\xff\xff\xa0_Tp\xff\xff\xff\xff\xa1\x8b\xeap\xff\xff\xff\xff\xa2A\xd9p\xff\xff\xff\xff\xa3nop\xff\xff\xff\xff\xa4#\f\xf0\xff\xff\xff\xff\xa5O\xa2\xf0\xff\xff\xff\xff\xaa\x05\xefp\xff" + + "\xff\xff\xff\xaa\xf4\x8e\xf0\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2p\"p\xff\xff\xff\xff\xb3" + + "r\x88p\xff\xff\xff\xff\xb4P\x04p\xff\xff\xff\xff\xb72Lp\xff\xff\xff\xff\xb8\x0f\xc8p\xff\xff\xff\xff\xb8\xff\xb9p\xff\xff\xff\xff\xb9\xef\xaap\xff\xff\xff\xff\xbcȷ\xf0\xff\xff\xff\xff\xbd\xb8\xa8\xf0\xff" + + "\xff\xff\xff\xbe\x9f_p\xff\xff\xff\xff\xbf\x98\x8a\xf0\xff\xff\xff\xff\xc0\x9a\xf0\xf0\xff\xff\xff\xff\xc1xl\xf0\xff\xff\xff\xff\xc2h]\xf0\xff\xff\xff\xff\xc3XN\xf0\xff\xff\xff\xff\xc4?\x05p\xff\xff\xff\xff\xc5" + + "80\xf0\xff\xff\xff\xff\xc6:\x96\xf0\xff\xff\xff\xff\xc7X\xacp\xff\xff\xff\xff\xc7\xd9\xdfp\xff\xff\xff\xff\xc9\x01/p\xff\xff\xff\xff\xc9\xf1 p\xff\xff\xff\xff\xca\xe2b\xf0\xff\xff\xff\xff˵R\xf0\xff" + + "\xff\xff\xff\xcb\xec\xa3\xe0\xff\xff\xff\xff̀K\xe0\xff\xff\xff\xff\xccܢ\xf0\xff\xff\xff\xff͕4\xf0\xff\xff\xff\xff\xcd\xc3K`\xff\xff\xff\xff\xcer\xa2\xe0\xff\xff\xff\xff\xceſp\xff\xff\xff\xff\xcf" + + "u\x16\xf0\xff\xff\xff\xffϬg\xe0\xff\xff\xff\xff\xd0R\x84\xe0\xff\xff\xff\xffХ\xa1p\xff\xff\xff\xff\xd1T\xf8\xf0\xff\xff\xff\xffьI\xe0\xff\xff\xff\xff\xd22f\xe0\xff\xff\xff\xff҅\x83p\xff" + + "\xff\xff\xff\xd3Y\xc4\xf0\xff\xff\xff\xff\xd4I\xb5\xf0\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd6)\xc2 \xff\xff\xff\xff\xd7\x19\xb3 \xff\xff\xff\xff\xd8\t\xa4 \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xd9" + + "\xe9\x86 \xff\xff\xff\xffܹY \xff\xff\xff\xffݲ\x84\xa0\xff\xff\xff\xffޢu\xa0\xff\xff\xff\xffߒf\xa0\xff\xff\xff\xff\xe0\x82W\xa0\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2b9\xa0\xff" + + "\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4B\x1b\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6!\xfd\xa0\xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\v\x1a \xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9" + + "\xea\xfc \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xca\xde \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xaa\xc0 \xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\uf2a2 \xff\xff\xff\xff\xf0z\x93 \xff" + + "\xff\xff\xff\xf1j\x84 \xff\xff\xff\xff\xf2c\xaf\xa0\xff\xff\xff\xff\xf3S\xa0\xa0\xff\xff\xff\xff\xf4C\x91\xa0\xff\xff\xff\xff\xf53\x82\xa0\xff\xff\xff\xff\xf6#s\xa0\xff\xff\xff\xff\xf7\x13d\xa0\xff\xff\xff\xff\xf8" + + "\x03U\xa0\xff\xff\xff\xff\xf8\xf3F\xa0\x00\x00\x00\x00\f\xab*\x00\x00\x00\x00\x00\r\x9b\x1b\x00\x00\x00\x00\x00\x0e\x8b\f\x00\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11d\x19\x80\x00" + + "\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13C\xfb\x80\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18" + + "㽠\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00" + + "\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00C" + + "d\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00" + + "\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00Q" + + "W\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00" + + "\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_" + + "\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00" + + "\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m" + + "\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00" + + "\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{" + + "λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x00\x06\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x03\x04\x03\x05\x03\x04\x03\x05\x03\x04\x03\x05\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\a\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\b\t\b\t\b\t\b\n\x06\n\x06\n\x06\n" + + "\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n" + + "\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\n\x06\xff\xff\xf7c\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\t\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\t\x00\x00\x1c \x01\r\x00\x00\x00\x00\x00\t\x00" + + "\x00\x0e\x10\x00\x12\x00\x00\x0e\x10\x00\x12\x00\x00\x1c \x01\x16\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\tLMT\x00WEST\x00WET\x00WEMT\x00CET\x00CEST\x00\x00\x00\x00\x01" + + "\x01\x01\x01\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x01\x00\x01\x01\x01\x01\nWET0WEST,M3.5.0/1,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9c" + + "P\xc7\x1a\x03B\xf9\x02\x00\x00\xf9\x02\x00\x00\x03\x00\x1c\x00ROCUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00\x05\x00\x00\x00\x10\x80\x00\x00\x00\xc3UI\x80\xd2TY\x80Ӌ{\x80\xd4B\xad\xf0\xd5E\"\x00\xd6L\xbf\xf0" + + "\xd7<\xbf\x00\xd8\x06fp\xd9\x1d\xf2\x80\xd9\xe7\x99\xf0\xda\xff&\x00\xdb\xc8\xcdp\xdc\xe0Y\x80ݪ\x00\xf0\xders\x00ߵdp\xe0|\x85\x00ᖗ\xf0\xe2]\xb8\x80\xe3w\xcbp\xe4>\xec\x00" + + "\xe50 p\xe6!q\x00\xe7\x12\xa5p\xe8\x02\xa4\x80\xe8\xf3\xd8\xf0\xe9\xe3\xd8\x00\xea\xd5\fp\xeb\xc5\v\x80\xec\xb6?\xf0\xed\xf7\xfc\x00\xee\x98\xc4\xf0\xef\xd9/\x80\xf0y\xf8p\a\xfcV\x00\b\xed\x8ap" + + "\t݉\x80\nν\xf0\x11ۡ\x80\x12T\xddp\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x00\x00q" + + "\xe8\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x00\b\x00\x00~\x90\x01\f\x00\x00p\x80\x00\x04LMT\x00CST\x00JST\x00CDT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xfft\xce\xf0\x18\xff\xff\xff\xff\xc3UI\x80\xff\xff\xff\xff\xd2TY\x80\xff\xff\xff\xffӋ{\x80\xff" + + "\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9\xe7\x99\xf0\xff\xff\xff\xff\xda" + + "\xff&\x00\xff\xff\xff\xff\xdb\xc8\xcdp\xff\xff\xff\xff\xdc\xe0Y\x80\xff\xff\xff\xffݪ\x00\xf0\xff\xff\xff\xff\xders\x00\xff\xff\xff\xffߵdp\xff\xff\xff\xff\xe0|\x85\x00\xff\xff\xff\xffᖗ\xf0\xff" + + "\xff\xff\xff\xe2]\xb8\x80\xff\xff\xff\xff\xe3w\xcbp\xff\xff\xff\xff\xe4>\xec\x00\xff\xff\xff\xff\xe50 p\xff\xff\xff\xff\xe6!q\x00\xff\xff\xff\xff\xe7\x12\xa5p\xff\xff\xff\xff\xe8\x02\xa4\x80\xff\xff\xff\xff\xe8" + + "\xf3\xd8\xf0\xff\xff\xff\xff\xe9\xe3\xd8\x00\xff\xff\xff\xff\xea\xd5\fp\xff\xff\xff\xff\xeb\xc5\v\x80\xff\xff\xff\xff\xec\xb6?\xf0\xff\xff\xff\xff\xed\xf7\xfc\x00\xff\xff\xff\xff\xee\x98\xc4\xf0\xff\xff\xff\xff\xef\xd9/\x80\xff" + + "\xff\xff\xff\xf0y\xf8p\x00\x00\x00\x00\a\xfcV\x00\x00\x00\x00\x00\b\xed\x8ap\x00\x00\x00\x00\t݉\x80\x00\x00\x00\x00\nν\xf0\x00\x00\x00\x00\x11ۡ\x80\x00\x00\x00\x00\x12T\xddp\x01\x02\x01\x03\x01" + + "\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x00\x00q\xe8\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x00\b\x00\x00~\x90\x01\f" + + "\x00\x00p\x80\x00\x04LMT\x00CST\x00JST\x00CDT\x00\nCST-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe3\x16\xfb\xddi\x02\x00\x00i\x02\x00\x00\x03\x00\x1c\x00R" + + "OKUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x1d\x00\x00\x00\a\x00\x00\x00\x10\x8b\xd7\xf0x\x92\xe6\x16\xf8\xd2C'\xf0\xd7e\x8fp\xd7\xee\x9d`\xd8\xf8\xfap\xd9\xcd-\xe0\xda\u05ca\xf0ۭ\x0f\xe0\xdc\xe6\xe2\xf0\u074c\xf1\xe0\xe2O" + + ")\xf0\xe4k\xb7\xf8\xe5\x13\x18h\xe6b\x03x\xe7\x11L\xe8\xe8/px\xe8\xe7\xf4h\xea\x0fRx\xea\xc7\xd6h\xeb\xef4x째h\xed\xcf\x16x\ue1dah\xf05qx \xa3`\x90!n" + + "g\x90\"\x83B\x90#NI\x90\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x04\x03\x04\x03\x04\x00\x00w\b\x00\x00\x00\x00w\x88\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c" + + "\xa0\x01\f\x00\x00~\x90\x00\x04\x00\x00\x85\x98\x01\f\x00\x00\x8c\xa0\x01\fLMT\x00KST\x00JST\x00KDT\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\a\x00\x00\x00\x10\xff\xff\xff\xff\x8b\xd7\xf0x\xff\xff\xff\xff\x92\xe6\x16\xf8\xff\xff\xff\xff\xd2C'\xf0\xff\xff\xff\xff\xd7e\x8fp\xff\xff\xff\xff\xd7\xee\x9d" + + "`\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xd9\xcd-\xe0\xff\xff\xff\xff\xda\u05ca\xf0\xff\xff\xff\xffۭ\x0f\xe0\xff\xff\xff\xff\xdc\xe6\xe2\xf0\xff\xff\xff\xff\u074c\xf1\xe0\xff\xff\xff\xff\xe2O)\xf0\xff\xff\xff" + + "\xff\xe4k\xb7\xf8\xff\xff\xff\xff\xe5\x13\x18h\xff\xff\xff\xff\xe6b\x03x\xff\xff\xff\xff\xe7\x11L\xe8\xff\xff\xff\xff\xe8/px\xff\xff\xff\xff\xe8\xe7\xf4h\xff\xff\xff\xff\xea\x0fRx\xff\xff\xff\xff\xea\xc7\xd6" + + "h\xff\xff\xff\xff\xeb\xef4x\xff\xff\xff\xff째h\xff\xff\xff\xff\xed\xcf\x16x\xff\xff\xff\xff\ue1dah\xff\xff\xff\xff\xf05qx\x00\x00\x00\x00 \xa3`\x90\x00\x00\x00\x00!ng\x90\x00\x00\x00" + + "\x00\"\x83B\x90\x00\x00\x00\x00#NI\x90\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x04\x03\x04\x03\x04\x00\x00w\b\x00\x00\x00\x00w\x88\x00\x04\x00\x00~\x90\x00\b" + + "\x00\x00\x8c\xa0\x01\f\x00\x00~\x90\x00\x04\x00\x00\x85\x98\x01\f\x00\x00\x8c\xa0\x01\fLMT\x00KST\x00JST\x00KDT\x00\nKST-9\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9c" + + "P\b\x01\xc8*\u007f\x01\x00\x00\u007f\x01\x00\x00\t\x00\x1c\x00SingaporeUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\b\x00\x00\x00 \x80\x00\x00\x00\x86\x83\x85\xa3\xbagN\x90\xc0\n\xe4`ʳ\xe5`ˑ" + + "_\b\xd2Hm\xf0\x16\x91\xf5\b\u007f\xff\xff\xff\x01\x02\x03\x04\x05\x06\x05\a\a\x00\x00a]\x00\x00\x00\x00a]\x00\x04\x00\x00bp\x00\b\x00\x00g \x01\f\x00\x00g \x00\f\x00\x00ix\x00\x12\x00" + + "\x00~\x90\x00\x18\x00\x00p\x80\x00\x1cLMT\x00SMT\x00+07\x00+0720\x00+0730\x00+09\x00+08\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\b\x00\x00\x00 \xff\xff\xff\xff~6S\xa3\xff\xff\xff\xff\x86\x83\x85\xa3\xff\xff\xff\xff\xbagN\x90\xff\xff\xff\xff\xc0\n\xe4`\xff" + + "\xff\xff\xffʳ\xe5`\xff\xff\xff\xffˑ_\b\xff\xff\xff\xff\xd2Hm\xf0\x00\x00\x00\x00\x16\x91\xf5\b\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x02\x03\x04\x05\x06\x05\a\a\x00\x00a]\x00\x00\x00\x00a]\x00\x04" + + "\x00\x00bp\x00\b\x00\x00g \x01\f\x00\x00g \x00\f\x00\x00ix\x00\x12\x00\x00~\x90\x00\x18\x00\x00p\x80\x00\x1cLMT\x00SMT\x00+07\x00+0720\x00+0730\x00" + + "+09\x00+08\x00\n<+08>-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc2\xf47\xbd\x9b\a\x00\x00\x9b\a\x00\x00\x06\x00\x1c\x00TurkeyUT\t\x00\x03n\xd3" + + "\xa7^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00t\x00\x00\x00" + + "\v\x00\x00\x00\x19\x80\x00\x00\x00\x90\x8b\xf5\x98\x9b\f\x17`\x9bվТec\xe0\xa3{\x82P\xa4N\x80`\xa5?\xb4Ц%'\xe0\xa7'\u007fЪ((`\xaa\xe1\xfdЫ\xf9\x89\xe0\xac\xc31" + + "Pȁ?\xe0\xc9\x01\x13P\xc9J\xf5`\xca\u0380P\xcbˮ`\xd2k\tPӢ9`\xd4C\x02P\xd5L\r\xe0\xd6){\xd0\xd7+\xef\xe0\xd8\t]\xd0\xd9\x02\x97`\xd9\xe9?\xd0\xda\xeb\xb3" + + "\xe0\xdb\xd2\\P\xdc\xd4\xd0`ݲ>P\xf1\xf4\xb9`\xf4b\xefP\xf5h\x06`\xf6\x1f8\xd0\x06n\x93p\a9\x9ap\a\xfbu\x00\t\x19|p\t\xd0\xcb\x00\n\xf9^p\v\xb1\xfe\x80\f\xd9@" + + "p\r\xa4U\x80\x0e\xa6\xadp\x0f\x847\x80\x0f\xf8\x11P\x19\x89\xb0p\x19ܰ\xe0\x1b\xe6\xd0\xf0\x1c\xc6\xef\xf0\x1d\x9b1p\x1e\x8cs\xf0\x1f|d\xf0 lU\xf0!\\F\xf0\"L7\xf0#<(" + + "\xf0$,\x19\xf0%\x1c\n\xf0&\v\xfb\xf0'\x05'p'\xf5\x18p(\xe5\tp)\xd4\xfap*\xc4\xebp+\xb4\xdcp,\xa4\xcdp-\x8b\x83\xf0.\x84\xafp/t\xa0p0d\x91p1]\xbc" + + "\xf02r\x97\xf03=\x9e\xf04Ry\xf05\x1d\x80\xf062[\xf06\xfdb\xf08\x1bxp8\xddD\xf09\xfbZp:\xbd&\xf0;\xdb\x86%p?\x9b\x00" + + "p@f\apA\x84\x1c\xf0BE\xe9pCc\xfe\xf0D%\xcbpEC\xe0\xf0F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8f\xdd" + + "\x90N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S8\xbe\x10TLG\x90U\x17N\x90V>\x9e\x90V\xf70\x90W\xcf.P\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" + + "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x03\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" + + "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\x04\x04\x00\x00\x1b(\x00\x00\x00\x00\x1bh\x00\x04\x00\x00*" + + "0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x00\x11\x00\x008@\x01\x15\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x00\x11LMT\x00IMT\x00E" + + "EST\x00EET\x00+03\x00+04\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\v\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00t\x00\x00\x00\v\x00\x00\x00\x19\xff\xff\xff\xffV\xb6\xc8\xd8\xff\xff\xff\xff\x90\x8b\xf5\x98\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9bվ\xd0\xff\xff\xff\xff\xa2e" + + "c\xe0\xff\xff\xff\xff\xa3{\x82P\xff\xff\xff\xff\xa4N\x80`\xff\xff\xff\xff\xa5?\xb4\xd0\xff\xff\xff\xff\xa6%'\xe0\xff\xff\xff\xff\xa7'\u007f\xd0\xff\xff\xff\xff\xaa((`\xff\xff\xff\xff\xaa\xe1\xfd\xd0\xff\xff" + + "\xff\xff\xab\xf9\x89\xe0\xff\xff\xff\xff\xac\xc31P\xff\xff\xff\xffȁ?\xe0\xff\xff\xff\xff\xc9\x01\x13P\xff\xff\xff\xff\xc9J\xf5`\xff\xff\xff\xff\xca\u0380P\xff\xff\xff\xff\xcbˮ`\xff\xff\xff\xff\xd2k" + + "\tP\xff\xff\xff\xffӢ9`\xff\xff\xff\xff\xd4C\x02P\xff\xff\xff\xff\xd5L\r\xe0\xff\xff\xff\xff\xd6){\xd0\xff\xff\xff\xff\xd7+\xef\xe0\xff\xff\xff\xff\xd8\t]\xd0\xff\xff\xff\xff\xd9\x02\x97`\xff\xff" + + "\xff\xff\xd9\xe9?\xd0\xff\xff\xff\xff\xda\xeb\xb3\xe0\xff\xff\xff\xff\xdb\xd2\\P\xff\xff\xff\xff\xdc\xd4\xd0`\xff\xff\xff\xffݲ>P\xff\xff\xff\xff\xf1\xf4\xb9`\xff\xff\xff\xff\xf4b\xefP\xff\xff\xff\xff\xf5h" + + "\x06`\xff\xff\xff\xff\xf6\x1f8\xd0\x00\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\a9\x9ap\x00\x00\x00\x00\a\xfbu\x00\x00\x00\x00\x00\t\x19|p\x00\x00\x00\x00\t\xd0\xcb\x00\x00\x00\x00\x00\n\xf9^p\x00\x00" + + "\x00\x00\v\xb1\xfe\x80\x00\x00\x00\x00\f\xd9@p\x00\x00\x00\x00\r\xa4U\x80\x00\x00\x00\x00\x0e\xa6\xadp\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x0f\xf8\x11P\x00\x00\x00\x00\x19\x89\xb0p\x00\x00\x00\x00\x19\xdc" + + "\xb0\xe0\x00\x00\x00\x00\x1b\xe6\xd0\xf0\x00\x00\x00\x00\x1c\xc6\xef\xf0\x00\x00\x00\x00\x1d\x9b1p\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00" + + "\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5" + + "\tp\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x8b\x83\xf0\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00" + + "\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfd" + + "b\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC" + + "\xe0\xf0\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00" + + "\x00\x00L̿\x90\x00\x00\x00\x00M\x8fݐ\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S8" + + "\xbe\x10\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V>\x9e\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00W\xcf.P\x00\x00\x00\x00\u007f\xff\xff\xff\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x03\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" + + "\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\x04\x04\x00\x00\x1b(\x00\x00\x00\x00\x1bh\x00\x04\x00\x00" + + "*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x00\x11\x00\x008@\x01\x15\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x00\x11LMT\x00IMT\x00" + + "EEST\x00EET\x00+03\x00+04\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\n<+03>-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F" + + "\x9cP\xfaj.6r\x00\x00\x00r\x00\x00\x00\x03\x00\x1c\x00UCTUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x1c\x00US/UT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x99\x16" + + "\x9bpC\t\x00\x00C\t\x00\x00\t\x00\x1c\x00US/AlaskaUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00\x00\t\x00\x00\x00(\x80\x00\x00\x00ˉ6\xc0\xd2#\xf4p\xd2aB0\xfa\xd2G\xa0\xfe\xb8c@\xff" + + "\xa8F0\x00\x98E@\x01\x88(0\x02x'@\x03qD\xb0\x04aC\xc0\x05Q&\xb0\x06A%\xc0\a1\b\xb0\a\x8d_\xc0\t\x10\xea\xb0\t\xad\xdb@\n\xf0̰\v\xe0\xcb\xc0\f\xd9\xe90\r" + + "\xc0\xad\xc0\x0e\xb9\xcb0\x0f\xa9\xca@\x10\x99\xad0\x11\x89\xac@\x12y\x8f0\x13i\x8e@\x14Yq0\x15Ip@\x169S0\x17)R@\x18\"o\xb0\x19\t4@\x1a\x02Q\xb0\x1a+\x14\x10\x1a" + + "\xf2B\xb0\x1b\xe2%\xa0\x1c\xd2$\xb0\x1d\xc2\a\xa0\x1e\xb2\x06\xb0\x1f\xa1\xe9\xa0 v90!\x81ˠ\"V\x1b0#j\xe8 $5\xfd0%J\xca &\x15\xdf0'*\xac '\xfe\xfb\xb0)" + + "\n\x8e )\xdeݰ*\xeap +\xbe\xbf\xb0,ӌ\xa0-\x9e\xa1\xb0.\xb3n\xa0/~\x83\xb00\x93P\xa01g\xa002s2\xa03G\x8204S\x14\xa05'd062\xf6\xa07" + + "\aF08\x1c\x13 8\xe7(09\xfb\xf5 :\xc7\n0;\xdb\xd7 <\xb0&\xb0=\xbb\xb9 >\x90\b\xb0?\x9b\x9b @o\xea\xb0A\x84\xb7\xa0BO̰Cd\x99\xa0D/\xae\xb0E" + + "D{\xa0E\xf3\xe10G-\x98 G\xd3\xc30I\rz I\xb3\xa50J\xed\\ K\x9c\xc1\xb0L\xd6x\xa0M|\xa3\xb0N\xb6Z\xa0O\\\x85\xb0P\x96<\xa0Q\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO̰\x00\x00\x00\x00Cd\x99\xa0\x00" + + "\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x00\x00\x00\x00G-\x98 \x00\x00\x00\x00G\xd3\xc30\x00\x00\x00\x00I\rz \x00\x00\x00\x00I\xb3\xa50\x00\x00\x00\x00J" + + "\xed\\ \x00\x00\x00\x00K\x9c\xc1\xb0\x00\x00\x00\x00L\xd6x\xa0\x00\x00\x00\x00M|\xa3\xb0\x00\x00\x00\x00N\xb6Z\xa0\x00\x00\x00\x00O\\\x85\xb0\x00\x00\x00\x00P\x96<\xa0\x00\x00\x00\x00Q\x8f" + + "\xfa\xa0?\x9b\x8d\x10@oܠA\x84\xa9\x90BO\xbe\xa0Cd\x8b\x90D/\xa0\xa0EDm\x90E\xf3\xd3 G-\x8a\x10Gӵ I\rl\x10I\xb3\x97 J\xedN\x10K\x9c\xb3\xa0L\xd6" + + "j\x90M|\x95\xa0N\xb6L\x90O\\w\xa0P\x96.\x90Q\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90" + + "\x00\x00\x00\x00E\xf3\xd3 \x00\x00\x00\x00G-\x8a\x10\x00\x00\x00\x00Gӵ \x00\x00\x00\x00I\rl\x10\x00\x00\x00\x00I\xb3\x97 \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00" + + "L\xd6j\x90\x00\x00\x00\x00M|\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\\w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q\x8f\xd0p?\x9bb\xe0@o\xb2pA\x84\u007f`BO" + + "\x94pCda`D/vpEDC`E\xf3\xa8\xf0G-_\xe0Gӊ\xf0I\rA\xe0I\xb3l\xf0J\xed#\xe0K\x9c\x89pL\xd6@`M|kpN\xb6\"`O\\MpP\x96" + + "\x04`Q\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\u007f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00" + + "\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x00\x00\x00\x00G-_\xe0\x00\x00\x00\x00Gӊ\xf0\x00\x00\x00\x00I\rA\xe0\x00\x00\x00\x00I\xb3l\xf0\x00\x00\x00\x00J\xed" + + "#\xe0\x00\x00\x00\x00K\x9c\x89p\x00\x00\x00\x00L\xd6@`\x00\x00\x00\x00M|kp\x00\x00\x00\x00N\xb6\"`\x00\x00\x00\x00O\\Mp\x00\x00\x00\x00P\x96\x04`\x00\x00\x00\x00Q\x8f\xd0p?\x9bb\xe0@o\xb2pA\x84\u007f`BO\x94pCda`D/vpEDC`E" + + "\xf3\xa8\xf0G-_\xe0Gӊ\xf0I\rA\xe0I\xb3l\xf0J\xed#\xe0K\x9c\x89pL\xd6@`M|kpN\xb6\"`O\\MpP\x96\x04`Q\x8f\xd0p" + + "\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\u007f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00" + + "E\xf3\xa8\xf0\x00\x00\x00\x00G-_\xe0\x00\x00\x00\x00Gӊ\xf0\x00\x00\x00\x00I\rA\xe0\x00\x00\x00\x00I\xb3l\xf0\x00\x00\x00\x00J\xed#\xe0\x00\x00\x00\x00K\x9c\x89p\x00\x00\x00\x00L\xd6@`" + + "\x00\x00\x00\x00M|kp\x00\x00\x00\x00N\xb6\"`\x00\x00\x00\x00O\\Mp\x00\x00\x00\x00P\x96\x04`\x00\x00\x00\x00Q\x90\x16\xc0?\x9b\xa90@o\xf8\xc0A\x84ŰBO\xda\xc0Cd\xa7\xb0D/\xbc\xc0ED\x89\xb0E\xf3\xef@G-\xa60G\xd3\xd1" + + "@I\r\x880I\xb3\xb3@J\xedj0K\x9c\xcf\xc0Lֆ\xb0M|\xb1\xc0N\xb6h\xb0O\\\x93\xc0P\x96J\xb0Q\x90\x16\xc0\x00\x00" + + "\x00\x00?\x9b\xa90\x00\x00\x00\x00@o\xf8\xc0\x00\x00\x00\x00A\x84Ű\x00\x00\x00\x00BO\xda\xc0\x00\x00\x00\x00Cd\xa7\xb0\x00\x00\x00\x00D/\xbc\xc0\x00\x00\x00\x00ED\x89\xb0\x00\x00\x00\x00E\xf3" + + "\xef@\x00\x00\x00\x00G-\xa60\x00\x00\x00\x00G\xd3\xd1@\x00\x00\x00\x00I\r\x880\x00\x00\x00\x00I\xb3\xb3@\x00\x00\x00\x00J\xedj0\x00\x00\x00\x00K\x9c\xcf\xc0\x00\x00\x00\x00Lֆ\xb0\x00\x00" + + "\x00\x00M|\xb1\xc0\x00\x00\x00\x00N\xb6h\xb0\x00\x00\x00\x00O\\\x93\xc0\x00\x00\x00\x00P\x96J\xb0\x00\x00\x00\x00Q\x8fހ?\x9bp\xf0@o\xc0\x80A\x84\x8dpBO\xa2\x80CdopD/\x84\x80EDQpE\xf3\xb7\x00" + + "G-m\xf0Gә\x00I\rO\xf0I\xb3{\x00J\xed1\xf0K\x9c\x97\x80L\xd6NpM|y\x80N\xb60pO\\[\x80P\x96\x12pQ<=\x80Ru\xf4pS\x1c\x1f\x80TU\xd6p" + + "T\xfc\x01\x80V5\xb8pV\xe5\x1e\x00X\x1e\xd4\xf0X\xc5\x00\x00Y\xfe\xb6\xf0Z\xa4\xe2\x00[ޘ\xf0\\\x84\xc4\x00]\xbez\xf0^d\xa6\x00_\x9e\\\xf0`M\u0080a\x87ypb-\xa4\x80" + + "cg[pd\r\x86\x80eG=pe\xedh\x80g'\x1fpg\xcdJ\x80i\a\x01pi\xad,\x80j\xe6\xe3pk\x96I\x00l\xcf\xff\xf0mv+\x00n\xaf\xe1\xf0oV\r\x00p\x8f\xc3\xf0" + + "q5\xef\x00ro\xa5\xf0s\x15\xd1\x00tO\x87\xf0t\xfe\xed\x80v8\xa4pv\xdeπx\x18\x86px\xbe\xb1\x80y\xf8hpz\x9e\x93\x80{\xd8Jp|~u\x80}\xb8,p~^W\x80" + + "\u007f\x98\x0ep\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x05\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\xff\xff\xad\xd4\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x00\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x01\x14\xff\xff\xab\xa0\x00\bLMT\x00CDT\x00CST\x00EST\x00CW" + + "T\x00CPT\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\xec\x00\x00\x00\a" + + "\x00\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xa2\xcbt\x00\xff\xff\xff\xff\xa3\x83\xf7\xf0" + + "\xff\xff\xff\xff\xa4EҀ\xff\xff\xff\xff\xa5c\xd9\xf0\xff\xff\xff\xff\xa6S\xd9\x00\xff\xff\xff\xff\xa7\x15\x97p\xff\xff\xff\xff\xa83\xbb\x00\xff\xff\xff\xff\xa8\xfe\xb3\xf0\xff\xff\xff\xff\xaa\x13\x9d\x00\xff\xff\xff\xff" + + "\xaaޕ\xf0\xff\xff\xff\xff\xab\xf3\u007f\x00\xff\xff\xff\xff\xac\xbew\xf0\xff\xff\xff\xff\xad\xd3a\x00\xff\xff\xff\xff\xae\x9eY\xf0\xff\xff\xff\xff\xaf\xb3C\x00\xff\xff\xff\xff\xb0~;\xf0\xff\xff\xff\xff\xb1\x9c_\x80" + + "\xff\xff\xff\xff\xb2gXp\xff\xff\xff\xff\xb3|A\x80\xff\xff\xff\xff\xb4G:p\xff\xff\xff\xff\xb5\\#\x80\xff\xff\xff\xff\xb6'\x1cp\xff\xff\xff\xff\xb7<\x05\x80\xff\xff\xff\xff\xb8\x06\xfep\xff\xff\xff\xff" + + "\xb9\x1b\xe7\x80\xff\xff\xff\xff\xb9\xe6\xe0p\xff\xff\xff\xff\xbb\x05\x04\x00\xff\xff\xff\xff\xbb\xc6\xc2p\xff\xff\xff\xff\xbc\xe4\xe6\x00\xff\xff\xff\xff\xbd\xaf\xde\xf0\xff\xff\xff\xff\xbe\xc4\xc8\x00\xff\xff\xff\xff\xbf\x8f\xc0\xf0" + + "\xff\xff\xff\xff\xc0Z\xd6\x00\xff\xff\xff\xff\xc1\xb0\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop" + + "\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G-m\xf0\x00\x00\x00\x00Gә\x00\x00\x00\x00\x00I\rO\xf0\x00\x00\x00\x00I\xb3{\x00\x00\x00\x00\x00" + + "J\xed1\xf0\x00\x00\x00\x00K\x9c\x97\x80\x00\x00\x00\x00L\xd6Np\x00\x00\x00\x00M|y\x80\x00\x00\x00\x00N\xb60p\x00\x00\x00\x00O\\[\x80\x00\x00\x00\x00P\x96\x12p\x00\x00\x00\x00Q<=\x80" + + "\x00\x00\x00\x00Ru\xf4p\x00\x00\x00\x00S\x1c\x1f\x80\x00\x00\x00\x00TU\xd6p\x00\x00\x00\x00T\xfc\x01\x80\x00\x00\x00\x00V5\xb8p\x00\x00\x00\x00V\xe5\x1e\x00\x00\x00\x00\x00X\x1e\xd4\xf0\x00\x00\x00\x00" + + "X\xc5\x00\x00\x00\x00\x00\x00Y\xfe\xb6\xf0\x00\x00\x00\x00Z\xa4\xe2\x00\x00\x00\x00\x00[ޘ\xf0\x00\x00\x00\x00\\\x84\xc4\x00\x00\x00\x00\x00]\xbez\xf0\x00\x00\x00\x00^d\xa6\x00\x00\x00\x00\x00_\x9e\\\xf0" + + "\x00\x00\x00\x00`M\u0080\x00\x00\x00\x00a\x87yp\x00\x00\x00\x00b-\xa4\x80\x00\x00\x00\x00cg[p\x00\x00\x00\x00d\r\x86\x80\x00\x00\x00\x00eG=p\x00\x00\x00\x00e\xedh\x80\x00\x00\x00\x00" + + "g'\x1fp\x00\x00\x00\x00g\xcdJ\x80\x00\x00\x00\x00i\a\x01p\x00\x00\x00\x00i\xad,\x80\x00\x00\x00\x00j\xe6\xe3p\x00\x00\x00\x00k\x96I\x00\x00\x00\x00\x00l\xcf\xff\xf0\x00\x00\x00\x00mv+\x00" + + "\x00\x00\x00\x00n\xaf\xe1\xf0\x00\x00\x00\x00oV\r\x00\x00\x00\x00\x00p\x8f\xc3\xf0\x00\x00\x00\x00q5\xef\x00\x00\x00\x00\x00ro\xa5\xf0\x00\x00\x00\x00s\x15\xd1\x00\x00\x00\x00\x00tO\x87\xf0\x00\x00\x00\x00" + + "t\xfe\xed\x80\x00\x00\x00\x00v8\xa4p\x00\x00\x00\x00v\xdeπ\x00\x00\x00\x00x\x18\x86p\x00\x00\x00\x00x\xbe\xb1\x80\x00\x00\x00\x00y\xf8hp\x00\x00\x00\x00z\x9e\x93\x80\x00\x00\x00\x00{\xd8Jp" + + "\x00\x00\x00\x00|~u\x80\x00\x00\x00\x00}\xb8,p\x00\x00\x00\x00~^W\x80\x00\x00\x00\x00\u007f\x98\x0ep\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" + + "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x05\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" + + "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xad\xd4\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x00\f\xff\xff\xb9\xb0\x01\x10\xff\xff" + + "\xb9\xb0\x01\x14\xff\xff\xab\xa0\x00\bLMT\x00CDT\x00CST\x00EST\x00CWT\x00CPT\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x01\x00\nCST6CDT,M3." + + "2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc41\xb4\x85\x8c\t\x00\x00\x8c\t\x00\x00\v\x00\x1c\x00US/MountainUT\t\x00\x03n\xd3" + + "\xa7^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x9e\x00\x00\x00" + + "\x05\x00\x00\x00\x14\x80\x00\x00\x00\x9e\xa6:\x90\x9f\xbb\a\x80\xa0\x86\x1c\x90\xa1\x9a逢e\xfe\x90\xa3\x84\x06\x00\xa4E\xe0\x90\xa4\x8f\xa6\x80ˉ\f\x90\xd2#\xf4p\xd2a\x18\x00\xf7/v\x90\xf8(\x94" + + "\x00\xf9\x0fX\x90\xfa\bv\x00\xfa\xf8u\x10\xfb\xe8X\x00\xfc\xd8W\x10\xfd\xc8:\x00\xfe\xb89\x10\xff\xa8\x1c\x00\x00\x98\x1b\x10\x01\x87\xfe\x00\x02w\xfd\x10\x03q\x1a\x80\x04a\x19\x90\x05P\xfc\x80\x06@\xfb" + + "\x90\a0ހ\a\x8d5\x90\t\x10\xc0\x80\t\xad\xb1\x10\n\xf0\xa2\x80\vࡐ\fٿ\x00\r\xc0\x83\x90\x0e\xb9\xa1\x00\x0f\xa9\xa0\x10\x10\x99\x83\x00\x11\x89\x82\x10\x12ye\x00\x13id\x10\x14YG" + + "\x00\x15IF\x10\x169)\x00\x17)(\x10\x18\"E\x80\x19\t\n\x10\x1a\x02'\x80\x1a\xf2&\x90\x1b\xe2\t\x80\x1c\xd2\b\x90\x1d\xc1\xeb\x80\x1e\xb1\xea\x90\x1f\xa1̀ v\x1d\x10!\x81\xaf\x80\"U\xff" + + "\x10#j\xcc\x00$5\xe1\x10%J\xae\x00&\x15\xc3\x10'*\x90\x00'\xfeߐ)\nr\x00)\xde\xc1\x90*\xeaT\x00+\xbe\xa3\x90,\xd3p\x80-\x9e\x85\x90.\xb3R\x80/~g\x900\x934" + + "\x801g\x84\x102s\x16\x803Gf\x104R\xf8\x805'H\x1062ڀ7\a*\x108\x1b\xf7\x008\xe7\f\x109\xfb\xd9\x00:\xc6\xee\x10;ۻ\x00<\xb0\n\x90=\xbb\x9d\x00>\x8f\xec" + + "\x90?\x9b\u007f\x00@oΐA\x84\x9b\x80BO\xb0\x90Cd}\x80D/\x92\x90ED_\x80E\xf3\xc5\x10G-|\x00Gӧ\x10I\r^\x00I\xb3\x89\x10J\xed@\x00K\x9c\xa5\x90L\xd6\\" + + "\x80M|\x87\x90N\xb6>\x80O\\i\x90P\x96 \x80Q\x8f\xec\x90\x00\x00\x00\x00?\x9b\u007f\x00\x00" + + "\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x00\x00\x00\x00G" + + "-|\x00\x00\x00\x00\x00Gӧ\x10\x00\x00\x00\x00I\r^\x00\x00\x00\x00\x00I\xb3\x89\x10\x00\x00\x00\x00J\xed@\x00\x00\x00\x00\x00K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\\\x80\x00\x00\x00\x00M|\x87\x90\x00" + + "\x00\x00\x00N\xb6>\x80\x00\x00\x00\x00O\\i\x90\x00\x00\x00\x00P\x96 \x80\x00\x00\x00\x00Q\xf2y" + + "\x9e*\xee\xf9\x9e\xf79i\x9f\x84W\xf9\xa0\xd8l\xe9\xa1\x009\x80\xa1<\xa6@\xa4\x10m\xc0\xa4=2\xb0\xa5\x15h\xb0\xa5=\x03\xc0\xa7\x1eEP\xb5\xa4\x19`\x15'\xa7\xd0\x16\x18\xdc@\x17\b\xdbP" + + "\x17\xfa\x0f\xc0\x18\xea\x0e\xd0\x19\xdbC@\x1a̓\xd0\x1b\xbc\xa0\xf0\x1c\xac\x91\xf0\x1d\x9c\x82\xf0\x1e\x8cs\xf0\x1f|d\xf0 lU\xf0!\\F\xf0\"L7\xf0#<(\xf0$,\x19\xf0%\x1c\n\xf0" + + "&\v\xfb\xf0'\x05'p'\xf5\x18p(\xe5\x17\x80)x\xbf\x80)\xd4\xfap*\xc4\xebp+\xb4\xdcp,\xa4\xcdp-\x94\xbep.\x84\xafp/t\xa0p0d\x91p1]\xbc\xf02r\x97\xf0" + + "3=\x9e\xf04Ry\xf05\x1d\x80\xf062[\xf06\xfdb\xf08\x1bxp8\xddD\xf09\xfbZp:\xbd&\xf0;\xdb\x86%p?\x9b\x00p@f\ap" + + "A\x84\x1c\xf0BE\xe9pCc\xfe\xf0D%\xcbpEC\xe0\xf0F\x05\xadpG#\xc2\xf0G\xee\xc9\xf0I\x03\xa4\xf0IΫ\xf0J\xe3\x86\xf0K\xae\x8d\xf0ḶpM\x8eo\xf0TL\x1d`" + + "\x01\x03\x02\x03\x04\x02\x04\x05\x06\a\b\a\x06\t\x06\a\x06\a\x06\a\x06\a\n\v\n\v\n\v\n\v\n\v\n\v\n\f\r\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n" + + "\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\x0e\n\x00\x00#9\x00\x00\x00\x00#9\x00\x04\x00\x001\x87\x01\b\x00\x00#w\x00\x04\x00\x00?\x97\x01\f\x00\x008@\x01\x11\x00\x00*0\x00\x15" + + "\x00\x008@\x01\x11\x00\x00FP\x01\x19\x00\x00\x1c \x00\x1d\x00\x00*0\x00\x15\x00\x008@\x01\x11\x00\x00*0\x01!\x00\x00\x1c \x00\x1d\x00\x008@\x00\x15\x00\x008@\x01\x11\x00\x00*0\x00\x15" + + "LMT\x00MMT\x00MST\x00MDST\x00MSD\x00MSK\x00+05\x00EET\x00EEST\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00" + + "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00N\x00\x00\x00\x11\x00\x00\x00&\xff\xff\xff\xff" + + "V\xb6\xc0\xc7\xff\xff\xff\xff\x9b_\x1e\xc7\xff\xff\xff\xff\x9d>\xf2y\xff\xff\xff\xff\x9e*\xee\xf9\xff\xff\xff\xff\x9e\xf79i\xff\xff\xff\xff\x9f\x84W\xf9\xff\xff\xff\xff\xa0\xd8l\xe9\xff\xff\xff\xff\xa1\x009\x80" + + "\xff\xff\xff\xff\xa1<\xa6@\xff\xff\xff\xff\xa4\x10m\xc0\xff\xff\xff\xff\xa4=2\xb0\xff\xff\xff\xff\xa5\x15h\xb0\xff\xff\xff\xff\xa5=\x03\xc0\xff\xff\xff\xff\xa7\x1eEP\xff\xff\xff\xff\xb5\xa4\x19`\x00\x00\x00\x00" + + "\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0" + + "\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00" + + "#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)x\xbf\x80" + + "\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x00" + + "0d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0" + + "\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0" + + "\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00" + + "Ḷp\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x01\x03\x02\x03\x04\x02\x04\x05\x06\a\b\a\x06\t\x06\a\x06\a\x06\a\x06\a\n\v\n\v\n\v\n\v\n\v\n\v\n\f\r\n\v\n" + + "\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\v\n\x0e\n\x00\x00#9\x00\x00\x00\x00#9\x00\x04\x00\x001\x87\x01\b\x00\x00#w" + + "\x00\x04\x00\x00?\x97\x01\f\x00\x008@\x01\x11\x00\x00*0\x00\x15\x00\x008@\x01\x11\x00\x00FP\x01\x19\x00\x00\x1c \x00\x1d\x00\x00*0\x00\x15\x00\x008@\x01\x11\x00\x00*0\x01!\x00\x00\x1c " + + "\x00\x1d\x00\x008@\x00\x15\x00\x008@\x01\x11\x00\x00*0\x00\x15LMT\x00MMT\x00MST\x00MDST\x00MSD\x00MSK\x00+05\x00EET\x00EEST\x00\x00\x00" + + "\x00\x00\x00\x01\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\nMSK-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\x82\x13\x83dq\a\x00" + + "\x00q\a\x00\x00\x03\x00\x1c\x00WETUT\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00z\x00\x00\x00\x04\x00\x00\x00\t\r\xa4c\x90\x0e\x8b\x1a\x10\x0f\x84E\x90\x10t6\x90\x11d'\x90\x12T\x18\x90\x13MD\x10\x143\xfa\x90\x15#\xeb\x90" + + "\x16\x13ܐ\x17\x03͐\x17\xf3\xbe\x90\x18㯐\x19Ӡ\x90\x1aÑ\x90\x1b\xbc\xbd\x10\x1c\xac\xae\x10\x1d\x9c\x9f\x10\x1e\x8c\x90\x10\x1f|\x81\x10 lr\x10!\\c\x10\"LT\x10#\x86A\x90?\x9b\x1c\x90" + + "@f#\x90A\x849\x10BF\x05\x90Cd\x1b\x10D%\xe7\x90EC\xfd\x10F\x05ɐG#\xdf\x10G\xee\xe6\x10I\x03\xc1\x10I\xce\xc8\x10J\xe3\xa3\x10K\xae\xaa\x10L̿\x90M\x8e\x8c\x10" + + "N\xac\xa1\x90Onn\x10P\x8c\x83\x90QW\x8a\x90Rle\x90S7l\x90TLG\x90U\x17N\x90V,)\x90V\xf70\x90X\x15F\x10X\xd7\x12\x90Y\xf5(\x10Z\xb6\xf4\x90[\xd5\n\x10" + + "\\\xa0\x11\x10]\xb4\xec\x10^\u007f\xf3\x10_\x94\xce\x10`_\xd5\x10a}\xea\x90b?\xb7\x10c]̐d\x1f\x99\x10e=\xae\x90f\b\xb5\x90g\x1d\x90\x90g藐h\xfdr\x90i\xc8y\x90" + + "j\xddT\x90k\xa8[\x90l\xc6q\x10m\x88=\x90n\xa6S\x10oh\x1f\x90p\x865\x10qQ<\x10rf\x17\x10s1\x1e\x10tE\xf9\x10u\x11\x00\x10v/\x15\x90v\xf0\xe2\x10x\x0e\xf7\x90" + + "x\xd0\xc4\x10y\xeeِz\xb0\xa6\x10{λ\x90|\x99\u0090}\xae\x9d\x90~y\xa4\x90\u007f\x8e\u007f\x90\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00" + + "\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00" + + "\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x05\x00\x00\x0e\x10\x01\x00\x00\x00\x0e\x10\x01\x00\x00\x00\x00\x00\x00\x05WE" + + "ST\x00WET\x00\x01\x01\x01\x01\x01\x01\x01\x01TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00z\x00\x00\x00\x04\x00\x00\x00\t\x00" + + "\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x14" + + "3\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00" + + "\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"" + + "LT\x10\x00\x00\x00\x00#" + + "\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00" + + "\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L" + + "̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00" + + "\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z" + + "\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\u007f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00" + + "\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\x00\x00\x00\x00f\b\xb5\x90\x00\x00\x00\x00g\x1d\x90\x90\x00\x00\x00\x00g藐\x00\x00\x00\x00h" + + "\xfdr\x90\x00\x00\x00\x00i\xc8y\x90\x00\x00\x00\x00j\xddT\x90\x00\x00\x00\x00k\xa8[\x90\x00\x00\x00\x00l\xc6q\x10\x00\x00\x00\x00m\x88=\x90\x00\x00\x00\x00n\xa6S\x10\x00\x00\x00\x00oh\x1f\x90\x00" + + "\x00\x00\x00p\x865\x10\x00\x00\x00\x00qQ<\x10\x00\x00\x00\x00rf\x17\x10\x00\x00\x00\x00s1\x1e\x10\x00\x00\x00\x00tE\xf9\x10\x00\x00\x00\x00u\x11\x00\x10\x00\x00\x00\x00v/\x15\x90\x00\x00\x00\x00v" + + "\xf0\xe2\x10\x00\x00\x00\x00x\x0e\xf7\x90\x00\x00\x00\x00x\xd0\xc4\x10\x00\x00\x00\x00y\xeeِ\x00\x00\x00\x00z\xb0\xa6\x10\x00\x00\x00\x00{λ\x90\x00\x00\x00\x00|\x99\u0090\x00\x00\x00\x00}\xae\x9d\x90\x00" + + "\x00\x00\x00~y\xa4\x90\x00\x00\x00\x00\u007f\x8e\u007f\x90\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01" + + "\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01" + + "\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x05\x00\x00\x0e\x10\x01\x00\x00\x00\x0e\x10\x01\x00\x00\x00\x00\x00\x00\x05WEST\x00WET\x00\x01\x01\x01\x01\x01\x01\x01\x01\nW" + + "ET0WEST,M3.5.0/1,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfaj.6r\x00\x00\x00r\x00\x00\x00\x04\x00\x1c\x00ZuluU" + + "T\t\x00\x03nӧ^nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10" + + "\x00\xedA\x00\x00\x00\x00Africa/UT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPo\xa5)\xa4\xfe\x00" + + "\x00\x00\xfe\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81A\x00\x00\x00Africa/Sao_TomeUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14" + + "\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xae\x18\x88\x94\x00\x00\x00\x94\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x88\x01\x00\x00Africa/Cona" + + "kryUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xae\x18\x88\x94\x00\x00\x00\x94\x00\x00\x00\f\x00\x18\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\xa4\x81d\x02\x00\x00Africa/DakarUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00" + + "\x00\xf5F\x9cP\xa3\x12>\xaa\xc7\x00\x00\x00\xc7\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81>\x03\x00\x00Africa/NdjamenaUT\x05\x00\x03nӧ^u" + + "x\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xd4K-\x14}\t\x00\x00}\t\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81N\x04\x00\x00" + + "Africa/CasablancaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xae\x18" + + "\x88\x94\x00\x00\x00\x94\x00\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x16\x0e\x00\x00Africa/LomeUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00" + + "\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x8d>\xe14\xdf\x02\x00\x00\xdf\x02\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xef\x0e\x00\x00Africa/Algie" + + "rsUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPx=\xfb\xae\xfb\x00\x00\x00\xfb\x00\x00\x00\x10\x00\x18\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\xa4\x81\x16\x12\x00\x00Africa/MogadishuUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00" + + "\x00\x00\x00\x00\xf5F\x9cP.\x85\x1f\xf0\x95\x00\x00\x00\x95\x00\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81[\x13\x00\x00Africa/LagosUT\x05\x00\x03nӧ^u" + + "x\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP.\x85\x1f\xf0\x95\x00\x00\x00\x95\x00\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x816\x14\x00\x00" + + "Africa/BrazzavilleUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xae" + + "\x18\x88\x94\x00\x00\x00\x94\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x17\x15\x00\x00Africa/TimbuktuUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01" + + "\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xae\x18\x88\x94\x00\x00\x00\x94\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf4\x15\x00\x00Africa/" + + "NouakchottUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb1\x980\xb2\xf6\x00\x00\x00\xf6\x00" + + "\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xd3\x16\x00\x00Africa/MaseruUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01" + + "\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP.\x85\x1f\xf0\x95\x00\x00\x00\x95\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x10\x18\x00\x00Africa/Libreville" + + "UT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP4\x8b\xa4 \x95\x00\x00\x00\x95\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\xa4\x81\xf0\x18\x00\x00Africa/HarareUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5" + + "F\x9cP.\x85\x1f\xf0\x95\x00\x00\x00\x95\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xcc\x19\x00\x00Africa/MalaboUT\x05\x00\x03nӧ^ux\v\x00\x01" + + "\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP.\x85\x1f\xf0\x95\x00\x00\x00\x95\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa8\x1a\x00\x00Afri" + + "ca/BanguiUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPx=\xfb\xae\xfb\x00\x00\x00\xfb\x00\x00" + + "\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x84\x1b\x00\x00Africa/NairobiUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01" + + "\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP.\x85\x1f\xf0\x95\x00\x00\x00\x95\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc7\x1c\x00\x00Africa/KinshasaUT" + + "\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP.\x85\x1f\xf0\x95\x00\x00\x00\x95\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\xa4\x81\xa5\x1d\x00\x00Africa/Porto-NovoUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00" + + "\x00\xf5F\x9cPtg&ף\a\x00\x00\xa3\a\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x85\x1e\x00\x00Africa/CairoUT\x05\x00\x03nӧ^ux\v\x00" + + "\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP.\x85\x1f\xf0\x95\x00\x00\x00\x95\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81n&\x00\x00Afr" + + "ica/DoualaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP4#\xa3\xe0\x8d\x02\x00\x00\x8d\x02" + + "\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81J'\x00\x00Africa/JubaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e" + + "\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP4\x8b\xa4 \x95\x00\x00\x00\x95\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x1c*\x00\x00Africa/GaboroneUT\x05\x00" + + "\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x94\xbdb?\xb1\x02\x00\x00\xb1\x02\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\xa4\x81\xfa*\x00\x00Africa/TunisUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPx=" + + "\xfb\xae\xfb\x00\x00\x00\xfb\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf1-\x00\x00Africa/KampalaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00" + + "\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb1\x980\xb2\xf6\x00\x00\x00\xf6\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x814/\x00\x00Africa/M" + + "babaneUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPx=\xfb\xae\xfb\x00\x00\x00\xfb\x00\x00\x00\x12\x00" + + "\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81r0\x00\x00Africa/Addis_AbabaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK" + + "\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP4\x8b\xa4 \x95\x00\x00\x00\x95\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb91\x00\x00Africa/MaputoUT\x05" + + "\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xd6UH\xae\xc2\x00\x00\x00\xc2\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\xa4\x81\x952\x00\x00Africa/BissauUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP" + + "4\x8b\xa4 \x95\x00\x00\x00\x95\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9e3\x00\x00Africa/BlantyreUT\x05\x00\x03nӧ^ux\v\x00\x01\x04" + + "\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP.\x85\x1f\xf0\x95\x00\x00\x00\x95\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81|4\x00\x00Afric" + + "a/NiameyUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xae\x18\x88\x94\x00\x00\x00\x94\x00\x00\x00" + + "\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81X5\x00\x00Africa/BanjulUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e" + + "\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xae\x18\x88\x94\x00\x00\x00\x94\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x8136\x00\x00Africa/AbidjanUT\x05\x00\x03" + + "nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPx=\xfb\xae\xfb\x00\x00\x00\xfb\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4" + + "\x81\x0f7\x00\x00Africa/AsmaraUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xae" + + "\x18\x88\x94\x00\x00\x00\x94\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Q8\x00\x00Africa/BamakoUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00" + + "\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xae\x18\x88\x94\x00\x00\x00\x94\x00\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81,9\x00\x00Africa/Ou" + + "agadougouUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP4\x8b\xa4 \x95\x00\x00\x00\x95\x00\x00" + + "\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\f:\x00\x00Africa/LusakaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02" + + "\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP.\x85\x1f\xf0\x95\x00\x00\x00\x95\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe8:\x00\x00Africa/LuandaUT\x05\x00\x03" + + "nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPx=\xfb\xae\xfb\x00\x00\x00\xfb\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4" + + "\x81\xc4;\x00\x00Africa/AsmeraUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP4\x8b" + + "\xa4 \x95\x00\x00\x00\x95\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x06=\x00\x00Africa/LubumbashiUT\x05\x00\x03nӧ^ux\v\x00\x01\x04" + + "\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPҫd\x850\x03\x00\x000\x03\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe6=\x00\x00Afric" + + "a/AccraUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\u007f\xccV\xb2\xa7\x02\x00\x00\xa7\x02\x00\x00\x0f" + + "\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\\A\x00\x00Africa/KhartoumUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02" + + "\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x97\x17\x1ai\xf4\a\x00\x00\xf4\a\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81LD\x00\x00Africa/CeutaUT\x05\x00\x03n" + + "ӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP4\x8b\xa4 \x95\x00\x00\x00\x95\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81" + + "\x86L\x00\x00Africa/BujumburaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP" + + "\xe1X(\b\xbb\x03\x00\x00\xbb\x03\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81eM\x00\x00Africa/WindhoekUT\x05\x00\x03nӧ^ux\v\x00\x01\x04" + + "\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x0f%\b\xcc\xf7\b\x00\x00\xf7\b\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81iQ\x00\x00Afric" + + "a/El_AaiunUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc2ɵ,q\x02\x00\x00q\x02" + + "\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa9Z\x00\x00Africa/TripoliUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK" + + "\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP|\xe5C0\xd0\x00\x00\x00\xd0\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81b]\x00\x00Africa/MonroviaU" + + "T\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPx=\xfb\xae\xfb\x00\x00\x00\xfb\x00\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\xa4\x81{^\x00\x00Africa/Dar_es_SalaamUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n" + + "\x00\x00\x00\x00\x00\xf5F\x9cP\xb1\x980\xb2\xf6\x00\x00\x00\xf6\x00\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc4_\x00\x00Africa/JohannesburgUT" + + "\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP4\x8b\xa4 \x95\x00\x00\x00\x95\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\xa4\x81\aa\x00\x00Africa/KigaliUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9c" + + "Px=\xfb\xae\xfb\x00\x00\x00\xfb\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe3a\x00\x00Africa/DjiboutiUT\x05\x00\x03nӧ^ux\v\x00\x01" + + "\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xae\x18\x88\x94\x00\x00\x00\x94\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81'c\x00\x00Afri" + + "ca/FreetownUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\b\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedA\x04d\x00\x00America/UT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n" + + "\x00\x00\x00\x00\x00\xf5F\x9cP(*3\xf3\xf6\x00\x00\x00\xf6\x00\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Fd\x00\x00America/Puerto_RicoUT" + + "\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x03\xcdU\x02\xcc\x02\x00\x00\xcc\x02\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\xa4\x81\x89e\x00\x00America/RecifeUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F" + + "\x9cP\x10\x91Wpd\a\x00\x00d\a\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9dh\x00\x00America/ResoluteUT\x05\x00\x03nӧ^ux\v" + + "\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP*\x95<\xda\\\x02\x00\x00\\\x02\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Kp\x00\x00Am" + + "erica/ManausUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x96-\xbf\x9f\xd0\r\x00\x00" + + "\xd0\r\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xefr\x00\x00America/New_YorkUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00" + + "\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa1\xfc\xb8\xa6d\a\x00\x00d\a\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\t\x81\x00\x00America/Rank" + + "in_InletUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPiyᨖ\x01\x00\x00\x96\x01\x00\x00" + + "\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xbb\x88\x00\x00America/LimaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03" + + "\n\x00\x00\x00\x00\x00\xf5F\x9cP\xcf|3(\x94\x00\x00\x00\x94\x00\x00\x00\x15\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x97\x8a\x00\x00America/St_Barthelem" + + "yUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPr\xcb;\xb3\xca\x01\x00\x00\xca\x01\x00\x00\x15\x00\x18\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\xa4\x81z\x8b\x00\x00America/Santo_DomingoUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02" + + "\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x03:\x80]\xb6\b\x00\x00\xb6\b\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x93\x8d\x00\x00America/DetroitUT\x05" + + "\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xbb\xa4T\xc1\x06\x01\x00\x00\x06\x01\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\xa4\x81\x92\x96\x00\x00America/ParamariboUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00" + + "\x00\xf5F\x9cP\x14_\t\xbd\x01\t\x00\x00\x01\t\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe4\x97\x00\x00America/YakutatUT\x05\x00\x03nӧ^u" + + "x\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc0\xce*\xf4Z\x02\x00\x00Z\x02\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81.\xa1\x00\x00" + + "America/SantaremUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x89S\xb8\xd5" + + "n\a\x00\x00n\a\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81ң\x00\x00America/Punta_ArenasUT\x05\x00\x03nӧ^ux\v\x00\x01" + + "\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xcfV%\x9e|\a\x00\x00|\a\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x8e\xab\x00\x00Amer" + + "ica/ScoresbysundUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP|p&\x14" + + "\xe1\t\x00\x00\xe1\t\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81X\xb3\x00\x00America/SantiagoUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00" + + "\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfe\xd6y\x85\xec\x00\x00\x00\xec\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x83\xbd\x00\x00America/" + + "GuyanaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPENO\xd9P\x01\x00\x00P\x01\x00\x00\x15\x00" + + "\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb7\xbe\x00\x00America/Coral_HarbourUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00" + + "\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe6\xee\xf1\xbft\x02\x00\x00t\x02\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81V\xc0\x00\x00America/Rio_B" + + "rancoUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe6\xee\xf1\xbft\x02\x00\x00t\x02\x00\x00\x12\x00\x18" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x16\xc3\x00\x00America/Porto_AcreUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01" + + "\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x01\x84\xd10J\b\x00\x00J\b\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xd6\xc5\x00\x00America/NipigonUT" + + "\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPI-l\xd2\x1c\t\x00\x00\x1c\t\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\xa4\x81i\xce\x00\x00America/EdmontonUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00" + + "\xf5F\x9cP\xcf|3(\x94\x00\x00\x00\x94\x00\x00\x00\x15\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xcf\xd7\x00\x00America/Port_of_SpainUT\x05\x00\x03" + + "nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP#\x16\x92r\xba\x00\x00\x00\xba\x00\x00\x00\x15\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4" + + "\x81\xb2\xd8\x00\x00America/Lower_PrincesUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00" + + "\x00\x00\xf5F\x9cP\xcf|3(\x94\x00\x00\x00\x94\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xbb\xd9\x00\x00America/St_ThomasUT\x05\x00\x03n\xd3" + + "\xa7^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\n\x85\xb7\x89\x18\x01\x00\x00\x18\x01\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9a" + + "\xda\x00\x00America/GuatemalaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP" + + "\xaa?b\xbe4\x04\x00\x004\x04\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xfd\xdb\x00\x00America/CatamarcaUT\x05\x00\x03nӧ^ux\v\x00" + + "\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xcf|3(\x94\x00\x00\x00\x94\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81|\xe0\x00\x00Ame" + + "rica/AntiguaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP+!\xd6\n@\x02\x00\x00" + + "@\x02\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Y\xe1\x00\x00America/Porto_VelhoUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00" + + "\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb6\xb1\xfb\x104\x04\x00\x004\x04\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe6\xe3\x00\x00America/R" + + "osarioUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf8=\xf2\x1a\xf8\r\x00\x00\xf8\r\x00\x00\x0f\x00" + + "\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81c\xe8\x00\x00America/ChicagoUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e" + + "\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa4\xac\xbaE\xd0\x00\x00\x00\xd0\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa4\xf6\x00\x00America/CrestonUT\x05\x00" + + "\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xd7o̥\xae\x01\x00\x00\xae\x01\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\xa4\x81\xbd\xf7\x00\x00America/ManaguaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9c" + + "P#yȝ\xd2\b\x00\x00\xd2\b\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb4\xf9\x00\x00America/NassauUT\x05\x00\x03nӧ^ux\v\x00\x01\x04" + + "\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe8M\xb5\xdb\xf6\x00\x00\x00\xf6\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xce\x02\x01\x00Ameri" + + "ca/BogotaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPC2\xb5\xff\x0e\x03\x00\x00\x0e\x03\x00" + + "\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\f\x04\x01\x00America/CancunUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01" + + "\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa5\xa5\x94w\xcc\x05\x00\x00\xcc\x05\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81b\a\x01\x00America/Chihuahua" + + "UT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x93l\xbbV\xa4\x05\x00\x00\xa4\x05\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\xa4\x81y\r\x01\x00America/Campo_GrandeUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03" + + "\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe8OD\xf3`\r\x00\x00`\r\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81k\x13\x01\x00America/HalifaxUT\x05\x00\x03" + + "nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPUT\x8d\x8dZ\t\x00\x00Z\t\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4" + + "\x81\x14!\x01\x00America/BoiseUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb3\f" + + "so\xa6\r\x00\x00\xa6\r\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb5*\x01\x00America/MontrealUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5" + + "\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPd\x88\u007f4\x8a\f\x00\x00\x8a\f\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa58\x01\x00Americ" + + "a/Goose_BayUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPM\x16\b*\xa4\x05\x00\x00\xa4" + + "\x05\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81zE\x01\x00America/Sao_PauloUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00" + + "\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf3\x93Ϊ*\x01\x00\x00*\x01\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81iK\x01\x00America/Blan" + + "c-SablonUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa9K%7H\x01\x00\x00H\x01\x00\x00" + + "\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe1L\x01\x00America/PhoenixUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01" + + "\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPENO\xd9P\x01\x00\x00P\x01\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81rN\x01\x00America/AtikokanU" + + "T\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP(x\xa1\xf4\xc6\x00\x00\x00\xc6\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\xa4\x81\fP\x01\x00America/CayenneUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00" + + "\xf5F\x9cPv\x89Z\xa8V\a\x00\x00V\a\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x1bQ\x01\x00America/NuukUT\x05\x00\x03nӧ^ux\v\x00\x01" + + "\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x95\"R\xd4&\t\x00\x00&\t\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb7X\x01\x00Amer" + + "ica/Santa_IsabelUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xad\x8f\x10\x0f" + + "x\x02\x00\x00x\x02\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81+b\x01\x00America/Boa_VistaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01" + + "\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa1\xaah\x81\n\x06\x00\x00\n\x06\x00\x00\x16\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xeed\x01\x00America" + + "/Bahia_BanderasUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedAHk\x01\x00America/Indiana/UT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00" + + "\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPz\x9d\x031\x86\x05\x00\x00\x86\x05\x00\x00\x15\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x92k\x01\x00America/I" + + "ndiana/VevayUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xa6O\x1d\x82\x06\x00\x00" + + "\x82\x06\x00\x00\x1c\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81gq\x01\x00America/Indiana/IndianapolisUT\x05\x00\x03nӧ^u" + + "x\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x1fK\xc3\xd1\xf2\x06\x00\x00\xf2\x06\x00\x00\x17\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81?x\x01\x00" + + "America/Indiana/WinamacUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5" + + "F\x9cP\xdde\xde$\x94\x06\x00\x00\x94\x06\x00\x00\x19\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x82\u007f\x01\x00America/Indiana/Tell_CityUT" + + "\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\a\xcb\xd8\x1ap\a\x00\x00p\a\x00\x00\x1a\x00\x18\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\xa4\x81i\x86\x01\x00America/Indiana/PetersburgUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK" + + "\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPW\x0e\xf7\x10\x9e\x06\x00\x00\x9e\x06\x00\x00\x19\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81-\x8e\x01\x00America/Indiana/" + + "VincennesUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPh։\xbc|\t\x00\x00|\t\x00" + + "\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x1e\x95\x01\x00America/Indiana/KnoxUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14" + + "\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP8\x00o\xf5\xba\x06\x00\x00\xba\x06\x00\x00\x17\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe8\x9e\x01\x00America/Ind" + + "iana/MarengoUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPm\xa6O\x1d\x82\x06\x00\x00" + + "\x82\x06\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf3\xa5\x01\x00America/IndianapolisUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00" + + "\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xcf|3(\x94\x00\x00\x00\x94\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81ì\x01\x00America/" + + "DominicaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedA\xa1\xad\x01\x00America/Argentina/UT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00" + + "PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPi\xa2+\x99\x18\x04\x00\x00\x18\x04\x00\x00\x17\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xed\xad\x01\x00America/Argent" + + "ina/SaltaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x9e4\xa4\x8b4\x04\x00\x004\x04\x00" + + "\x00\x19\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81V\xb2\x01\x00America/Argentina/UshuaiaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5" + + "\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xaa?b\xbe4\x04\x00\x004\x04\x00\x00\x1b\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81ݶ\x01\x00Americ" + + "a/Argentina/CatamarcaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9c" + + "P\xaa?b\xbe4\x04\x00\x004\x04\x00\x00 \x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81f\xbb\x01\x00America/Argentina/ComodRivada" + + "viaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xac\xa8\x1a\x9aB\x04\x00\x00B\x04\x00\x00\x1a\x00\x18\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf4\xbf\x01\x00America/Argentina/San_JuanUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14" + + "\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPGB\xad\x0fN\x04\x00\x00N\x04\x00\x00\x1a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x8a\xc4\x01\x00America/Arg" + + "entina/San_LuisUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPQy\xf3\n4" + + "\x04\x00\x004\x04\x00\x00\x1e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81,\xc9\x01\x00America/Argentina/Rio_GallegosUT\x05\x00\x03" + + "nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf5\"\xa0\xdf\x18\x04\x00\x00\x18\x04\x00\x00\x17\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4" + + "\x81\xb8\xcd\x01\x00America/Argentina/JujuyUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00" + + "\x00\x00\x00\x00\xf5F\x9cPqr%\xd5P\x04\x00\x00P\x04\x00\x00\x19\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81!\xd2\x01\x00America/Argentina/Tucu" + + "manUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\t)<\xb24\x04\x00\x004\x04\x00\x00\x1e\x00\x18\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc4\xd6\x01\x00America/Argentina/Buenos_AiresUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01" + + "\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb6\xb1\xfb\x104\x04\x00\x004\x04\x00\x00\x19\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81P\xdb\x01\x00America" + + "/Argentina/CordobaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa1\xad" + + "\x99\x05B\x04\x00\x00B\x04\x00\x00\x1a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xd7\xdf\x01\x00America/Argentina/La_RiojaUT\x05\x00\x03n" + + "ӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x1a\xdb?\x854\x04\x00\x004\x04\x00\x00\x19\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81" + + "m\xe4\x01\x00America/Argentina/MendozaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n" + + "\x00\x00\x00\x00\x00\xf5F\x9cP\x0e\xacEg\xe8\x00\x00\x00\xe8\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf4\xe8\x01\x00America/La_PazUT\x05\x00\x03n\xd3" + + "\xa7^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPЧ\x00\x94@\x06\x00\x00@\x06\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81$" + + "\xea\x01\x00America/DawsonUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x96\xc2\xf2" + + "\x12R\f\x00\x00R\f\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xac\xf0\x01\x00America/MonctonUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00" + + "\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\"N\xeb\x01n\x05\x00\x00n\x05\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81G\xfd\x01\x00America/" + + "MatamorosUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xcf|3(\x94\x00\x00\x00\x94\x00\x00" + + "\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00\x03\x02\x00America/St_VincentUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00" + + "\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xd2k\xc2\xda\xd4\x03\x00\x00\xd4\x03\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe0\x03\x02\x00America/Regin" + + "aUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa0\xea\xacW\xae\a\x00\x00\xae\a\x00\x00\x13\x00\x18\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\xa4\x81\xfc\a\x02\x00America/YellowknifeUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03" + + "\n\x00\x00\x00\x00\x00\xf5F\x9cPRS\x13\xcfJ\b\x00\x00J\b\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf7\x0f\x02\x00America/Rainy_RiverU" + + "T\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP#\x16\x92r\xba\x00\x00\x00\xba\x00\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\xa4\x81\x8e\x18\x02\x00America/KralendijkUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00" + + "\x00\x00\x00\xf5F\x9cP.m\x983n\x05\x00\x00n\x05\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x94\x19\x02\x00America/MonterreyUT\x05\x00\x03n" + + "ӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf9,\x94G\xe2\x01\x00\x00\xe2\x01\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81" + + "M\x1f\x02\x00America/JamaicaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPA" + + "kx\xeap\t\x00\x00p\t\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81x!\x02\x00America/HavanaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01" + + "\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa9ב\xa5\xfc\x00\x00\x00\xfc\x00\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x810+\x02\x00America" + + "/TegucigalpaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPgt\xddX\xf6\x00\x00\x00" + + "\xf6\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81y,\x02\x00America/GuayaquilUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14" + + "\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb4\xa0\x9aƏ\x05\x00\x00\x8f\x05\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xba-\x02\x00America/Met" + + "lakatlaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPv:D\x98\xf6\x05\x00\x00\xf6\x05\x00\x00\x10" + + "\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x953\x02\x00America/MazatlanUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01" + + "\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe2\xa9(\xfc\xb4\x03\x00\x00\xb4\x03\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xd59\x02\x00America/BelizeUT\x05" + + "\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPh։\xbc|\t\x00\x00|\t\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\xa4\x81\xd1=\x02\x00America/Knox_INUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F" + + "\x9cP\x8a\xa3\xa5\x8a\x88\x05\x00\x00\x88\x05\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x96G\x02\x00America/CuiabaUT\x05\x00\x03nӧ^ux\v\x00\x01" + + "\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa7\xaa/\x17\x8e\x05\x00\x00\x8e\x05\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81fM\x02\x00Amer" + + "ica/MeridaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf5\"\xa0\xdf\x18\x04\x00\x00\x18\x04" + + "\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x03\x00America/Grand_TurkUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01" + + "\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xcf|3(\x94\x00\x00\x00\x94\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\rF\x03\x00America" + + "/VirginUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x99\x16\x9bpC\t\x00\x00C\t\x00\x00\x11" + + "\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe9F\x03\x00America/AnchorageUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK" + + "\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPo\xfc\xba\xb6<\x01\x00\x00<\x01\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81wP\x03\x00America/Costa_Ri" + + "caUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPq\x11\n\x98?\t\x00\x00?\t\x00\x00\f\x00\x18\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\xa4\x81\xffQ\x03\x00America/NomeUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00" + + "\xf5F\x9cP\xcf|3(\x94\x00\x00\x00\x94\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x84[\x03\x00America/GrenadaUT\x05\x00\x03nӧ^ux" + + "\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xd8\xc5\xf4\xe2G\x0e\x00\x00G\x0e\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81a\\\x03\x00A" + + "merica/St_JohnsUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPh\xef\x10-4" + + "\t\x00\x004\t\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf2j\x03\x00America/AtkaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00" + + "\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x19\x94\x8f\xd7\xfc\a\x00\x00\xfc\a\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81lt\x03\x00America/Asunc" + + "ionUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP;\xab\xd2\xe0\xa0\x01\x00\x00\xa0\x01\x00\x00\x12\x00\x18\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb2|\x03\x00America/HermosilloUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e" + + "\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x95\"R\xd4&\t\x00\x00&\t\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9e~\x03\x00America/TijuanaUT\x05\x00" + + "\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xcf|3(\x94\x00\x00\x00\x94\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\xa4\x81\r\x88\x03\x00America/MarigotUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9c" + + "PU\x9fop1\t\x00\x001\t\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xea\x88\x03\x00America/JuneauUT\x05\x00\x03nӧ^ux\v\x00\x01\x04" + + "\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP:[\xd10\xe6\x05\x00\x00\xe6\x05\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81c\x92\x03\x00Ameri" + + "ca/MontevideoUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPv\x89Z\xa8V\a\x00" + + "\x00V\a\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x95\x98\x03\x00America/GodthabUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00" + + "\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xcf|3(\x94\x00\x00\x00\x94\x00\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x814\xa0\x03\x00America/Guad" + + "eloupeUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xberb\x10\xe8\x02\x00\x00\xe8\x02\x00\x00\x0e\x00" + + "\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x14\xa1\x03\x00America/MaceioUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03" + + "\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb2\xde)%.\b\x00\x00.\b\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81D\xa4\x03\x00America/PangnirtungU" + + "T\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xcf|3(\x94\x00\x00\x00\x94\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\xa4\x81\xbf\xac\x03\x00America/St_KittsUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00" + + "\x00\xf5F\x9cP\xe61Ƀ:\x01\x00\x00:\x01\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9d\xad\x03\x00America/BarbadosUT\x05\x00\x03nӧ^" + + "ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf1\x1ak\xd0\xf0\a\x00\x00\xf0\a\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81!\xaf\x03" + + "\x00America/IqaluitUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xaeJM\xcf" + + "\xe2\b\x00\x00\xe2\b\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Z\xb7\x03\x00America/MenomineeUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01" + + "\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x97\xa99\xc2\xe8\x00\x00\x00\xe8\x00\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x87\xc0\x03\x00America" + + "/MartiniqueUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPM\x16R\xd50\x06\x00\x000" + + "\x06\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xbb\xc1\x03\x00America/Mexico_CityUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04" + + "\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPyn\x92m0\x02\x00\x000\x02\x00\x00\x15\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x818\xc8\x03\x00America/Sw" + + "ift_CurrentUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x854\x86\x9d\x82\x06\x00\x00\x82" + + "\x06\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb7\xca\x03\x00America/MiquelonUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00" + + "\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP#\x16\x92r\xba\x00\x00\x00\xba\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x83\xd1\x03\x00America/Curac" + + "aoUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb2\xeb-;\x1a\x04\x00\x00\x1a\x04\x00\x00\x14\x00\x18\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\xa4\x81\x86\xd2\x03\x00America/Dawson_CreekUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02" + + "\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x1a\xdb?\x854\x04\x00\x004\x04\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xee\xd6\x03\x00America/MendozaUT\x05" + + "\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPh\xef\x10-4\t\x00\x004\t\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\xa4\x81k\xdb\x03\x00America/AdakUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP|" + + "m\x8dA\x9a\b\x00\x00\x9a\b\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe5\xe4\x03\x00America/Thunder_BayUT\x05\x00\x03nӧ^ux\v" + + "\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP#\x16\x92r\xba\x00\x00\x00\xba\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xcc\xed\x03\x00Am" + + "erica/ArubaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPdl\xee\xad\xc0\b\x00\x00\xc0" + + "\b\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xcd\xee\x03\x00America/Fort_NelsonUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04" + + "\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPq\xf5\xf3C\x19\t\x00\x00\x19\t\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xda\xf7\x03\x00America/Si" + + "tkaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xcf|3(\x94\x00\x00\x00\x94\x00\x00\x00\x10\x00\x18\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\xa4\x81:\x01\x04\x00America/AnguillaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n" + + "\x00\x00\x00\x00\x00\xf5F\x9cP0Q?\xbf\xba\x02\x00\x00\xba\x02\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x18\x02\x04\x00America/DanmarkshavnU" + + "T\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00" + + "\x00\x10\x00\xedA \x05\x04\x00Antarctica/UT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP" + + "\xde,\xad\f\x8a\x05\x00\x00\x8a\x05\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81e\x05\x04\x00Antarctica/PalmerUT\x05\x00\x03nӧ^ux\v\x00" + + "\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa2\xa45\xb7)\x01\x00\x00)\x01\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81:\v\x04\x00Ant" + + "arctica/DavisUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x91h\x16Ƥ\x00\x00" + + "\x00\xa4\x00\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xad\f\x04\x00Antarctica/RotheraUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00" + + "\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP[\xcbΟ\xa5\x00\x00\x00\xa5\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9d\r\x04\x00Antarctic" + + "a/VostokUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP0\xa4\x84ԥ\x00\x00\x00\xa5\x00\x00\x00" + + "\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x8d\x0e\x04\x00Antarctica/SyowaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK" + + "\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP,(\xa1q\xc2\x00\x00\x00\xc2\x00\x00\x00\x19\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81|\x0f\x04\x00Antarctica/Dumon" + + "tDUrvilleUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP0>8\xb8\x85\t\x00\x00\x85\t\x00" + + "\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x91\x10\x04\x00Antarctica/McMurdoUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00" + + "\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x93\xbc>\a\xf0\x05\x00\x00\xf0\x05\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81b\x1a\x04\x00Antarctica/Ma" + + "cquarieUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP0>8\xb8\x85\t\x00\x00\x85\t\x00\x00\x15" + + "\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa0 \x04\x00Antarctica/South_PoleUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00" + + "\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xba\x9c\x04Z\x8a\x04\x00\x00\x8a\x04\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81t*\x04\x00Antarctica/T" + + "rollUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPYl '\xc7\x00\x00\x00\xc7\x00\x00\x00\x11\x00\x18\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81H/\x04\x00Antarctica/MawsonUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e" + + "\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x8c\xa1\xe8G)\x01\x00\x00)\x01\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Z0\x04\x00Antarctica/CaseyUT\x05" + + "\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10" + + "\x00\xedA\xcd1\x04\x00Arctic/UT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa7\x99\x04[\xb4\b" + + "\x00\x00\xb4\b\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x0e2\x04\x00Arctic/LongyearbyenUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01" + + "\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedA\x0f;\x04\x00Asia/UT" + + "\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP=\x13q\x1aO\x02\x00\x00O\x02\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\xa4\x81N;\x04\x00Asia/DushanbeUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9c" + + "P\xad\xfeuz\xf3\x03\x00\x00\xf3\x03\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe4=\x04\x00Asia/QostanayUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5" + + "\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x88括\x1d\x01\x00\x00\x1d\x01\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x1eB\x04\x00Asia/C" + + "alcuttaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPw:\xb4ե\x00\x00\x00\xa5\x00\x00\x00\v" + + "\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x82C\x04\x00Asia/UrumqiUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00" + + "\x00\x00\x00\x00\xf5F\x9cP\xd2\xc25G{\x01\x00\x00{\x01\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81lD\x04\x00Asia/KarachiUT\x05\x00\x03nӧ^u" + + "x\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x9c\xd9\xefd\xf7\x04\x00\x00\xf7\x04\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81-F\x04\x00" + + "Asia/KhandygaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xbc?y\x93\xcb\x00\x00" + + "\x00\xcb\x00\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81kK\x04\x00Asia/ThimbuUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK" + + "\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xbc?y\x93\xcb\x00\x00\x00\xcb\x00\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81{L\x04\x00Asia/ThimphuUT\x05\x00" + + "\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x9cAu*\xb8\x04\x00\x00\xb8\x04\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\xa4\x81\x8cM\x04\x00Asia/VladivostokUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F" + + "\x9cP\x90\xc4\xe3*\xc7\x00\x00\x00\xc7\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x8eR\x04\x00Asia/VientianeUT\x05\x00\x03nӧ^ux\v\x00\x01" + + "\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPy\x84\xe1i1\x02\x00\x001\x02\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9dS\x04\x00Asia" + + "/ShanghaiUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xbd*B/{\x03\x00\x00{\x03\x00" + + "\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x15V\x04\x00Asia/Ulan_BatorUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK" + + "\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPs\x92<\x8f\xa5\x00\x00\x00\xa5\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xd9Y\x04\x00Asia/AdenUT\x05\x00\x03n\xd3" + + "\xa7^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x8e\"\x05\x94\xa5\x00\x00\x00\xa5\x00\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc1" + + "Z\x04\x00Asia/MuscatUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xd7\x1e>W\xf6\b" + + "\x00\x00\xf6\b\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xab[\x04\x00Asia/DamascusUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00" + + "\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfe\x1c\xdd\x02\xf0\b\x00\x00\xf0\b\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe8d\x04\x00Asia/Jerusale" + + "mUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe3\x97\x04\xe9\xcb\x00\x00\x00\xcb\x00\x00\x00\v\x00\x18\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\xa4\x81 n\x04\x00Asia/BruneiUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F" + + "\x9cP\xbd*B/{\x03\x00\x00{\x03\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x810o\x04\x00Asia/UlaanbaatarUT\x05\x00\x03nӧ^ux\v" + + "\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa0Qf\xd1=\a\x00\x00=\a\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf5r\x04\x00As" + + "ia/AmmanUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x92\xa4\x05+\xe3\x01\x00\x00\xe3\x01\x00\x00" + + "\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81vz\x04\x00Asia/KuchingUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03" + + "\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfe\x1c\xdd\x02\xf0\b\x00\x00\xf0\b\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9f|\x04\x00Asia/Tel_AvivUT\x05\x00\x03n\xd3" + + "\xa7^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe3\x16\xfb\xddi\x02\x00\x00i\x02\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xd6" + + "\x85\x04\x00Asia/SeoulUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xd3Y\xee\x16\xdf\x03\x00" + + "\x00\xdf\x03\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x83\x88\x04\x00Asia/AtyrauUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK" + + "\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xd3\"6\x9f\xed\x00\x00\x00\xed\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa7\x8c\x04\x00Asia/PyongyangUT" + + "\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x0f֏\x10{\x03\x00\x00{\x03\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\xa4\x81܍\x04\x00Asia/HovdUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xec\x80*" + + "\xa6(\t\x00\x00(\t\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9a\x91\x04\x00Asia/HebronUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00" + + "\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPs\x92<\x8f\xa5\x00\x00\x00\xa5\x00\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\a\x9b\x04\x00Asia/KuwaitU" + + "T\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb5\xc1\xd0\f\xc5\x04\x00\x00\xc5\x04\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\xa4\x81\xf1\x9b\x04\x00Asia/TomskUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPl" + + "\xb2\xad\xbbH\x01\x00\x00H\x01\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xfa\xa0\x04\x00Asia/ManilaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04" + + "\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPuX\x12q\xc5\x04\x00\x00\xc5\x04\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x87\xa2\x04\x00Asia/Chita" + + "UT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP)\xfa\xf8j\xd4\x00\x00\x00\xd4\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\xa4\x81\x90\xa7\x04\x00Asia/KatmanduUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5" + + "F\x9cP}\x9e\xc1\xa4\f\t\x00\x00\f\t\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xab\xa8\x04\x00Asia/GazaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00" + + "\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfd\xfc)\xc9A\x02\x00\x00A\x02\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xfa\xb1\x04\x00Asia/Sam" + + "arkandUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc7\x1a\x03B\xf9\x02\x00\x00\xf9\x02\x00\x00\v\x00" + + "\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x83\xb4\x04\x00Asia/TaipeiUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00" + + "\x00\x00\x00\xf5F\x9cP\xee\xbf\xd8\xecO\x02\x00\x00O\x02\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc1\xb7\x04\x00Asia/TashkentUT\x05\x00\x03nӧ^u" + + "x\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe5.\xe4\xfc\xdb\x04\x00\x00\xdb\x04\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81W\xba\x04\x00" + + "Asia/YekaterinburgUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP9\xf3" + + "\x91\x9b\xcb\x04\x00\x00\xcb\x04\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81~\xbf\x04\x00Asia/MacauUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00" + + "\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\n:\xf3_\x01\x04\x00\x00\x01\x04\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x8d\xc4\x04\x00Asia/Qyzylor" + + "daUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP9\xf3\x91\x9b\xcb\x04\x00\x00\xcb\x04\x00\x00\n\x00\x18\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\xa4\x81\xd6\xc8\x04\x00Asia/MacaoUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F" + + "\x9cP\fH\xe6\r5\x01\x00\x005\x01\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe5\xcd\x04\x00Asia/TokyoUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00" + + "\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc9 \xb3\x05\xcb\x04\x00\x00\xcb\x04\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81^\xcf\x04\x00Asia/Bak" + + "uUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP}\x94iH\xc5\x04\x00\x00\xc5\x04\x00\x00\f\x00\x18\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\xa4\x81l\xd4\x04\x00Asia/BarnaulUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5" + + "F\x9cP\xc2\xf47\xbd\x9b\a\x00\x00\x9b\a\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81w\xd9\x04\x00Asia/IstanbulUT\x05\x00\x03nӧ^ux\v\x00\x01" + + "\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPj\xcc\xd7\xe7\xdb\x04\x00\x00\xdb\x04\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Y\xe1\x04\x00Asia" + + "/IrkutskUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP@+\xbfW\xc7\x00\x00\x00\xc7\x00\x00\x00" + + "\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81z\xe6\x04\x00Asia/QatarUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00" + + "\x00\x00\x00\x00\xf5F\x9cP@+\xbfW\xc7\x00\x00\x00\xc7\x00\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x85\xe7\x04\x00Asia/BahrainUT\x05\x00\x03nӧ^u" + + "x\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x1d`u\xd5\f\x01\x00\x00\f\x01\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x92\xe8\x04\x00" + + "Asia/YangonUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPz\xfb\xb5\x11\u007f\x04\x00\x00\u007f" + + "\x04\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe3\xe9\x04\x00Asia/YerevanUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01" + + "\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc4/ձ\xe5\x03\x00\x00\xe5\x03\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa8\xee\x04\x00Asia/AlmatyUT\x05\x00\x03n" + + "ӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPp\a\x00Etc/GMT+4UT\x05\x00\x03n" + + "ӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x10\x8b\x9a\xb9t\x00\x00\x00t\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81" + + "\x03?\a\x00Etc/GMT+3UT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xd8\xf3g\xcbu\x00\x00" + + "\x00u\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xba?\a\x00Etc/GMT-9UT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02" + + "\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa64^\xabr\x00\x00\x00r\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81r@\a\x00Etc/GMT-0UT\x05\x00\x03nӧ^" + + "ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xad8\xee\xe8u\x00\x00\x00u\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81'A\a" + + "\x00Etc/GMT-7UT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPt3\xab\xe656\n\x00\x006\n\x00\x00\r\x00\x18\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\xa4\x81E,\b\x00Europe/MadridUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00" + + "\x00\xf5F\x9cP\xcd\xc6JÀ\a\x00\x00\x80\a\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc26\b\x00Europe/PodgoricaUT\x05\x00\x03nӧ^" + + "ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPy\xcc\x01\x9du\a\x00\x00u\a\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x8c>\b" + + "\x00Europe/BusingenUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfcc!\x8e" + + "Q\n\x00\x00Q\n\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81JF\b\x00Europe/VaticanUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04" + + "\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa5\xa2\x06\xaf@\x0e\x00\x00@\x0e\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe3P\b\x00Europe/Bel" + + "fastUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe59\xab\xf0\xfd\b\x00\x00\xfd\b\x00\x00\x11\x00\x18\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81k_\b\x00Europe/BratislavaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e" + + "\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPp\xbc&\f(\b\x00\x00(\b\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb3h\b\x00Europe/KievUT\x05\x00\x03nӧ" + + "^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc5^+J\xd5\x05\x00\x00\xd5\x05\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81 q" + + "\b\x00Europe/KaliningradUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP" + + "\xb6\x92}\xbe:\b\x00\x00:\b\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Aw\b\x00Europe/ZaporozhyeUT\x05\x00\x03nӧ^ux\v\x00" + + "\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x8btѪ\x98\b\x00\x00\x98\b\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc6\u007f\b\x00Eur" + + "ope/ViennaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x9d\x8f\xfd_@\t\x00\x00@\t" + + "\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa5\x88\b\x00Europe/BudapestUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00P" + + "K\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xec\xe5\x98\xc7r\b\x00\x00r\b\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81.\x92\b\x00Europe/VilniusU" + + "T\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x97\xf3U}\x80\v\x00\x00\x80\v\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\xa4\x81\xe8\x9a\b\x00Europe/MonacoUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F" + + "\x9cP\xa7\x99\x04[\xb4\b\x00\x00\xb4\b\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xaf\xa6\b\x00Europe/OsloUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01" + + "\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPokI-\x8d\x04\x00\x00\x8d\x04\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa8\xaf\b\x00Europe/" + + "AstrakhanUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPSSc.\xad\x05\x00\x00\xad\x05\x00" + + "\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\u007f\xb4\b\x00Europe/SimferopolUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00" + + "PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPi\xd8V\xbf\x8d\x04\x00\x00\x8d\x04\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81w\xba\b\x00Europe/Volgogr" + + "adUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa5\xa2\x06\xaf@\x0e\x00\x00@\x0e\x00\x00\x12\x00\x18\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\xa4\x81N\xbf\b\x00Europe/Isle_of_ManUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03" + + "\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa5\xa2\x06\xaf@\x0e\x00\x00@\x0e\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xda\xcd\b\x00Europe/LondonUT\x05\x00\x03n\xd3" + + "\xa7^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x94\xad\x88\x98\x96\b\x00\x00\x96\b\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81a" + + "\xdc\b\x00Europe/RigaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\u07b9\x9bQ\xce\x06" + + "\x00\x00\xce\x06\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81<\xe5\b\x00Europe/AndorraUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00" + + "\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe59\xab\xf0\xfd\b\x00\x00\xfd\b\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81R\xec\b\x00Europe/Pragu" + + "eUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP4\x91\x960\xfa\b\x00\x00\xfa\b\x00\x00\r\x00\x18\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\xa4\x81\x96\xf5\b\x00Europe/BerlinUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00" + + "\xf5F\x9cP[}\x0epd\b\x00\x00d\b\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xd7\xfe\b\x00Europe/TallinnUT\x05\x00\x03nӧ^ux\v" + + "\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfcc!\x8eQ\n\x00\x00Q\n\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x83\a\t\x00Eu" + + "rope/RomeUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP_4\xf8\xf2<\n\x00\x00<\n\x00" + + "\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x19\x12\t\x00Europe/MaltaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e" + + "\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xcd\xc6JÀ\a\x00\x00\x80\a\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9b\x1c\t\x00Europe/ZagrebUT\x05\x00\x03n" + + "ӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb6\xfd\xfb\xb4^\v\x00\x00^\v\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81" + + "b$\t\x00Europe/AmsterdamUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP" + + "\x83\xd5\x04\xbb\xd2\a\x00\x00\xd2\a\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\n0\t\x00Europe/NicosiaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5" + + "\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xff\xba\xee&\x88\b\x00\x00\x88\b\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81$8\t\x00Europe" + + "/BucharestUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc4NW\"Y\b\x00\x00Y\b" + + "\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf6@\t\x00Europe/CopenhagenUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00" + + "\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPe\x8d\x0fgV\t\x00\x00V\t\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9aI\t\x00Europe/Chisin" + + "auUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf9\xe6\xa9\xc7l\a\x00\x00l\a\x00\x00\x10\x00\x18\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\xa4\x819S\t\x00Europe/MariehamnUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00" + + "\x00\x00\x00\x00\xf5F\x9cPvȞN\x1d\b\x00\x00\x1d\b\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xefZ\t\x00Europe/SofiaUT\x05\x00\x03nӧ^u" + + "x\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPRg\x93\xa8\xd6\b\x00\x00\xd6\b\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Rc\t\x00" + + "Europe/AthensUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPr\xe7\x92\x17u\a\x00" + + "\x00u\a\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81ol\t\x00Europe/StockholmUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14" + + "\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x98_{t\xbf\x04\x00\x00\xbf\x04\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81.t\t\x00Europe/Sama" + + "raUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPaت\xdcu\v\x00\x00u\v\x00\x00\x0f\x00\x18\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\xa4\x814y\t\x00Europe/BrusselsUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00" + + "\x00\x00\x00\xf5F\x9cP\xa5\xb8\xb6C^\n\x00\x00^\n\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf2\x84\t\x00Europe/WarsawUT\x05\x00\x03nӧ^u" + + "x\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe9\x10\x19\xb7t\x00\x00\x00t\x00\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x97\x8f\t\x00" + + "FactoryUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa5\xa2\x06\xaf@\x0e\x00\x00@\x0e\x00\x00\x02" + + "\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81L\x90\t\x00GBUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa5" + + "\xa2\x06\xaf@\x0e\x00\x00@\x0e\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Ȟ\t\x00GB-EireUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00" + + "PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa64^\xabr\x00\x00\x00r\x00\x00\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81I\xad\t\x00GMTUT\x05\x00\x03nӧ^ux" + + "\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa64^\xabr\x00\x00\x00r\x00\x00\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf8\xad\t\x00G" + + "MT+0UT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa64^\xabr\x00\x00\x00r\x00\x00\x00\x05\x00\x18\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa9\xae\t\x00GMT-0UT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa6" + + "4^\xabr\x00\x00\x00r\x00\x00\x00\x04\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Z\xaf\t\x00GMT0UT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01" + + "\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa64^\xabr\x00\x00\x00r\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\n\xb0\t\x00GreenwichUT\x05\x00\x03nӧ" + + "^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x91\x12\x12Cs\x00\x00\x00s\x00\x00\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xbf\xb0" + + "\t\x00HSTUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf5Dk\x8d\xb3\x04\x00\x00\xb3\x04\x00\x00\b\x00\x18" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81o\xb1\t\x00HongkongUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5" + + "F\x9cP-\x84\xb1)\x8a\x04\x00\x00\x8a\x04\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81d\xb6\t\x00IcelandUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04" + + "\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedA/\xbb\t\x00Indian/UT\x05" + + "\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPE\xa8\xf0\xf8\xf1\x00\x00\x00\xf1\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\xa4\x81p\xbb\t\x00Indian/MauritiusUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5" + + "F\x9cPvQҸ\xc7\x00\x00\x00\xc7\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xab\xbc\t\x00Indian/ChagosUT\x05\x00\x03nӧ^ux\v\x00\x01" + + "\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPx=\xfb\xae\xfb\x00\x00\x00\xfb\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb9\xbd\t\x00Indi" + + "an/MayotteUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP,\x14Ქ\x00\x00\x00\xa5\x00" + + "\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xfc\xbe\t\x00Indian/ChristmasUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00" + + "PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x93&\xf6\xb6\xae\x00\x00\x00\xae\x00\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xeb\xbf\t\x00Indian/CocosUT" + + "\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPi\xf9Q\xd5\xc7\x00\x00\x00\xc7\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\xa4\x81\xdf\xc0\t\x00Indian/MaldivesUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5" + + "F\x9cPx=\xfb\xae\xfb\x00\x00\x00\xfb\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xef\xc1\t\x00Indian/ComoroUT\x05\x00\x03nӧ^ux\v\x00\x01" + + "\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x1c\xb3\x02H\xa5\x00\x00\x00\xa5\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x811\xc3\t\x00Indi" + + "an/ReunionUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP4e\x10\x18\xa5\x00\x00\x00\xa5\x00" + + "\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x1e\xc4\t\x00Indian/MaheUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e" + + "\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa7\xd1X\x9a\xa5\x00\x00\x00\xa5\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\b\xc5\t\x00Indian/KerguelenUT\x05" + + "\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPx=\xfb\xae\xfb\x00\x00\x00\xfb\x00\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\xa4\x81\xf7\xc5\t\x00Indian/AntananarivoUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00" + + "\x00\x00\xf5F\x9cP\x93G\xdd9\x16\n\x00\x00\x16\n\x00\x00\x04\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81?\xc7\t\x00IranUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04" + + "\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfe\x1c\xdd\x02\xf0\b\x00\x00\xf0\b\x00\x00\x06\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x93\xd1\t\x00IsraelUT\x05\x00" + + "\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf9,\x94G\xe2\x01\x00\x00\xe2\x01\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\xa4\x81\xc3\xda\t\x00JamaicaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\fH\xe6\r5\x01\x00" + + "\x005\x01\x00\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe6\xdc\t\x00JapanUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00" + + "\x00\x00\x00\x00\xf5F\x9cP\x03|\x89\xf2<\x01\x00\x00<\x01\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Z\xde\t\x00KwajaleinUT\x05\x00\x03nӧ^ux\v\x00" + + "\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc2ɵ,q\x02\x00\x00q\x02\x00\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xd9\xdf\t\x00Lib" + + "yaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf5\xd6:\xad.\b\x00\x00.\b\x00\x00\x03\x00\x18\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\xa4\x81\x89\xe2\t\x00METUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP~#;\xf4r" + + "\x00\x00\x00r\x00\x00\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf4\xea\t\x00MSTUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00" + + "\x00\x00\x00\x00\xf5F\x9cPw\x1c\x17t\x06\t\x00\x00\x06\t\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa3\xeb\t\x00MST7MDTUT\x05\x00\x03nӧ^ux\v\x00\x01\x04" + + "\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedA\xea\xf4\t\x00Mexic" + + "o/UT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x95\"R\xd4&\t\x00\x00&\t\x00\x00\x10\x00\x18\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\xa4\x81+\xf5\t\x00Mexico/BajaNorteUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00" + + "\x00\x00\x00\x00\xf5F\x9cPM\x16R\xd50\x06\x00\x000\x06\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9b\xfe\t\x00Mexico/GeneralUT\x05\x00\x03nӧ" + + "^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPv:D\x98\xf6\x05\x00\x00\xf6\x05\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x13\x05" + + "\n\x00Mexico/BajaSurUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP0>8\xb8" + + "\x85\t\x00\x00\x85\t\x00\x00\x02\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Q\v\n\x00NZUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00" + + "\x00\x00\x00\x00\xf5F\x9cP{\x9d0U\x14\b\x00\x00\x14\b\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x12\x15\n\x00NZ-CHATUT\x05\x00\x03nӧ^ux\v\x00\x01\x04" + + "\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc41\xb4\x85\x8c\t\x00\x00\x8c\t\x00\x00\x06\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81g\x1d\n\x00Navaj" + + "oUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPy\x84\xe1i1\x02\x00\x001\x02\x00\x00\x03\x00\x18\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\xa4\x813'\n\x00PRCUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb0\xf39\xa3\x06\t" + + "\x00\x00\x06\t\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa1)\n\x00PST8PDTUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e" + + "\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedA\xe82\n\x00Pacific/UT\x05\x00\x03nӧ^ux" + + "\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP`K\x059\xba\x00\x00\x00\xba\x00\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81*3\n\x00P" + + "acific/Port_MoresbyUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPN" + + "\xaexD\r\x01\x00\x00\r\x01\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x8124\n\x00Pacific/ChuukUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00" + + "\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x97+τ\xb9\b\x00\x00\xb9\b\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x865\n\x00Pacific/" + + "EasterUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x03|\x89\xf2<\x01\x00\x00<\x01\x00\x00\x11\x00" + + "\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x87>\n\x00Pacific/KwajaleinUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01" + + "\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa2\xee;+t\x01\x00\x00t\x01\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x0e@\n\x00Pacific/Tongatapu" + + "UT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPN\xaexD\r\x01\x00\x00\r\x01\x00\x00\v\x00\x18\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\xa4\x81\xcdA\n\x00Pacific/YapUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9c" + + "P~\x9eԨ\xa6\x00\x00\x00\xa6\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x1fC\n\x00Pacific/WallisUT\x05\x00\x03nӧ^ux\v\x00\x01\x04" + + "\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP:\f\xd7WI\x04\x00\x00I\x04\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\rD\n\x00Pacif" + + "ic/ApiaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xddnO\np\x03\x00\x00p\x03\x00\x00\x0f" + + "\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9cH\n\x00Pacific/NorfolkUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02" + + "\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x8b}\x1f-\xd2\x01\x00\x00\xd2\x01\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81UL\n\x00Pacific/EfateUT\x05\x00\x03" + + "nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPg\xf5\x05\xa35\x04\x00\x005\x04\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4" + + "\x81nN\n\x00Pacific/FijiUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xe0\x17\xe2" + + "\xba\xa6\x00\x00\x00\xa6\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe9R\n\x00Pacific/FunafutiUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01" + + "\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP(\xa1_\xa3\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xd9S\n\x00Pacific" + + "/PalauUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x98\xd4\xe8V\xee\x01\x00\x00\xee\x01\x00\x00\f\x00" + + "\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xd4T\n\x00Pacific/GuamUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00" + + "\x00\x00\x00\x00\xf5F\x9cP\x98\xd4\xe8V\xee\x01\x00\x00\xee\x01\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\bW\n\x00Pacific/SaipanUT\x05\x00\x03nӧ" + + "^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x93dt\x0e_\x01\x00\x00_\x01\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81>Y" + + "\n\x00Pacific/KosraeUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP&QJ\xb4" + + "\xf1\x00\x00\x00\xf1\x00\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe5Z\n\x00Pacific/NiueUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00" + + "\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPV\xa7\x1f\xd4/\x01\x00\x00/\x01\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x1c\\\n\x00Pacific/Pona" + + "peUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x01\xc1\xe8\x00\xa6\x00\x00\x00\xa6\x00\x00\x00\f\x00\x18\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\xa4\x81\x93]\n\x00Pacific/WakeUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00" + + "\xf5F\x9cP\xc7s\xd0 \xee\x00\x00\x00\xee\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\u007f^\n\x00Pacific/GalapagosUT\x05\x00\x03nӧ^" + + "ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPָ|\xb0I\x01\x00\x00I\x01\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb8_\n" + + "\x00Pacific/JohnstonUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPy|\x8d" + + "ܯ\x00\x00\x00\xaf\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Ka\n\x00Pacific/MidwayUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00" + + "\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPZV\x1d\xe0\xfc\x00\x00\x00\xfc\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Bb\n\x00Pacific/N" + + "auruUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP8\xb8\x85\t\x00\x00\x85\t\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\xa4\x81\xd5l\n\x00Pacific/AucklandUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00" + + "\xf5F\x9cPS\x91O\xa50\x01\x00\x000\x01\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa4v\n\x00Pacific/NoumeaUT\x05\x00\x03nӧ^ux\v" + + "\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc8\x1ar\x86\xc8\x00\x00\x00\xc8\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x1cx\n\x00Pa" + + "cific/FakaofoUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\t\xd07\"\xa5\x00\x00" + + "\x00\xa5\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81-y\n\x00Pacific/TahitiUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00" + + "\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb6\x1c\xb3\x9e\xa4\x00\x00\x00\xa4\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x1az\n\x00Pacific/Gambi" + + "erUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc0YK\x026\x01\x00\x006\x01\x00\x00\x0e\x00\x18\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\xa4\x81\a{\n\x00Pacific/MajuroUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00" + + "\x00\x00\xf5F\x9cPָ|\xb0I\x01\x00\x00I\x01\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x85|\n\x00Pacific/HonoluluUT\x05\x00\x03nӧ" + + "^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPV\xa7\x1f\xd4/\x01\x00\x00/\x01\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x18~" + + "\n\x00Pacific/PohnpeiUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPy|\x8d" + + "ܯ\x00\x00\x00\xaf\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x90\u007f\n\x00Pacific/Pago_PagoUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5" + + "\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPN\xaexD\r\x01\x00\x00\r\x01\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x8a\x80\n\x00Pacifi" + + "c/TrukUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xb9\xfc\xba\xcd\xca\x00\x00\x00\xca\x00\x00\x00\x10\x00" + + "\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81݁\n\x00Pacific/PitcairnUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02" + + "\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPʣ\xc1\x9d\xad\x00\x00\x00\xad\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf1\x82\n\x00Pacific/MarquesasU" + + "T\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP!\xce\xc3\xf8\f\x01\x00\x00\f\x01\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\xa4\x81\xe9\x83\n\x00Pacific/BougainvilleUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n" + + "\x00\x00\x00\x00\x00\xf5F\x9cP\xa4\xdbp$\xa6\x00\x00\x00\xa6\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81C\x85\n\x00Pacific/TarawaUT\x05\x00\x03n\xd3" + + "\xa7^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x04>\xe0gA\x02\x00\x00A\x02\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x811" + + "\x86\n\x00Pacific/RarotongaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP" + + "y|\x8dܯ\x00\x00\x00\xaf\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xbd\x88\n\x00Pacific/SamoaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01" + + "\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x83kȗ\xee\x00\x00\x00\xee\x00\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb3\x89\n\x00Pacific" + + "/KiritimatiUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x0f\xbb\x9eK\xea\x00\x00\x00\xea" + + "\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xed\x8a\n\x00Pacific/EnderburyUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00" + + "\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa5\xb8\xb6C^\n\x00\x00^\n\x00\x00\x06\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\"\x8c\n\x00PolandUT\x05\x00\x03n" + + "ӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf2J꿍\r\x00\x00\x8d\r\x00\x00\b\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81" + + "\xc0\x96\n\x00PortugalUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc7\x1a\x03B\xf9\x02\x00\x00" + + "\xf9\x02\x00\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x8f\xa4\n\x00ROCUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00" + + "\x00\xf5F\x9cP\xe3\x16\xfb\xddi\x02\x00\x00i\x02\x00\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81ŧ\n\x00ROKUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00" + + "\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\b\x01\xc8*\u007f\x01\x00\x00\u007f\x01\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81k\xaa\n\x00SingaporeUT\x05" + + "\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc2\xf47\xbd\x9b\a\x00\x00\x9b\a\x00\x00\x06\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\xa4\x81-\xac\n\x00TurkeyUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfaj.6r\x00\x00" + + "\x00r\x00\x00\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\b\xb4\n\x00UCTUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00" + + "\x00\x00\xf5F\x9cP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedA\xb7\xb4\n\x00US/UT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14" + + "\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x99\x16\x9bpC\t\x00\x00C\t\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf4\xb4\n\x00US/AlaskaUT" + + "\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPʇ(-\x14\v\x00\x00\x14\v\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\xa4\x81z\xbe\n\x00US/PacificUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x96-" + + "\xbf\x9f\xd0\r\x00\x00\xd0\r\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xd2\xc9\n\x00US/EasternUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00" + + "\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x03:\x80]\xb6\b\x00\x00\xb6\b\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe6\xd7\n\x00US/MichiganU" + + "T\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xa9K%7H\x01\x00\x00H\x01\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\xa4\x81\xe1\xe0\n\x00US/ArizonaUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPh" + + "։\xbc|\t\x00\x00|\t\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81m\xe2\n\x00US/Indiana-StarkeUT\x05\x00\x03nӧ^ux\v\x00\x01" + + "\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPh\xef\x10-4\t\x00\x004\t\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x814\xec\n\x00US/A" + + "leutianUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPָ|\xb0I\x01\x00\x00I\x01\x00\x00\t" + + "\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xad\xf5\n\x00US/HawaiiUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00" + + "\x00\x00\xf5F\x9cPm\xa6O\x1d\x82\x06\x00\x00\x82\x06\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x819\xf7\n\x00US/East-IndianaUT\x05\x00\x03nӧ^" + + "ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xf8=\xf2\x1a\xf8\r\x00\x00\xf8\r\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x04\xfe\n" + + "\x00US/CentralUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xc41\xb4\x85\x8c\t\x00\x00\x8c" + + "\t\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81@\f\v\x00US/MountainUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02" + + "\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cPy|\x8dܯ\x00\x00\x00\xaf\x00\x00\x00\b\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x11\x16\v\x00US/SamoaUT\x05\x00\x03nӧ^u" + + "x\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfaj.6r\x00\x00\x00r\x00\x00\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x02\x17\v\x00" + + "UTCUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfaj.6r\x00\x00\x00r\x00\x00\x00\t\x00\x18\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb1\x17\v\x00UniversalUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F" + + "\x9cPc\xb1\xa1\x88\xff\x05\x00\x00\xff\x05\x00\x00\x04\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81f\x18\v\x00W-SUUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00" + + "PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\x82\x13\x83dq\a\x00\x00q\a\x00\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa3\x1e\v\x00WETUT\x05\x00\x03nӧ^ux" + + "\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\xf5F\x9cP\xfaj.6r\x00\x00\x00r\x00\x00\x00\x04\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Q&\v\x00Z" + + "uluUT\x05\x00\x03nӧ^ux\v\x00\x01\x04\xf5\x01\x00\x00\x04\x14\x00\x00\x00PK\x05\x06\x00\x00\x00\x00f\x02f\x02\x96\xc9\x00\x00\x01'\v\x00\x00\x00" diff --git a/libgo/go/time/tzdata_test.go b/libgo/go/time/tzdata_test.go new file mode 100644 index 00000000000..eb6d6c98a86 --- /dev/null +++ b/libgo/go/time/tzdata_test.go @@ -0,0 +1,99 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package time_test + +import ( + "reflect" + "testing" + "time" + _ "time/tzdata" +) + +var zones = []string{ + "Asia/Jerusalem", + "America/Los_Angeles", +} + +func TestEmbeddedTZData(t *testing.T) { + time.ForceZipFileForTesting(true) + defer time.ForceZipFileForTesting(false) + + for _, zone := range zones { + ref, err := time.LoadLocation(zone) + if err != nil { + t.Errorf("LoadLocation(%q): %v", zone, err) + continue + } + + embedded, err := time.LoadFromEmbeddedTZData(zone) + if err != nil { + t.Errorf("LoadFromEmbeddedTZData(%q): %v", zone, err) + continue + } + sample, err := time.LoadLocationFromTZData(zone, []byte(embedded)) + if err != nil { + t.Errorf("LoadLocationFromTZData failed for %q: %v", zone, err) + continue + } + + // Compare the name and zone fields of ref and sample. + // The tx field changes faster as tzdata is updated. + // The cache fields are expected to differ. + v1 := reflect.ValueOf(ref).Elem() + v2 := reflect.ValueOf(sample).Elem() + typ := v1.Type() + nf := typ.NumField() + found := 0 + for i := 0; i < nf; i++ { + ft := typ.Field(i) + if ft.Name != "name" && ft.Name != "zone" { + continue + } + found++ + if !equal(t, v1.Field(i), v2.Field(i)) { + t.Errorf("zone %s: system and embedded tzdata field %s differs", zone, ft.Name) + } + } + if found != 2 { + t.Errorf("test must be updated for change to time.Location struct") + } + } +} + +// equal is a small version of reflect.DeepEqual that we use to +// compare the values of zoneinfo unexported fields. +func equal(t *testing.T, f1, f2 reflect.Value) bool { + switch f1.Type().Kind() { + case reflect.Slice: + if f1.Len() != f2.Len() { + return false + } + for i := 0; i < f1.Len(); i++ { + if !equal(t, f1.Index(i), f2.Index(i)) { + return false + } + } + return true + case reflect.Struct: + nf := f1.Type().NumField() + for i := 0; i < nf; i++ { + if !equal(t, f1.Field(i), f2.Field(i)) { + return false + } + } + return true + case reflect.String: + return f1.String() == f2.String() + case reflect.Bool: + return f1.Bool() == f2.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return f1.Int() == f2.Int() + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return f1.Uint() == f2.Uint() + default: + t.Errorf("test internal error: unsupported kind %v", f1.Type().Kind()) + return true + } +} diff --git a/libgo/go/time/zoneinfo.go b/libgo/go/time/zoneinfo.go index 558803f24ed..c3662297c7d 100644 --- a/libgo/go/time/zoneinfo.go +++ b/libgo/go/time/zoneinfo.go @@ -21,6 +21,13 @@ type Location struct { zone []zone tx []zoneTrans + // The tzdata information can be followed by a string that describes + // how to handle DST transitions not recorded in zoneTrans. + // The format is the TZ environment variable without a colon; see + // https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html. + // Example string, for America/Los_Angeles: PST8PDT,M3.2.0,M11.1.0 + extend string + // Most lookups will be for the current time. // To avoid the binary search through tx, keep a // static one-element cache that gives the correct @@ -167,6 +174,15 @@ func (l *Location) lookup(sec int64) (name string, offset int, start, end int64) offset = zone.offset start = tx[lo].when // end = maintained during the search + + // If we're at the end of the known zone transitions, + // try the extend string. + if lo == len(tx)-1 && l.extend != "" { + if ename, eoffset, estart, eend, ok := tzset(l.extend, end, sec); ok { + return ename, eoffset, estart, eend + } + } + return } @@ -222,6 +238,338 @@ func (l *Location) firstZoneUsed() bool { return false } +// tzset takes a timezone string like the one found in the TZ environment +// variable, the end of the last time zone transition expressed as seconds +// since January 1, 1970 00:00:00 UTC, and a time expressed the same way. +// We call this a tzset string since in C the function tzset reads TZ. +// The return values are as for lookup, plus ok which reports whether the +// parse succeeded. +func tzset(s string, initEnd, sec int64) (name string, offset int, start, end int64, ok bool) { + var ( + stdName, dstName string + stdOffset, dstOffset int + ) + + stdName, s, ok = tzsetName(s) + if ok { + stdOffset, s, ok = tzsetOffset(s) + } + if !ok { + return "", 0, 0, 0, false + } + + // The numbers in the tzset string are added to local time to get UTC, + // but our offsets are added to UTC to get local time, + // so we negate the number we see here. + stdOffset = -stdOffset + + if len(s) == 0 || s[0] == ',' { + // No daylight savings time. + return stdName, stdOffset, initEnd, omega, true + } + + dstName, s, ok = tzsetName(s) + if ok { + if len(s) == 0 || s[0] == ',' { + dstOffset = stdOffset + secondsPerHour + } else { + dstOffset, s, ok = tzsetOffset(s) + dstOffset = -dstOffset // as with stdOffset, above + } + } + if !ok { + return "", 0, 0, 0, false + } + + if len(s) == 0 { + // Default DST rules per tzcode. + s = ",M3.2.0,M11.1.0" + } + // The TZ definition does not mention ';' here but tzcode accepts it. + if s[0] != ',' && s[0] != ';' { + return "", 0, 0, 0, false + } + s = s[1:] + + var startRule, endRule rule + startRule, s, ok = tzsetRule(s) + if !ok || len(s) == 0 || s[0] != ',' { + return "", 0, 0, 0, false + } + s = s[1:] + endRule, s, ok = tzsetRule(s) + if !ok || len(s) > 0 { + return "", 0, 0, 0, false + } + + year, _, _, yday := absDate(uint64(sec+unixToInternal+internalToAbsolute), false) + + ysec := int64(yday*secondsPerDay) + sec%secondsPerDay + + // Compute start of year in seconds since Unix epoch. + d := daysSinceEpoch(year) + abs := int64(d * secondsPerDay) + abs += absoluteToInternal + internalToUnix + + startSec := int64(tzruleTime(year, startRule, stdOffset)) + endSec := int64(tzruleTime(year, endRule, dstOffset)) + if endSec < startSec { + startSec, endSec = endSec, startSec + stdName, dstName = dstName, stdName + stdOffset, dstOffset = dstOffset, stdOffset + } + + // The start and end values that we return are accurate + // close to a daylight savings transition, but are otherwise + // just the start and end of the year. That suffices for + // the only caller that cares, which is Date. + if ysec < startSec { + return stdName, stdOffset, abs, startSec + abs, true + } else if ysec >= endSec { + return stdName, stdOffset, endSec + abs, abs + 365*secondsPerDay, true + } else { + return dstName, dstOffset, startSec + abs, endSec + abs, true + } +} + +// tzsetName returns the timezone name at the start of the tzset string s, +// and the remainder of s, and reports whether the parsing is OK. +func tzsetName(s string) (string, string, bool) { + if len(s) == 0 { + return "", "", false + } + if s[0] != '<' { + for i, r := range s { + switch r { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ',', '-', '+': + if i < 3 { + return "", "", false + } + return s[:i], s[i:], true + } + } + if len(s) < 3 { + return "", "", false + } + return s, "", true + } else { + for i, r := range s { + if r == '>' { + return s[1:i], s[i+1:], true + } + } + return "", "", false + } +} + +// tzsetOffset returns the timezone offset at the start of the tzset string s, +// and the remainder of s, and reports whether the parsing is OK. +// The timezone offset is returned as a number of seconds. +func tzsetOffset(s string) (offset int, rest string, ok bool) { + if len(s) == 0 { + return 0, "", false + } + neg := false + if s[0] == '+' { + s = s[1:] + } else if s[0] == '-' { + s = s[1:] + neg = true + } + + var hours int + hours, s, ok = tzsetNum(s, 0, 24) + if !ok { + return 0, "", false + } + off := hours * secondsPerHour + if len(s) == 0 || s[0] != ':' { + if neg { + off = -off + } + return off, s, true + } + + var mins int + mins, s, ok = tzsetNum(s[1:], 0, 59) + if !ok { + return 0, "", false + } + off += mins * secondsPerMinute + if len(s) == 0 || s[0] != ':' { + if neg { + off = -off + } + return off, s, true + } + + var secs int + secs, s, ok = tzsetNum(s[1:], 0, 59) + if !ok { + return 0, "", false + } + off += secs + + if neg { + off = -off + } + return off, s, true +} + +// ruleKind is the kinds of rules that can be seen in a tzset string. +type ruleKind int + +const ( + ruleJulian ruleKind = iota + ruleDOY + ruleMonthWeekDay +) + +// rule is a rule read from a tzset string. +type rule struct { + kind ruleKind + day int + week int + mon int + time int // transition time +} + +// tzsetRule parses a rule from a tzset string. +// It returns the rule, and the remainder of the string, and reports success. +func tzsetRule(s string) (rule, string, bool) { + var r rule + if len(s) == 0 { + return rule{}, "", false + } + ok := false + if s[0] == 'J' { + var jday int + jday, s, ok = tzsetNum(s[1:], 1, 365) + if !ok { + return rule{}, "", false + } + r.kind = ruleJulian + r.day = jday + } else if s[0] == 'M' { + var mon int + mon, s, ok = tzsetNum(s[1:], 1, 12) + if !ok || len(s) == 0 || s[0] != '.' { + return rule{}, "", false + + } + var week int + week, s, ok = tzsetNum(s[1:], 1, 5) + if !ok || len(s) == 0 || s[0] != '.' { + return rule{}, "", false + } + var day int + day, s, ok = tzsetNum(s[1:], 0, 6) + if !ok { + return rule{}, "", false + } + r.kind = ruleMonthWeekDay + r.day = day + r.week = week + r.mon = mon + } else { + var day int + day, s, ok = tzsetNum(s, 0, 365) + if !ok { + return rule{}, "", false + } + r.kind = ruleDOY + r.day = day + } + + if len(s) == 0 || s[0] != '/' { + r.time = 2 * secondsPerHour // 2am is the default + return r, s, true + } + + offset, s, ok := tzsetOffset(s[1:]) + if !ok || offset < 0 { + return rule{}, "", false + } + r.time = offset + + return r, s, true +} + +// tzsetNum parses a number from a tzset string. +// It returns the number, and the remainder of the string, and reports success. +// The number must be between min and max. +func tzsetNum(s string, min, max int) (num int, rest string, ok bool) { + if len(s) == 0 { + return 0, "", false + } + num = 0 + for i, r := range s { + if r < '0' || r > '9' { + if i == 0 || num < min { + return 0, "", false + } + return num, s[i:], true + } + num *= 10 + num += int(r) - '0' + if num > max { + return 0, "", false + } + } + if num < min { + return 0, "", false + } + return num, "", true +} + +// tzruleTime takes a year, a rule, and a timezone offset, +// and returns the number of seconds since the start of the year +// that the rule takes effect. +func tzruleTime(year int, r rule, off int) int { + var s int + switch r.kind { + case ruleJulian: + s = (r.day - 1) * secondsPerDay + if isLeap(year) && r.day >= 60 { + s += secondsPerDay + } + case ruleDOY: + s = r.day * secondsPerDay + case ruleMonthWeekDay: + // Zeller's Congruence. + m1 := (r.mon+9)%12 + 1 + yy0 := year + if r.mon <= 2 { + yy0-- + } + yy1 := yy0 / 100 + yy2 := yy0 % 100 + dow := ((26*m1-2)/10 + 1 + yy2 + yy2/4 + yy1/4 - 2*yy1) % 7 + if dow < 0 { + dow += 7 + } + // Now dow is the day-of-week of the first day of r.mon. + // Get the day-of-month of the first "dow" day. + d := r.day - dow + if d < 0 { + d += 7 + } + for i := 1; i < r.week; i++ { + if d+7 >= daysIn(Month(r.mon), year) { + break + } + d += 7 + } + d += int(daysBefore[r.mon-1]) + if isLeap(year) && r.mon > 2 { + d++ + } + s = d * secondsPerDay + } + + return s + r.time - off +} + // lookupName returns information about the time zone with // the given name (such as "EST") at the given pseudo-Unix time // (what the given time of day would be in UTC). diff --git a/libgo/go/time/zoneinfo_ios.go b/libgo/go/time/zoneinfo_ios.go index f5a97befd89..6016a7925a7 100644 --- a/libgo/go/time/zoneinfo_ios.go +++ b/libgo/go/time/zoneinfo_ios.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // +build darwin -// +build arm arm64 +// +build arm64 package time diff --git a/libgo/go/time/zoneinfo_read.go b/libgo/go/time/zoneinfo_read.go index 1e559a62cc2..c2429726f13 100644 --- a/libgo/go/time/zoneinfo_read.go +++ b/libgo/go/time/zoneinfo_read.go @@ -13,8 +13,22 @@ import ( "errors" "runtime" "syscall" + _ "unsafe" // for go:linkname ) +// registerLoadFromEmbeddedTZData is called by the time/tzdata package, +// if it is imported. +//go:linkname registerLoadFromEmbeddedTZData +func registerLoadFromEmbeddedTZData(f func(string) (string, error)) { + loadFromEmbeddedTZData = f +} + +// loadFromEmbeddedTZData is used to load a specific tzdata file +// from tzdata information embedded in the binary itself. +// This is set when the time/tzdata package is imported, +// via registerLoadFromEmbeddedTzdata. +var loadFromEmbeddedTZData func(zipname string) (string, error) + // maxFileSize is the max permitted size of files read by readFile. // As reference, the zoneinfo.zip distributed by Go is ~350 KB, // so 10MB is overkill. @@ -78,6 +92,13 @@ func (d *dataIO) byte() (n byte, ok bool) { return p[0], true } +// read returns the read of the data in the buffer. +func (d *dataIO) rest() []byte { + r := d.p + d.p = nil + return r +} + // Make a string by stopping at the first NUL func byteString(p []byte) string { for i := 0; i < len(p); i++ { @@ -213,6 +234,12 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) { return nil, badData } + var extend string + rest := d.rest() + if len(rest) > 2 && rest[0] == '\n' && rest[len(rest)-1] == '\n' { + extend = string(rest[1 : len(rest)-1]) + } + // Now we can build up a useful data structure. // First the zone information. // utcoff[4] isdst[1] nameindex[1] @@ -289,7 +316,7 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) { } // Committed to succeed. - l := &Location{zone: zone, tx: tx, name: name} + l := &Location{zone: zone, tx: tx, name: name, extend: extend} // Fill in the cache with information about right now, // since that will be the most common lookup. @@ -486,6 +513,17 @@ func loadLocation(name string, sources []string) (z *Location, firstErr error) { firstErr = err } } + if loadFromEmbeddedTZData != nil { + zonedata, err := loadFromEmbeddedTZData(name) + if err == nil { + if z, err = LoadLocationFromTZData(name, []byte(zonedata)); err == nil { + return z, nil + } + } + if firstErr == nil && err != syscall.ENOENT { + firstErr = err + } + } if firstErr != nil { return nil, firstErr } diff --git a/libgo/go/time/zoneinfo_test.go b/libgo/go/time/zoneinfo_test.go index 9ef64def104..dac05e01e37 100644 --- a/libgo/go/time/zoneinfo_test.go +++ b/libgo/go/time/zoneinfo_test.go @@ -188,3 +188,97 @@ func TestMalformedTZData(t *testing.T) { t.Error("expected error, got none") } } + +func TestTzset(t *testing.T) { + for _, test := range []struct { + inStr string + inEnd int64 + inSec int64 + name string + off int + start int64 + end int64 + ok bool + }{ + {"", 0, 0, "", 0, 0, 0, false}, + {"PST8PDT,M3.2.0,M11.1.0", 0, 2159200800, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true}, + {"PST8PDT,M3.2.0,M11.1.0", 0, 2152173599, "PST", -8 * 60 * 60, 2145916800, 2152173600, true}, + {"PST8PDT,M3.2.0,M11.1.0", 0, 2152173600, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true}, + {"PST8PDT,M3.2.0,M11.1.0", 0, 2152173601, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true}, + {"PST8PDT,M3.2.0,M11.1.0", 0, 2172733199, "PDT", -7 * 60 * 60, 2152173600, 2172733200, true}, + {"PST8PDT,M3.2.0,M11.1.0", 0, 2172733200, "PST", -8 * 60 * 60, 2172733200, 2177452800, true}, + {"PST8PDT,M3.2.0,M11.1.0", 0, 2172733201, "PST", -8 * 60 * 60, 2172733200, 2177452800, true}, + } { + name, off, start, end, ok := time.Tzset(test.inStr, test.inEnd, test.inSec) + if name != test.name || off != test.off || start != test.start || end != test.end || ok != test.ok { + t.Errorf("tzset(%q, %d, %d) = %q, %d, %d, %d, %t, want %q, %d, %d, %d, %t", test.inStr, test.inEnd, test.inSec, name, off, start, end, ok, test.name, test.off, test.start, test.end, test.ok) + } + } +} + +func TestTzsetName(t *testing.T) { + for _, test := range []struct { + in string + name string + out string + ok bool + }{ + {"", "", "", false}, + {"X", "", "", false}, + {"PST", "PST", "", true}, + {"PST8PDT", "PST", "8PDT", true}, + {"PST-08", "PST", "-08", true}, + {"+08", "A+B", "+08", true}, + } { + name, out, ok := time.TzsetName(test.in) + if name != test.name || out != test.out || ok != test.ok { + t.Errorf("tzsetName(%q) = %q, %q, %t, want %q, %q, %t", test.in, name, out, ok, test.name, test.out, test.ok) + } + } +} + +func TestTzsetOffset(t *testing.T) { + for _, test := range []struct { + in string + off int + out string + ok bool + }{ + {"", 0, "", false}, + {"X", 0, "", false}, + {"+", 0, "", false}, + {"+08", 8 * 60 * 60, "", true}, + {"-01:02:03", -1*60*60 - 2*60 - 3, "", true}, + {"01", 1 * 60 * 60, "", true}, + {"100", 0, "", false}, + {"8PDT", 8 * 60 * 60, "PDT", true}, + } { + off, out, ok := time.TzsetOffset(test.in) + if off != test.off || out != test.out || ok != test.ok { + t.Errorf("tzsetName(%q) = %d, %q, %t, want %d, %q, %t", test.in, off, out, ok, test.off, test.out, test.ok) + } + } +} + +func TestTzsetRule(t *testing.T) { + for _, test := range []struct { + in string + r time.Rule + out string + ok bool + }{ + {"", time.Rule{}, "", false}, + {"X", time.Rule{}, "", false}, + {"J10", time.Rule{Kind: time.RuleJulian, Day: 10, Time: 2 * 60 * 60}, "", true}, + {"20", time.Rule{Kind: time.RuleDOY, Day: 20, Time: 2 * 60 * 60}, "", true}, + {"M1.2.3", time.Rule{Kind: time.RuleMonthWeekDay, Mon: 1, Week: 2, Day: 3, Time: 2 * 60 * 60}, "", true}, + {"30/03:00:00", time.Rule{Kind: time.RuleDOY, Day: 30, Time: 3 * 60 * 60}, "", true}, + {"M4.5.6/03:00:00", time.Rule{Kind: time.RuleMonthWeekDay, Mon: 4, Week: 5, Day: 6, Time: 3 * 60 * 60}, "", true}, + {"M4.5.7/03:00:00", time.Rule{}, "", false}, + } { + r, out, ok := time.TzsetRule(test.in) + if r != test.r || out != test.out || ok != test.ok { + t.Errorf("tzsetName(%q) = %#v, %q, %t, want %#v, %q, %t", test.in, r, out, ok, test.r, test.out, test.ok) + } + } +} diff --git a/libgo/go/time/zoneinfo_unix.go b/libgo/go/time/zoneinfo_unix.go index dc425a5591c..010c721d008 100644 --- a/libgo/go/time/zoneinfo_unix.go +++ b/libgo/go/time/zoneinfo_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin,386 darwin,amd64 dragonfly freebsd hurd linux,!android netbsd openbsd solaris +// +build aix darwin,amd64 dragonfly freebsd hurd linux,!android netbsd openbsd solaris // Parse "zoneinfo" time zone file. // This is a fairly standard file format used on OS X, Linux, BSD, Sun, and others. @@ -34,7 +34,7 @@ func initLocal() { tz, ok := syscall.Getenv("TZ") switch { case !ok: - z, err := loadLocation("localtime", []string{"/etc/"}) + z, err := loadLocation("localtime", []string{"/etc"}) if err == nil { localLoc = *z localLoc.name = "Local" diff --git a/libgo/go/unicode/utf8/utf8.go b/libgo/go/unicode/utf8/utf8.go index b8368fce41e..ef0d7409602 100644 --- a/libgo/go/unicode/utf8/utf8.go +++ b/libgo/go/unicode/utf8/utf8.go @@ -448,6 +448,20 @@ func RuneStart(b byte) bool { return b&0xC0 != 0x80 } // Valid reports whether p consists entirely of valid UTF-8-encoded runes. func Valid(p []byte) bool { + // Fast path. Check for and skip 8 bytes of ASCII characters per iteration. + for len(p) >= 8 { + // Combining two 32 bit loads allows the same code to be used + // for 32 and 64 bit platforms. + // The compiler can generate a 32bit load for first32 and second32 + // on many platforms. See test/codegen/memcombine.go. + first32 := uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24 + second32 := uint32(p[4]) | uint32(p[5])<<8 | uint32(p[6])<<16 | uint32(p[7])<<24 + if (first32|second32)&0x80808080 != 0 { + // Found a non ASCII byte (>= RuneSelf). + break + } + p = p[8:] + } n := len(p) for i := 0; i < n; { pi := p[i] @@ -480,6 +494,20 @@ func Valid(p []byte) bool { // ValidString reports whether s consists entirely of valid UTF-8-encoded runes. func ValidString(s string) bool { + // Fast path. Check for and skip 8 bytes of ASCII characters per iteration. + for len(s) >= 8 { + // Combining two 32 bit loads allows the same code to be used + // for 32 and 64 bit platforms. + // The compiler can generate a 32bit load for first32 and second32 + // on many platforms. See test/codegen/memcombine.go. + first32 := uint32(s[0]) | uint32(s[1])<<8 | uint32(s[2])<<16 | uint32(s[3])<<24 + second32 := uint32(s[4]) | uint32(s[5])<<8 | uint32(s[6])<<16 | uint32(s[7])<<24 + if (first32|second32)&0x80808080 != 0 { + // Found a non ASCII byte (>= RuneSelf). + break + } + s = s[8:] + } n := len(s) for i := 0; i < n; { si := s[i] diff --git a/libgo/gotool-packages.txt b/libgo/gotool-packages.txt index 90521ae0b50..745c34cd2e6 100644 --- a/libgo/gotool-packages.txt +++ b/libgo/gotool-packages.txt @@ -70,6 +70,7 @@ golang.org/x/tools/go/analysis/passes/copylock golang.org/x/tools/go/analysis/passes/ctrlflow golang.org/x/tools/go/analysis/passes/errorsas golang.org/x/tools/go/analysis/passes/httpresponse +golang.org/x/tools/go/analysis/passes/ifaceassert golang.org/x/tools/go/analysis/passes/inspect golang.org/x/tools/go/analysis/passes/internal/analysisutil golang.org/x/tools/go/analysis/passes/loopclosure @@ -79,6 +80,7 @@ golang.org/x/tools/go/analysis/passes/pkgfact golang.org/x/tools/go/analysis/passes/printf golang.org/x/tools/go/analysis/passes/shift golang.org/x/tools/go/analysis/passes/stdmethods +golang.org/x/tools/go/analysis/passes/stringintconv golang.org/x/tools/go/analysis/passes/structtag golang.org/x/tools/go/analysis/passes/tests golang.org/x/tools/go/analysis/passes/unmarshal @@ -91,5 +93,6 @@ golang.org/x/tools/go/ast/inspector golang.org/x/tools/go/cfg golang.org/x/tools/go/types/objectpath golang.org/x/tools/go/types/typeutil +golang.org/x/tools/internal/analysisinternal golang.org/x/xerrors golang.org/x/xerrors/internal diff --git a/libgo/libgo-packages.txt b/libgo/libgo-packages.txt index a3bdb948499..0b02988d11d 100644 --- a/libgo/libgo-packages.txt +++ b/libgo/libgo-packages.txt @@ -120,6 +120,7 @@ internal/nettrace internal/obscuretestdata internal/oserror internal/poll +internal/profile internal/race internal/reflectlite internal/singleflight @@ -128,6 +129,7 @@ internal/syscall/unix internal/testenv internal/testlog internal/trace +internal/unsafeheader internal/xcoff io io/ioutil @@ -174,7 +176,6 @@ runtime/internal/atomic runtime/internal/math runtime/internal/sys runtime/pprof -runtime/pprof/internal/profile runtime/trace sort strconv @@ -191,6 +192,7 @@ text/tabwriter text/template text/template/parse time +time/tzdata unicode unicode/utf16 unicode/utf8 diff --git a/libgo/misc/cgo/test/pkg_test.go b/libgo/misc/cgo/test/pkg_test.go index 08e075c022c..26c50ad883f 100644 --- a/libgo/misc/cgo/test/pkg_test.go +++ b/libgo/misc/cgo/test/pkg_test.go @@ -32,7 +32,7 @@ func TestCrossPackageTests(t *testing.T) { t.Skip("Can't exec cmd/go subprocess on Android.") case "darwin": switch runtime.GOARCH { - case "arm", "arm64": + case "arm64": t.Skip("Can't exec cmd/go subprocess on iOS.") } } diff --git a/libgo/misc/cgo/test/sigaltstack.go b/libgo/misc/cgo/test/sigaltstack.go index 2c9b81ced7a..8dfa1cb5adb 100644 --- a/libgo/misc/cgo/test/sigaltstack.go +++ b/libgo/misc/cgo/test/sigaltstack.go @@ -14,15 +14,22 @@ package cgotest #include #include +#ifdef _AIX +// On AIX, SIGSTKSZ is too small to handle Go sighandler. +#define CSIGSTKSZ 0x4000 +#else +#define CSIGSTKSZ SIGSTKSZ +#endif + static stack_t oss; -static char signalStack[SIGSTKSZ]; +static char signalStack[CSIGSTKSZ]; static void changeSignalStack(void) { stack_t ss; memset(&ss, 0, sizeof ss); ss.ss_sp = signalStack; ss.ss_flags = 0; - ss.ss_size = SIGSTKSZ; + ss.ss_size = CSIGSTKSZ; if (sigaltstack(&ss, &oss) < 0) { perror("sigaltstack"); abort(); @@ -55,10 +62,8 @@ import ( func testSigaltstack(t *testing.T) { switch { - case runtime.GOOS == "solaris", runtime.GOOS == "illumos", runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64"): + case runtime.GOOS == "solaris", runtime.GOOS == "illumos", runtime.GOOS == "darwin" && runtime.GOARCH == "arm64": t.Skipf("switching signal stack not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) - case runtime.GOOS == "darwin" && runtime.GOARCH == "386": - t.Skipf("sigaltstack fails on darwin/386") } C.changeSignalStack() diff --git a/libgo/misc/cgo/test/test.go b/libgo/misc/cgo/test/test.go index b0148995fe5..8c69ad91ac7 100644 --- a/libgo/misc/cgo/test/test.go +++ b/libgo/misc/cgo/test/test.go @@ -897,6 +897,10 @@ static uint16_t issue31093F(uint16_t v) { return v; } // issue 32579 typedef struct S32579 { unsigned char data[1]; } S32579; + +// issue 38649 +// Test that #define'd type aliases work. +#define netbsd_gid unsigned int */ import "C" @@ -2192,3 +2196,11 @@ func test32579(t *testing.T) { t.Errorf("&s[0].data[0] failed: got %d, want %d", s[0].data[0], 1) } } + +// issue 38649 + +var issue38649 C.netbsd_gid = 42 + +// issue 39877 + +var issue39877 *C.void = nil diff --git a/libgo/misc/cgo/test/testdata/issue27054/egl.h b/libgo/misc/cgo/test/testdata/issue27054/egl.h index 33a759ea2a8..30796273e80 100644 --- a/libgo/misc/cgo/test/testdata/issue27054/egl.h +++ b/libgo/misc/cgo/test/testdata/issue27054/egl.h @@ -5,3 +5,4 @@ // This is the relevant part of EGL/egl.h. typedef void *EGLDisplay; +typedef void *EGLConfig; diff --git a/libgo/misc/cgo/test/testdata/issue27054/test27054.go b/libgo/misc/cgo/test/testdata/issue27054/test27054.go index 186f5bd6020..01bf43a913b 100644 --- a/libgo/misc/cgo/test/testdata/issue27054/test27054.go +++ b/libgo/misc/cgo/test/testdata/issue27054/test27054.go @@ -13,5 +13,9 @@ import ( ) func Test27054(t *testing.T) { - var _ C.EGLDisplay = 0 // Note: 0, not nil. That makes sure we use uintptr for this type. + var ( + // Note: 0, not nil. That makes sure we use uintptr for these types. + _ C.EGLDisplay = 0 + _ C.EGLConfig = 0 + ) } diff --git a/libgo/misc/cgo/test/testx.go b/libgo/misc/cgo/test/testx.go index eb9d7fa47d3..7fbc5c64b31 100644 --- a/libgo/misc/cgo/test/testx.go +++ b/libgo/misc/cgo/test/testx.go @@ -164,7 +164,7 @@ func Add(x int) { } func testCthread(t *testing.T) { - if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { + if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" { t.Skip("the iOS exec wrapper is unable to properly handle the panic from Add") } sum.i = 0 diff --git a/libgo/misc/cgo/testcarchive/carchive_test.go b/libgo/misc/cgo/testcarchive/carchive_test.go index 98cd41ab1d1..af50e1e42e5 100644 --- a/libgo/misc/cgo/testcarchive/carchive_test.go +++ b/libgo/misc/cgo/testcarchive/carchive_test.go @@ -134,7 +134,7 @@ func testMain(m *testing.M) int { } else { switch GOOS { case "darwin": - if GOARCH == "arm" || GOARCH == "arm64" { + if GOARCH == "arm64" { libbase += "_shared" } case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris", "illumos": @@ -305,7 +305,7 @@ func TestEarlySignalHandler(t *testing.T) { switch GOOS { case "darwin": switch GOARCH { - case "arm", "arm64": + case "arm64": t.Skipf("skipping on %s/%s; see https://golang.org/issue/13701", GOOS, GOARCH) } case "windows": @@ -487,7 +487,7 @@ func checkSignalForwardingTest(t *testing.T) { switch GOOS { case "darwin": switch GOARCH { - case "arm", "arm64": + case "arm64": t.Skipf("skipping on %s/%s; see https://golang.org/issue/13701", GOOS, GOARCH) } case "windows": @@ -603,7 +603,7 @@ func TestExtar(t *testing.T) { if runtime.Compiler == "gccgo" { t.Skip("skipping -extar test when using gccgo") } - if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { + if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" { t.Skip("shell scripts are not executable on iOS hosts") } diff --git a/libgo/misc/cgo/testcshared/cshared_test.go b/libgo/misc/cgo/testcshared/cshared_test.go index cb95153abf6..bd4d341820e 100644 --- a/libgo/misc/cgo/testcshared/cshared_test.go +++ b/libgo/misc/cgo/testcshared/cshared_test.go @@ -108,7 +108,7 @@ func testMain(m *testing.M) int { libgodir := GOOS + "_" + GOARCH switch GOOS { case "darwin": - if GOARCH == "arm" || GOARCH == "arm64" { + if GOARCH == "arm64" { libgodir += "_shared" } case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris", "illumos": diff --git a/libgo/misc/cgo/testgodefs/testdata/issue38649.go b/libgo/misc/cgo/testgodefs/testdata/issue38649.go new file mode 100644 index 00000000000..6af74d60582 --- /dev/null +++ b/libgo/misc/cgo/testgodefs/testdata/issue38649.go @@ -0,0 +1,15 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// +build ignore + +package main + +/* +struct Issue38649 { int x; }; +#define issue38649 struct Issue38649 +*/ +import "C" + +type issue38649 C.issue38649 diff --git a/libgo/misc/cgo/testgodefs/testdata/issue39534.go b/libgo/misc/cgo/testgodefs/testdata/issue39534.go new file mode 100644 index 00000000000..9899ba16734 --- /dev/null +++ b/libgo/misc/cgo/testgodefs/testdata/issue39534.go @@ -0,0 +1,12 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// +build ignore + +package main + +// enum { ENUMVAL = 0x1 }; +import "C" + +const ENUMVAL = C.ENUMVAL diff --git a/libgo/misc/cgo/testgodefs/testdata/main.go b/libgo/misc/cgo/testgodefs/testdata/main.go index ef45b95e655..2e1ad3376a1 100644 --- a/libgo/misc/cgo/testgodefs/testdata/main.go +++ b/libgo/misc/cgo/testgodefs/testdata/main.go @@ -19,5 +19,8 @@ var v6 = B{} // Test that S is fully defined var v7 = S{} +// Test that #define'd type is fully defined +var _ = issue38649{X: 0} + func main() { } diff --git a/libgo/misc/cgo/testgodefs/testgodefs_test.go b/libgo/misc/cgo/testgodefs/testgodefs_test.go index 438d23d65c0..e4085f9ca80 100644 --- a/libgo/misc/cgo/testgodefs/testgodefs_test.go +++ b/libgo/misc/cgo/testgodefs/testgodefs_test.go @@ -23,6 +23,8 @@ var filePrefixes = []string{ "fieldtypedef", "issue37479", "issue37621", + "issue38649", + "issue39534", } func TestGoDefs(t *testing.T) { diff --git a/libgo/misc/cgo/testplugin/plugin_test.go b/libgo/misc/cgo/testplugin/plugin_test.go index ab98f61c0ad..2875271c03b 100644 --- a/libgo/misc/cgo/testplugin/plugin_test.go +++ b/libgo/misc/cgo/testplugin/plugin_test.go @@ -32,7 +32,7 @@ func TestMain(m *testing.M) { } func testMain(m *testing.M) int { - // Copy testdata into GOPATH/src/testarchive, along with a go.mod file + // Copy testdata into GOPATH/src/testplugin, along with a go.mod file // declaring the same path. GOPATH, err := ioutil.TempDir("", "plugin_test") diff --git a/libgo/misc/cgo/testshared/shared_test.go b/libgo/misc/cgo/testshared/shared_test.go index b9ef6dad8e2..f8dabbe7a01 100644 --- a/libgo/misc/cgo/testshared/shared_test.go +++ b/libgo/misc/cgo/testshared/shared_test.go @@ -38,7 +38,15 @@ var testWork = flag.Bool("testwork", false, "if true, log and do not delete the // run runs a command and calls t.Errorf if it fails. func run(t *testing.T, msg string, args ...string) { + runWithEnv(t, msg, nil, args...) +} + +// runWithEnv runs a command under the given environment and calls t.Errorf if it fails. +func runWithEnv(t *testing.T, msg string, env []string, args ...string) { c := exec.Command(args[0], args[1:]...) + if len(env) != 0 { + c.Env = append(os.Environ(), env...) + } if output, err := c.CombinedOutput(); err != nil { t.Errorf("executing %s (%s) failed %s:\n%s", strings.Join(args, " "), msg, err, output) } @@ -105,6 +113,8 @@ func testMain(m *testing.M) (int, error) { fmt.Printf("+ cd %s\n", modRoot) } os.Setenv("GOPATH", gopath) + // Explicitly override GOBIN as well, in case it was set through a GOENV file. + os.Setenv("GOBIN", filepath.Join(gopath, "bin")) os.Chdir(modRoot) os.Setenv("PWD", modRoot) @@ -153,10 +163,6 @@ func TestMain(m *testing.M) { log.SetFlags(log.Lshortfile) flag.Parse() - // Some of the tests install binaries into a custom GOPATH. - // That won't work if GOBIN is set. - os.Unsetenv("GOBIN") - exitCode, err := testMain(m) if err != nil { log.Fatal(err) @@ -223,7 +229,7 @@ func cloneGOROOTDeps(goroot string) error { for _, dir := range gorootDirs { if testing.Verbose() { - fmt.Fprintf(os.Stderr, "+ cp -r %s %s\n", filepath.Join(goroot, dir), filepath.Join(oldGOROOT, dir)) + fmt.Fprintf(os.Stderr, "+ cp -r %s %s\n", filepath.Join(oldGOROOT, dir), filepath.Join(goroot, dir)) } if err := overlayDir(filepath.Join(goroot, dir), filepath.Join(oldGOROOT, dir)); err != nil { return err @@ -1030,3 +1036,17 @@ func TestGeneratedHash(t *testing.T) { goCmd(nil, "install", "-buildmode=shared", "-linkshared", "./issue30768/issue30768lib") goCmd(nil, "test", "-linkshared", "./issue30768") } + +// Test that packages can be added not in dependency order (here a depends on b, and a adds +// before b). This could happen with e.g. go build -buildmode=shared std. See issue 39777. +func TestPackageOrder(t *testing.T) { + goCmd(t, "install", "-buildmode=shared", "-linkshared", "./issue39777/a", "./issue39777/b") +} + +// Test that GC data are generated correctly by the linker when it needs a type defined in +// a shared library. See issue 39927. +func TestGCData(t *testing.T) { + goCmd(t, "install", "-buildmode=shared", "-linkshared", "./gcdata/p") + goCmd(t, "build", "-linkshared", "./gcdata/main") + runWithEnv(t, "running gcdata/main", []string{"GODEBUG=clobberfree=1"}, "./main") +} diff --git a/libgo/misc/cgo/testshared/testdata/gcdata/main/main.go b/libgo/misc/cgo/testshared/testdata/gcdata/main/main.go new file mode 100644 index 00000000000..394862fd94c --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/gcdata/main/main.go @@ -0,0 +1,37 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test that GC data is generated correctly for global +// variables with types defined in a shared library. +// See issue 39927. + +// This test run under GODEBUG=clobberfree=1. The check +// *x[i] == 12345 depends on this debug mode to clobber +// the value if the object is freed prematurely. + +package main + +import ( + "fmt" + "runtime" + "testshared/gcdata/p" +) + +var x p.T + +func main() { + for i := range x { + x[i] = new(int) + *x[i] = 12345 + } + runtime.GC() + runtime.GC() + runtime.GC() + for i := range x { + if *x[i] != 12345 { + fmt.Printf("x[%d] == %d, want 12345\n", i, *x[i]) + panic("FAIL") + } + } +} diff --git a/libgo/misc/cgo/testshared/testdata/gcdata/p/p.go b/libgo/misc/cgo/testshared/testdata/gcdata/p/p.go new file mode 100644 index 00000000000..1fee75429ef --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/gcdata/p/p.go @@ -0,0 +1,7 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +type T [10]*int diff --git a/libgo/misc/cgo/testshared/testdata/issue39777/a/a.go b/libgo/misc/cgo/testshared/testdata/issue39777/a/a.go new file mode 100644 index 00000000000..c7bf8359514 --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/issue39777/a/a.go @@ -0,0 +1,9 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package a + +import "testshared/issue39777/b" + +func F() { b.F() } diff --git a/libgo/misc/cgo/testshared/testdata/issue39777/b/b.go b/libgo/misc/cgo/testshared/testdata/issue39777/b/b.go new file mode 100644 index 00000000000..4e681965e68 --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/issue39777/b/b.go @@ -0,0 +1,7 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package b + +func F() {} diff --git a/libgo/misc/cgo/testso/so_test.go b/libgo/misc/cgo/testso/so_test.go index 9c7f2724390..bdd6bd84685 100644 --- a/libgo/misc/cgo/testso/so_test.go +++ b/libgo/misc/cgo/testso/so_test.go @@ -20,16 +20,14 @@ import ( func requireTestSOSupported(t *testing.T) { t.Helper() switch runtime.GOARCH { - case "arm", "arm64": + case "arm64": if runtime.GOOS == "darwin" { t.Skip("No exec facility on iOS.") } case "ppc64": if runtime.GOOS == "linux" { - t.Skip("External linking not implemented on aix/ppc64 (issue #8912).") + t.Skip("External linking not implemented on linux/ppc64 (issue #8912).") } - case "mips64le", "mips64": - t.Skip("External linking not implemented on mips64.") } if runtime.GOOS == "android" { t.Skip("No exec facility on Android.") diff --git a/libgo/misc/cgo/testsovar/so_test.go b/libgo/misc/cgo/testsovar/so_test.go index 9c7f2724390..bdd6bd84685 100644 --- a/libgo/misc/cgo/testsovar/so_test.go +++ b/libgo/misc/cgo/testsovar/so_test.go @@ -20,16 +20,14 @@ import ( func requireTestSOSupported(t *testing.T) { t.Helper() switch runtime.GOARCH { - case "arm", "arm64": + case "arm64": if runtime.GOOS == "darwin" { t.Skip("No exec facility on iOS.") } case "ppc64": if runtime.GOOS == "linux" { - t.Skip("External linking not implemented on aix/ppc64 (issue #8912).") + t.Skip("External linking not implemented on linux/ppc64 (issue #8912).") } - case "mips64le", "mips64": - t.Skip("External linking not implemented on mips64.") } if runtime.GOOS == "android" { t.Skip("No exec facility on Android.")